Powershell: Improper usage of $input as a function parameter is silently ignored

Created on 30 Jul 2017  路  7Comments  路  Source: PowerShell/PowerShell

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.

Steps to reproduce

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

Expected behavior

I would presume PowerShell would fire an exception regarding improper usage of the $input as function parameter in Ensure-ArrayA.

Actual behavior

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

Environment data

> $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 
Area-Cmdlets Breaking-Change Committee-Reviewed Issue-Discussion WG-Language

All 7 comments

@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

Was this page helpful?
0 / 5 - 0 ratings