Check out CGSE Powershell tips.

Left-operand casting

Powershell will always take the type of the left operand to determine what the type of the final expression will be

1+"2"      # 3
"1"+2      # "12"

Implicit casting

You use a string in arithmetic operations, and you can interestingly use suffixes and prefixes too:

"0x$h"  # convert hex string to number
"0b$b"  # convert binary string to number

The n suffix is useful to create large BigInts like powers of ten:

[bigint]::Pow(10,50)
(0n)::Pow(10,50)
'10n*'*50+1|iex
"1$('0'*50)n"
'9'*50+'n'

Accessing static methods via instances

You don't need to spell out the entire library name when using the method:

[Math]::pow(10,$x)
(0n)::pow(10,$x)

$x=4,2,3
[Array]::sort($x)
$x::Sort($x)
"$x" # 2 3 4

[Array]::Reverse($x)
$x::Reverse($x)
"$x" # 4 3 2

Wildcards

Wildcards are super useful in powershell golf. Here is a list of some of them:

String.EnumerateRunes      *es
Rune.Value                 V*
String.ToCharArray         t*y
String.Substring           Su*
String.Replace             *ace
String.Trim                *m
String.ToLower             *wer
String.length              le*
String.ToUpper             *per
MatchInfo.Matches          m*
String.Indexof             i*f
String.Split               sp*, s*t
String.PadLeft             *ft
String.PadRight            *ht
Convert.ToString           *g

Note that it doesn't matter whether uppercase or lowercase Wildcards are used (the entire language is case insensitive).


This feature is very useful when obtaining the characters of a string (if you're ok with getting the acsii values):

$a.tochararray()
[char[]]$a
$a|% t*y

The |% t*y is short for | ForEach-Object -Method ToCharArray

If you happen to want to use the characters (as numbers, e.g. if the string was "1738") instead, make sure to not use ($_-48)

$a|% t*y|%{($_-48)...}
$a|% t*y|%{+"$_"}

You can remove the + sometimes due to automatic casting.


In some cases, using sls combined with a m wildcard can be shorter than using -match

if($x-match'pattern'){$matches}
$x|sls 'pattern'|% m*
$x|sls pattern|% m*             # if there's no | in pattern

Aliases

Aliases are incredibly useful in powershell golf, some of the main ones include:

?         Where-Object
%         ForEach-Object
gu        Get-Unique
sort      Sort-Object
iex       Invoke-Expression

Use Get-Alias to see them all.

iex

iex is extremely useful in some cases:

(...|measure -s).Sum
...-join'+'|iex

[math]::pow($a,$b)
(0n)::pow($a,$b)
"$a*"*$b+1|iex

...-join'+'|iex may actually have a bigger save:

'+...'*$x|iex

Char ranges

Character ranges are pretty useful in the case that you need them:

32..68|%{[char]$_}
' '..'D'|%{$_}

while loop

Instead of the usual while loop:

while(condition){}
for(;condition){}

You can even put code before the ; to save another byte if you have any code before the while.

Joining

If you want to join by spaces you can save a lot of bytes:

(...)-join" "
"$(...)"

Joining by nothing:

(...)-join""
-join(...)

If you are joining by a number, you don't need quotes around it. This works for -split and -replace too.

(...)-join'0'
(...)-join0

Getting the value of a regex match

Use a interpolation string instead of the longer function:

(regex_match).value
"$(regex_match)"

List of strings

Use echo instead of using a list of strings:

("abc","cde","efg","hij")
echo abc cde efg hij