I am not sure whether this qualifies as a bug or designed PowerShell behavior related to unrolling objects (which is to my opinion useless for serialized objects)
$Expression = [ScriptBlock]::Create('[byte[]](1, 2, 3)')
(&$Expression).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Byte[] System.Array
I would expect the same behavior as:
([byte[]](1, 2, 3)).GetType(),$Expression = [ScriptBlock]::Create('@{x = [byte[]](1, 2, 3)}'); (&$Expression)['x'].GetType()ConvertFrom-Expression cmdlet : (ConvertFrom-Expression $Expression -NoEnumerate).GetType().IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
(The byte[] array is converted to an object[] array)
This also happens with methods that return a valued array, e.g.: $Expression = [ScriptBlock]::Create('"abc".ToCharArray()') and the same happens with other "evaluate" cmdlets along with Invoke-Expression and Invoke-Command
This behavior is probably related to: stackoverflow question: How can I prevent a (serialized) expression to unroll
Name Value
---- -----
PSVersion 6.2.3
PSEdition Core
GitCommitId 6.2.3
OS Microsoft Windows 10.0.18362
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
I think your assumption is incorrect.
Your test case is:
[scriptblock]::Create('[byte[]](1, 2, 3)')
Which is identical to just doing:
{ [byte[]](1, 2, 3) }
Invoking either of these will cause the collection to be unrolled as it passes through PS's output systems. If you want to prevent this, you would instead need something analogous to:
{ Write-Output -NoEnumerate ([byte[]](1, 2, 3)) }
Note also that this isn't serialized data, it's just strings being parsed into PowerShell script via the standard parser, no different to any script PS processes normally.
If you want to serialize data, you can use Export-CliXml
Export-CliXml -Path bytes.xml -InputObject ([byte[]](1, 2, 3))
I wonder why the Write-Output got the -NoEnumerate parameter.
Wouldn't a -NoEnumerate parameter for the Invoke-Command make sense for the same reason?
It's not as meaningful, since Invoke-Command itself can contain an entire scriptblock with any number of commands; by the time the cmdlet receives any of the output, it's already enumerated. The best it could do is emit the entire object[] array as a single item. 馃檪
Thanks again for the answer and explanation.
Most helpful comment
I think your assumption is incorrect.
Your test case is:
Which is identical to just doing:
Invoking either of these will cause the collection to be unrolled as it passes through PS's output systems. If you want to prevent this, you would instead need something analogous to:
Note also that this isn't serialized data, it's just strings being parsed into PowerShell script via the standard parser, no different to any script PS processes normally.
If you want to serialize data, you can use
Export-CliXml