Skip to content

Instantly share code, notes, and snippets.

@ggorlen
Last active May 20, 2023 05:42
Show Gist options
  • Select an option

  • Save ggorlen/1e337f211f508124321c8bc7c1d264ed to your computer and use it in GitHub Desktop.

Select an option

Save ggorlen/1e337f211f508124321c8bc7c1d264ed to your computer and use it in GitHub Desktop.
PowerShell gotchas

PowerShell gotchas

See this SO thread

PowerShell and the -contains operator

Passing multiple arguments to a function

Given:

function Add-Numbers([int]$a, [int]$b) {
    return $a + $b
}

The code:

echo Add-Numbers(3, 2)

Prints:

Add-Numbers
3
2

But

echo (Add-Numbers 3 2) # => 5

Explanation

Variable interpolation

$a = 4
echo "$a" # => 4
echo "$($a)" # => 4
echo "$($($a))" # => 4

Reassigning types

function Maskify([string]$cc) {
    $res = ""
    $cc = $cc.ToCharArray()

    foreach ($c in $cc) {
        $res += "#"
    }

    $res
}

echo (Maskify "1234") # => #

This seems like it should loop 4 times and return "####" but only loops once. Possible fixes include removing the [string] type on the parameter or using $ccc = rather than $cc = and using $ccc in the foreach.

[int] rounds rather than floors

echo ([int]1.5) # => 2, not 1

Hash lookups with string index need cast

$hash = @{A = 42; B = 1}
$s = "AB"
echo $s[0] # => A
echo $hash[$s[0]] # => null
echo $hash[[string]$s[0]] # => 42

Inconsistent multidimensional array syntax

$arr = @(@(1, 2), @(3, 4))

echo $arr[0][0] # => 1
echo $arr[0][1] # => 2
echo $arr[1][0] # => 3
echo $arr[1][1] # => 4
echo $arr.length # => 2

$arr = @(@(1, 2))

echo $arr[0][0] # => 1
echo $arr[0][1] # => missing!!?
echo $arr.length # => 2 !!?

# correct:

$arr = @(,@(1, 2))
echo $arr[0][0] # => 1
echo $arr[0][1] # => 2
echo $arr.length # => 1

It turns out the @ symbols and parens are sort of optional. The best generalization seems to be:

$arr = ,(1, 2), (3, 4)
# or
$arr = ,(,1, 2), (,3, 4)

$arr = ,(,(,1, 2)), (,(,3, 4))
echo $arr[0][0][0] # => 1
echo $arr[0][0][1] # => 2
echo $arr[1][0][0] # => 3
echo $arr[1][0][1] # => 4
echo $arr.length # => 2

Explanation

Nested array indexing makes no sense

$arr = 1, 2
echo $arr[0] # => 1
echo $arr[0][0] # => 1
echo $arr[0][0][0] # => 1
echo $arr[0][0][0][0][0] # => 1
echo $arr[0][0][0][0][1] # => missing (`Unable to index into an object of type System.Int32` in strict mode)
echo $arr[0][-1][-1][-1][-1] # => 1

Pipelined function output is weird

function a() {
    echo 41
    42
    return 43
}

echo a # => a (hah! just testing)
echo (a) # => 41 42 43

Naturally this isn't the case with class methods:

class Test {
    [int] a() {
        echo 41
        42
        return 43
    }
}

$x = [Test]::new()
echo ($x.a) # => OverloadDefinitions ... what?
echo $x.a() # => 43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment