Consider the following code. I am simply passing in an array of 32-bit, signed integers [Int32[]]
into the Start-Job
cmdlet, by using the -InputObject
parameter.
$Job = Start-Job -ScriptBlock { $input.GetType().FullName; } -InputObject @(1,2,3);
Wait-Job -Job $Job;
Receive-Job -Keep $Job;
The result of this code is:
System.Management.Automation.Runspaces.PipelineReader`1+<GetReadEnumerator>d__0[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
Looking at the documentation for the PipelineReader .NET class, it has a ReadToEnd()
method. Therefore, the following code ought to work:
$Job = Start-Job -ScriptBlock { $input.ReadToEnd(); } -InputObject @(1,2,3);
Wait-Job -Job $Job;
Receive-Job -Keep $Job;
But instead, I get an error message:
Method invocation failed because [System.Int32] does not contain a method named 'ReadToEnd'. + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound + PSComputerName : localhost
So then I think, I'll just use the PSBase
property to get the "real" object.
$Job = Start-Job -ScriptBlock { $input.psbase.ReadToEnd(); } -InputObject @(1,2,3);
Wait-Job -Job $Job;
Receive-Job -Keep $Job;
But then I get a similar error message:
Method invocation failed because [System.Management.Automation.PSInternalMemberSet] does not contain a method named 'ReadToEnd'. + CategoryInfo : InvalidOperation: (ReadToEnd:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound + PSComputerName : localhost
I noticed that there is a Microsoft Connect bug filed around this confusion, but it confuses me even more. Apparently the PipelineReader
class has a confusingly-named property <>4__this
, which has a Read()
method, which you can't actually see by using Get-Member
.
Bottom line: Does anyone know how to simply "unwrap" the contents of the $input
automatic variable, when input is submitted via the -InputObject
parameter on the Start-Job
cmdlet, so that I can work with the objects on an individual basis?
This script should simply return 1
, not 1, 2, 3
.
$Job = Start-Job -ScriptBlock { $input[0]; } -InputObject @(1,2,3);
Wait-Job -Job $Job;
Receive-Job -Keep $Job;