PoshRSJob
PoshRSJob copied to clipboard
-ArgumentList argument count incorrect, causing "shift" of first parameter to $_
Do you want to request a feature or report a bug? Bug What is the current behavior? Start-RSJob incorrectly counts the parameters in the -ArgumentList, altering its behavior loading parameter values in the Runspace job and setting $_ (pipeline) to the first value in the -ArgumentList parameter. (I've seen previous, similar posts for problems with -ArgumentList, but I'm identifying the specific line I think is the problem, below) Note the DEBUG: ArgumentCount: X | SBParamCount: Y | IsPipeline: True in the output(s) given below
The bug is on line 285 of Start-RSJob:
$ArgumentCount = If (-not $ArgumentList -or ($SingleArgument -eq 0)) { # Empty array, or, 0 count
The $(SingleArgument -eq 0) resolves to TRUE even when $SingleArgument is False, because PowerShell is treating False == 0. For example:
PS C:\> if ($false -eq 0) { Write-Host "False is apparently zero, too" }
False is apparently zero, too
For the time being, I have fixed this locally with:
$ArgumentCount = If (-not $ArgumentList -or ($SingleArgument -and $SingleArgument -eq 0)) { # Empty array, or, 0 count
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem Example of current failure:
PS C:\Users\me\Documents\WindowsPowerShell> $scriptTemplate = @'
Param (
[object] $p1,
[string] $p2
)
Write-Output "Piped object: $_";
Write-Output "Param1: $p1";
Write-Output "Param2: $p2";
'@
$scriptBlock = [System.Management.Automation.ScriptBlock]::Create($scriptTemplate);
Start-RSJob -ScriptBlock $scriptBlock -ArgumentList $param1,$param2 -Verbose -Debug
DEBUG: [BEGIN]
VERBOSE: Displaying PSBoundParameters
VERBOSE: [ScriptBlock, Param (
[object] $p1,
[string] $p2
)
Write-Output "Piped object: $_";
Write-Output "Param1: $p1";
Write-Output "Param2: $p2";]
VERBOSE: [ArgumentList, System.Object[]]
VERBOSE: [Verbose, True]
VERBOSE: [Debug, True]
VERBOSE: Creating default Job Name
DEBUG: 2 argument/s passed via -ArgumentList
DEBUG: [PROCESS]
DEBUG: [END]
DEBUG: ArgumentCount: 0 | SBParamCount: 2 | IsPipeline: True
VERBOSE: Will use $_ in Param() Block
VERBOSE: PowerShell Version: 5
DEBUG: Using AST with PowerShell V3+
DEBUG: ScriptBlock: Param (
$_,
[object] $p1,
[string] $p2
)
Write-Output "Piped object: $_";
Write-Output "Param1: $p1";
Write-Output "Param2: $p2";
VERBOSE: Creating new runspacepool <545b7dab-2bc6-4a74-9436-c7a71431bb16>
DEBUG: No InputObject
VERBOSE: Incrementing job ID
VERBOSE: Adding Argument: FirstParam <System.String>
VERBOSE: Adding Argument: SecondParam <System.String>
Id Name State HasMoreData HasErrors Command
-- ---- ----- ----------- --------- -------
1 Job1 Completed True False Param (...
PS C:\Users\me\Documents\WindowsPowerShell> Get-RSJob | Receive-RSJob
Piped object: FirstParam
Param1: SecondParam
Param2:
PS C:\Users\me\Documents\WindowsPowerShell>
What is the expected behavior? Same example, with fix given above in place (line 285):
PS C:\Users\me\Documents\WindowsPowerShell> $scriptTemplate = @'
Param (
[object] $p1,
[string] $p2
)
Write-Output "Piped object: $_";
Write-Output "Param1: $p1";
Write-Output "Param2: $p2";
'@
$scriptBlock = [System.Management.Automation.ScriptBlock]::Create($scriptTemplate);
Start-RSJob -ScriptBlock $scriptBlock -ArgumentList $param1,$param2 -Verbose -Debug
DEBUG: [BEGIN]
VERBOSE: Displaying PSBoundParameters
VERBOSE: [ScriptBlock, Param (
[object] $p1,
[string] $p2
)
Write-Output "Piped object: $_";
Write-Output "Param1: $p1";
Write-Output "Param2: $p2";]
VERBOSE: [ArgumentList, System.Object[]]
VERBOSE: [Verbose, True]
VERBOSE: [Debug, True]
VERBOSE: Creating default Job Name
DEBUG: 2 argument/s passed via -ArgumentList
DEBUG: [PROCESS]
DEBUG: [END]
DEBUG: ArgumentCount: 2 | SBParamCount: 2 | IsPipeline: True
VERBOSE: PowerShell Version: 5
DEBUG: Using AST with PowerShell V3+
DEBUG: ScriptBlock: Param (
[object] $p1,
[string] $p2
)
Write-Output "Piped object: $_";
Write-Output "Param1: $p1";
Write-Output "Param2: $p2";
VERBOSE: Creating new runspacepool <43abebe4-2265-439a-9eea-a1b2a5d37056>
DEBUG: No InputObject
VERBOSE: Incrementing job ID
VERBOSE: Adding Argument: FirstParam <System.String>
VERBOSE: Adding Argument: SecondParam <System.String>
Id Name State HasMoreData HasErrors Command
-- ---- ----- ----------- --------- -------
1 Job1 Completed True False Param (...
PS C:\Users\me\Documents\WindowsPowerShell> Get-RSJob | Receive-RSJob
Piped object:
Param1: FirstParam
Param2: SecondParam
Which versions of Powershell and which OS are affected by this issue? Did this work in previous versions of our scripts?
PS C:\Users\alandye\Documents\WindowsPowerShell> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.15063.0
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.15063.0
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PoshRSJob module version is 1.7.3.9
Don't know if this previously (ever) worked.
Please provide a code example showing the issue, if applicable:
PS C:\Users\me\Documents\WindowsPowerShell> $scriptTemplate = @' Param ( [object] $p1, [string] $p2 ) Write-Output "Piped object: $_"; Write-Output "Param1: $p1"; Write-Output "Param2: $p2"; '@ $scriptBlock = [System.Management.Automation.ScriptBlock]::Create($scriptTemplate);
Start-RSJob -ScriptBlock $scriptBlock -ArgumentList $param1,$param2 -Verbose -Debug
PS C:\Users\me\Documents\WindowsPowerShell> Get-RSJob | Receive-RSJob
I am still seeing this issue in version 1.7.3.11. The suggested fix in the original posting works. Any chance this will fix (or some other version of this fix) will be incorporated in a future version?
I'm ready to make PR which should fix it. Please test my fork before...
Should say, this is feature :)
The way it works not clearly documented:
If you want to read large text, you can try :)
https://github.com/MVKozlov/PoshRSJob/wiki/NewParam-branch-changes
short version:
If scriptblock.param.count -ne 1
or
if scriptblock.param.count -eq argumentlist.count -and pipeline.count -gt 0
pipeline value inserted as $_ in scriptblock
argumentlist.count = real arguments count + pipeline
and now there is a bug, when $_ inserted when param.count -eq argumentlist.count
even there is no pipeline input
Thanks for the quick response. I tested the code in your fork and I can confirm that the -Argumentlist parameter bug is fixed.