[英]How to preserve the "Name" and "BaseType" of PowerShell Variables for System.* BaseTypes
大多數 Power Shell 變量是“String、char Object[] 數組或 Byte[] 數組”。 例子:
$string = "hello world"
$string.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
# OR
$char = 1,2,3,4,5,6
$char.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
但是做像 RSA 這樣的 Power Shell Encryption 這樣的事情會返回基本類型
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider
$rsa.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False RSACryptoServiceProvider System.Security.Cryptography.RSA
嘗試提取或保存“System.Security.Cryptography.RSA”$rsa BaseType 並從變量中恢復它會破壞基本類型。 似乎唯一可行的方法是將 $rsa 導出到 xml 文件並稍后將其導入為
Export-Clixml -InputObject $rsa -Path .\rsa.xml
$imported_rsa = Import-Clixml -Path ".\rsa.xml"
但是,如果 rsa.xml 存儲為字符串,則不能使用變量。 收到此錯誤。
$xml_string = @"
<xml-data>
"@
$xml_string.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
$imported_rsa = Import-Clixml $xml_string
Import-Clixml: Cannot find drive. A drive with the name '<Objs Version="1.1.0.1" xmlns="http' does not exist.
使用 PSSerializer 執行它看起來是正確的,但被轉換為錯誤類型的 System.Object
$rsa
CspKeyContainerInfo :
KeyExchangeAlgorithm : RSA
KeySize : 1024
LegalKeySizes : {System.Security.Cryptography.KeySizes}
PersistKeyInCsp : False
PublicOnly : False
SignatureAlgorithm : http://www.w3.org/2000/09/xmldsig#rsa-sha1
$rsa.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False RSACryptoServiceProvider System.Security.Cryptography.RSA
$xml_string = @"
<xml-data>
"@
[Management.Automation.PSSerializer]::Deserialize($xml_string)
KeyExchangeAlgorithm : RSA
KeySize : 1024
LegalKeySizes : {System.Security.Cryptography.KeySizes}
PersistKeyInCsp : False
PublicOnly : False
SignatureAlgorithm : http://www.w3.org/2000/09/xmldsig#rsa-sha1
[Management.Automation.PSSerializer]::Deserialize($xml_string).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True PSObject System.Object
嘗試通過將 System.Security.Cryptography.RSA BaseType 轉換為可以移動的格式來保存它。 一旦您嘗試將其移回其 System.Security.Cryptography.RSA BaseType,就會中斷。 唯一可行的方法是將 $rsa 變量導出為 XML 文件並將其導入。 但是,嘗試通過將數據存儲在導致錯誤 GetType 的變量中來完全做到這一點。 破壞 $rsa 並且事后無法解密或加密任何內容。
來自.GetType()
調用的 output 中的BaseType
屬性值是輸入類型派生自的類型,即它在 .NET inheritance 層次結構中的直接祖先。
您可以輕松顯示整個層次結構,從輸入對象自己的時間開始,最終以System.Object
結束,這是所有.NET 類型的根類型 - 通過內在的pstypenames
屬性; [1]例如:
# [System.Security.Cryptography.RSACryptoServiceProvider]::new() is PSv5+
# shorthand for: New-Object System.Security.Cryptography.RSACryptoServiceProvider
[System.Security.Cryptography.RSACryptoServiceProvider]::new().pstypenames
Output:
System.Security.Cryptography.RSACryptoServiceProvider
System.Security.Cryptography.RSA
System.Security.Cryptography.AsymmetricAlgorithm
System.Object
鑒於這種關系,通常不需要將給定的 object轉換為其任何基本類型,因為它是這些類型的一個實例(只是更特殊(派生)的一種),您可以使用-is
驗證它, 類型(-inheritance) / 接口測試操作符:
$instance = [System.Security.Cryptography.RSACryptoServiceProvider]::new()
# -> $true
$instance -is [System.Security.Cryptography.RSA]
使用 PowerShell 的基於 XML 的 CLIXML 格式序列化和稍后反序列化對象(無論是通過Export-Clixml
還是直接通過[System.Management.Automation.PSSerializer]
)是一個完全獨立的問題,並且如評論中所述:
[psobject]
/ [pscustomobject]
; 也就是說,原始類型標識丟失了- 有關詳細信息,請參閱此答案。[1] 請注意,此屬性可能包含為了 PowerShell 的ETS(擴展類型系統)而插入的虛擬條目。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.