Most Power Shell variables are a "String, char Object[] array, or Byte[] array". Example:
$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
But doing things like Encryption with Power Shell such as RSA returns the Base Type of
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider
$rsa.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False RSACryptoServiceProvider System.Security.Cryptography.RSA
Trying to extract or save the "System.Security.Cryptography.RSA" $rsa BaseType and restore it from a variable breaks the Base Type. Only way that seems to work is to export the $rsa to a xml file and import it later as
Export-Clixml -InputObject $rsa -Path .\rsa.xml
$imported_rsa = Import-Clixml -Path ".\rsa.xml"
However you can't do it with a variable if the rsa.xml is stored as a string. Getting this error.
$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.
Doing it with PSSerializer looks correct but is converted to the wrong type of 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
Attempting to save System.Security.Cryptography.RSA BaseType by converting it to a format that can be move around. Breaks once you try to move it back its System.Security.Cryptography.RSA BaseType. The only thing that seems to work is to export the $rsa variable as a XML file and Import it. However try to do it completely by storing data in variables which leads to the wrong GetType. Breaking the $rsa and not able to decrypt or encrypt anything after the fact.
The BaseType
property value in the output from a .GetType()
call is the type that the input type is derived from , ie its immediate ancestor in the .NET inheritance hierarchy .
You can easily show the entire hierarchy, starting with the input object's own time and eventually ending in System.Object
, the root type of all .NET types - via the intrinsic pstypenames
property ; [1] eg:
# [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
Given this relationship, there's usually no need to convert a given object to any of its base types, because it is an instance of these types (just of a more specialized (derived) kind), which you can verify with -is
, the type(-inheritance) / interface test operator :
$instance = [System.Security.Cryptography.RSACryptoServiceProvider]::new()
# -> $true
$instance -is [System.Security.Cryptography.RSA]
Serializing and later deserializing objects (whether via Export-Clixml
or directly via [System.Management.Automation.PSSerializer]
), using PowerShell's XML-based CLIXML format, is an entirely separate issue , and, as noted in the comments:
[psobject]
/ [pscustomobject]
; that is, the original type identity is lost - see this answer for details.[1] Note that it is possible for this property to contain virtual entries inserted for the benefit of PowerShell's ETS (Extended Type System) .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.