PSCmdlet.MyInvocation.BoundParameters contains values from previous invocations in pipeline
skaempfer opened this issue · 0 comments
skaempfer commented
My setup:
- PowerShell Core 7.2.1
- PowerShellStandard.Library 5.1.0
I have the following C# cmdlet:
[Cmdlet(VerbsDiagnostic.Test,"SampleCmdlet")]
public class TestSampleCmdletCommand : PSCmdlet
{
[Parameter(
Mandatory = false,
ValueFromPipelineByPropertyName = true)]
public string X { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipelineByPropertyName = true)]
public string Y { get; set; }
protected override void ProcessRecord()
{
if (this.MyInvocation.BoundParameters.ContainsKey(nameof(X)))
{
this.WriteObject("X is bound");
}
if (this.MyInvocation.BoundParameters.ContainsKey(nameof(Y)))
{
this.WriteObject("Y is bound");
}
}
}
I use this command in the following script:
$values = @(
[PSCustomObject] @{ X = "one" },
[PSCustomObject] @{ Y = "two" }
)
$values | Test-SampleCmdlet
This produces the following output:
X is bound
X is bound
Y is bound
Expected output:
X is bound
Y is bound
Inspecting the state of the PSCmdlet.MyInvocation.BoundParameters
dictionary during the second invocation in the pipeline shows that it still contains the key value pair X: "one"
from the first invocation. The actual value of the property X
of the cmdlet instance is null as expected.
Re-creating the same functionality with a PowerShell function yields the expected result:
function Test-SampleCmdlet
{
[CmdletBinding()]
param (
[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)][string] $X,
[Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true)][string] $Y
)
if($MyInvocation.BoundParameters.ContainsKey("X"))
{
Write-Output "X is bound";
}
if($MyInvocation.BoundParameters.ContainsKey("Y"))
{
Write-Output "Y is bound";
}
}
$values = @(
[PSCustomObject] @{ X = "one" },
[PSCustomObject] @{ Y = "two" }
)
$values | Test-SampleCmdlet
# Produces:
# X is bound
# Y is bound