As I learned the hard way today, $input is PowerShell automatic variable.
PowerShell seems to ignore obviously improper usage of the $input, leaving the programmer confused about the parameter not being propagated further.
There are two identical (non-optimal, I admit) implementations of Ensure-Array.
They both differ only in parameter name, nothing more.
function Ensure-ArrayA($input)
{
$result = @()
if ($input -is [system.array])
{
$result = $input
}
else
{
$result = @($input)
}
return [Array]$result
}
function Ensure-ArrayB($Unknown)
{
$result = @()
if ($Unknown -is [system.array])
{
$result = $Unknown
}
else
{
$result = @($Unknown)
}
return [Array]$result
}
$x = Ensure-ArrayA 1
$y = Ensure-ArrayB 1
$x.Count
$y.Count
I would presume PowerShell would fire an exception regarding improper usage of the $input as function parameter in Ensure-ArrayA.
Instead, PowerShell silently ignores this incorrect code, pretending everything is all right. Of course, using $input will result in incorrect output as consequence.
The script above will output simply:
1
> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.14393.1198
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14393.1198
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
@petrSchreiber Thanks for your report!
Related #3695.
/cc @jpsnover
Also: #3061, which tackles the issue comprehensively.
@PowerShell/powershell-committee discussed this and agree that the parser will enforce not allowing writing to $input
Set-Variable can write to the variable.
@iSazonov I think the intent here is to address common usage where the user isn't aware that the variable they are using could be clobbered by PowerShell. Set-Variable doesn't seem like it would fall under this, but I'm not opposed to special casing it in that cmdlet.
See this documentation issue for the necessary attendant change to the documentation.
Although a breaking change, I think we can address this in 6.1.0