簡體   English   中英

如何為 System.* BaseTypes 保留 PowerShell 變量的“名稱”和“BaseType”

[英]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] )是一個完全獨立的問題,並且如評論中所述:

  • 除了一些眾所周知的類型,反序列化導致原始對象及其屬性的無方法模擬,使用 PowerShell 的“屬性包”類型, [psobject] / [pscustomobject] 也就是說,原始類型標識丟失了- 有關詳細信息,請參閱此答案

[1] 請注意,此屬性可能包含為了 PowerShell 的ETS(擴展類型系統)而插入的虛擬條目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM