Powershell: Scriptblocks serialized to Clixml are deserialized as strings

Created on 11 Jul 2017  路  2Comments  路  Source: PowerShell/PowerShell

ScriptBlock objects are deserialized as strings when run through Import-CliXml.

@nightroman has a more detailed test case on his PowerShellTraps repo, including a link to a Microsoft Connect issue from March of 2015. This appears to have been migrated to the Windows Server UserVoice, but the issue still exists in v6.0.0-beta.3.

Steps to reproduce

{Get-Process} | Export-Clixml .\Test.clixml

Import-Clixml .\Test.Clixml | % GetType

Expected behavior

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ScriptBlock                              System.Object

Actual behavior

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      6.0.0-beta
PSEdition                      Core
GitCommitId                    v6.0.0-beta.3
OS                             Microsoft Windows 10.0.15063
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Area-Cmdlets-Utility Issue-Discussion Issue-Enhancement

Most helpful comment

Would it be feasible to implement this using a switch parameter on Import-CliXml, in that case? I can see how rehydrating scriptblocks could have a potential for unsafe code execution, but by the same token storing blocks of code alongside other object properties could prove useful in certain situations.

An approach similar to ConvertTo-SecureString - where specifying -AsPlainText throws an exception detailing the security risks unless -Force is also specified - could perhaps be applied here.

All 2 comments

Historically this is by design. Serializing scriptblocks with fidelity resulted in too many places where there was automatic code execution so to facilitate secure restricted runspaces, scriptblocks are always deserialized to strings.

Would it be feasible to implement this using a switch parameter on Import-CliXml, in that case? I can see how rehydrating scriptblocks could have a potential for unsafe code execution, but by the same token storing blocks of code alongside other object properties could prove useful in certain situations.

An approach similar to ConvertTo-SecureString - where specifying -AsPlainText throws an exception detailing the security risks unless -Force is also specified - could perhaps be applied here.

Was this page helpful?
0 / 5 - 0 ratings