Tag Archives: powershell_gotchas

Powershell gotchas: refer to variables outside a function

Consider the following code:

$x = 1
function changeit {
    "Changing `$x. Was: $x"
    $x = 2
    "New value: $x"
}
"`$x has value $x"
changeit
"`$x has value $x"

Not too complicated, right. Let’s see what happens when we run it:

$x has value 1
Changing $x. Was: 1
New value: 2
$x has value 1

What’s going on? Well, trying to change the value of $x inside the function did not work. Why not? What the statement $x = 2 actually does, is to create a local variable inside the function and give it the value of 2. Let’s fix that:

$x = 1
function changeit {
    "Changing `$x. Was: $x"
    $script:x = 2
    "New value: $x"
}
"`$x has value $x"
changeit
"`$x has value $x"

Now, we run it again:

$x has value 1
Changing $x. Was: 1
New value: 2
$x has value 2

The thing is that we have to explicitly tell Powershell to update the variable in the parent scope instead of creating a new variable in the current scope.

Powershell gotchas: calling a function

Consider the following code:

function f($a, $b, $c) {
	"f: `$a=$a, `$a.GetType()=$($a.GetType())"
	"f: `$b=$b, `$b.GetType()=$($b.GetType())"
	"f: `$c=$c, `$c.GetType()=$($c.GetType())"
}
f 1 2 3   # call f with three integers as parameters
f 1,2,3   # call f with an array of three integers
f (1,2,3) # as above

The gotcha here is not to fall into the trap to use a C#-like or Java(Script)-like syntax where parameters are separated by commas. The comma in Powershell is always an array constructor operator, and takes precedence over function application. (Which also means that adding paranthesis will yield the same result). The code above will result in:

f: $a=1, $a.GetType()=int
f: $b=2, $b.GetType()=int
f: $c=3, $c.GetType()=int
f: $a=1 2 3, $a.GetType()=System.Object[]
You cannot call a method on a null-valued expression.
At ...function-application.ps1:4 char:11
+ $b.GetType <<<< ()
    + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
f: $b=, $b.GetType()=
You cannot call a method on a null-valued expression.
At ...function-application.ps1:5 char:11
+ $c.GetType <<<< ()
    + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
f: $c=, $c.GetType()=
f: $a=1 2 3, $a.GetType()=System.Object[]
You cannot call a method on a null-valued expression.
At ...function-application.ps1:4 char:11
+ $b.GetType <<<< ()
    + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
f: $b=, $b.GetType()=
You cannot call a method on a null-valued expression.
At ...function-application.ps1:5 char:11
+ $c.GetType <<<< ()
    + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
f: $c=, $c.GetType()=