PowerShellスクリプトのチートシート

toc目次

PowerShellスクリプトの拡張子

PowerShellスクリプトファイルの拡張子は「.ps1

Hello World

Write-Hostでコンソールに文字を表示します。

Write-Host "Hello, World!"
実行結果 Hello, World!

コメント文

行コメント「#」、複数行コメントは「<#...#>」で囲います。

# 行コメント

<#
複数行
コメント
#>

変数

変数宣言

変数名は先頭に「$」を付けます。変数は動的型付けです(変数の値で型が決まる)。

$a = 12      # Int32
$b = "Word"  # String

[型名] 変数名 = 値で静的型付けも可能です。

[int] $i = 10
[string] $s = "hoge"

変数の型

.NETの型が使用可能です。

【参考】.NET type
[array] System.Array
[bool] System.Boolean
[byte] System.Byte
[char] System.Char
[datetime] System.DateTime
[decimal] System.Decimal
[double] System.Double
[guid] System.Guid
[hashtable] System.Collections.Hashtable
[int16] System.Int16
[int32], [int] System.Int32
[int64], [long] System.Int64
[nullable] System.Nullable
[psobject] System.Management.Automation.PSObject
[regex] System.Text.RegularExpressions.Regex
[sbyte] System.SByte
[scriptblock] System.Management.Automation.ScriptBlock
[single], [float] System.Single
[string] System.String
[switch] System.Management.Automation.SwitchParameter
[timespan] System.TimeSpan
[type] System.Type
[uint16] System.UInt16
[uint32] System.UInt32
[uint64] System.UInt64
[xml] System.Xml.XmlDocument

変数のスコープ

$[スコープ名:]変数名 = 値でスコープを指定可能です。
スコープを指定しない場合はローカルスコープとなります。

# グローバルスコープ(どこからでも参照可)
$global:a = 10

# スクリプトスコープ(同一スクリプト内で参照可)
$script:a = 10

#プライベートスコープ(現在のブロック内で参照可)
$private:a = 10

# ローカルスコープ(現在のブロックおよび子ブロックで参照可)
$a = 10

演算子

算術演算子

演算子 内容
+ $a + $b 加算
- $a - $b 減算
* $a * $b 乗算
/ $a / $b 除算
% $a % $b 余剰
- -$a 符号反転

代入演算子

演算子 内容
= $a = $b 代入
+= $a += $b 加算代入
-= $a -= $b 減算代入
*= $a *= $b 乗算代入
/= $a /= $b 除算代入
%= $a %= $b 余剰代入
++ ++$a, $a++ インクリメント
-- --$a, $a-- デクリメント

比較演算子

演算子 内容
-eq $a -eq $b 等価(==)
-ne $a -ne $b 不等価(!=)
-gt $a -gt $b より大きい(>)
-ge $a -ge $b 以上(>=)
-lt $a -lt $b より小さい(<)
-le $a -le $b 以下(<=)

論理演算子(ブール演算子)

演算子 内容
-and $a -and $b 論理積(AND)
-or $a -or $b 論理和(OR)
-xor $a -xor $b 排他的論理和(XOR)
-not -not $a 論理否定(NOT)
! !$a 論理否定(NOT)

ビット演算子

演算子 内容
-band $a -band $b ビット論理積(AND)
-bor $a -bor $b ビット論理和(OR)
-bxor $a -bxor $b ビット排他的論理和(XOR)
-bnot -bnot $a ビット否定(NOT)
-shl $a -shl $b 左シフト
-shr $a -shr $b 右シフト

リダイレクト演算子

演算子 内容
> n> 指定したストリームをファイルにリダイレクト(上書き)
>> n>> 指定したストリームをファイルにリダイレクト(追記)
>&1 n>&1 指定のストリームをSuccessストリームにリダイレクト

nにはストリーム番号を指定します。
ストリーム番号を省略した場合は1Success Stream)が指定される。

ストリーム番号一覧

No Stream
1 Success Stream
2 Error Stream
3 Warning Stream
4 Verbose Stream
5 Debug Stream
6 Information Stream
* All Streams

型演算子

演算子 内容
-is $a -is [型] 値の型が一致するか比較
-isnot $a -isnot [型] 値の型が一致しないか比較
-as $a -as [型] 値を指定の型にキャスト

文字列演算子

演算子 内容
+ "a" + "b" 文字列の連結
-join -join ("a", "b", "c") 複数の文字列を1つの文字列に結合
-split "a,b,c" -split ',' 文字列を部分文字列に分割

文字列比較演算子

演算子 用例 内容
-like $a -like [ワイルドカード] ワイルドカードと等しい
-notlike $a -notlike [ワイルドカード] ワイルドカードと等しくない
-match $a -match [正規表現] 正規表現と等しい
-notmatch $a -notmatch [正規表現] 正規表現と等しくない
  • 大文字と小文字は区別されません。
  • 大文字と小文字を区別するには演算子名の前に「c」を付けます。
    • -like-clike
    • -notlike-cnotlike
    • -match-cmatch
    • -notmatch-cnotmatch

文字列リテラル

ダブルクオート「""」またはシングルクォート「''」で囲います。

ダブルクオートで囲った場合、変数展開されます。

$s = "test"
Write-Host "$s"
実行結果 test

シングルクォートで囲った場合、変数展開されません。

$s = "test"
Write-Host '$s'
実行結果 $s

ヒアドキュメント

@""@」または「@''@」で囲います。

文字列リテラルと同様に「@""@」(ダブルクオート)は変数展開されます。

$s = "bbb"
$str = @"
aaa
$s
ccc
"@
Write-Host $str
実行結果 aaa
bbb
ccc

@''@」(シングルクォート)は変数展開されません。

$s = "bbb"
$str = @'
aaa
$s
ccc
'@
Write-Host $str
実行結果 aaa
$s
ccc

変数展開

変数展開の際、変数名のあとに半角文字が続くと最後までを変数名と認識します。
変数名を正しく認識させるためには「${}」で囲います。

$a = "hoge"
$aa = "fuga"
Write-Host "$aa"
Write-Host "${a}a"
Write-Host "${aa}"
実行結果 fuga
hogea
fuga

プロパティや配列を展開する場合は「$()」で囲います。

$str = "hoge"
Write-Host "$($str.GetType())"
実行結果 string
$array = @("hoge", "fuga")
Write-Host "$($array[0])"
実行結果 hoge

特殊文字

文字 説明
`0 Null
`a アラート
`b バックスペース
`e エスケープ
`f フォームフィード
`n 改行
`r キャリッジリターン
`t 水平タブ
`u{x} Unicodeエスケープシーケンス
`v 垂直タブ

※ 先頭はバッククオート「`」です(シングルクオート「'」ではないので注意)

特殊変数(自動変数)

変数 説明
$null Null値
$true True値
$false False値
$_ パイプラインオブジェクト内の現在のオブジェクト
$args 関数、スクリプト渡されるパラメーターの値の配列
$Error 直近のエラーを表すエラーオブジェクトの配列
$foreach ForEachループの列挙型
$input 関数に渡されるすべての入力を列挙する列挙子
$Matches -matchで一致した文字列値

一覧は以下参照

配列

# 空の配列
$a = @()

# 配列
$a = @("a", "b", "c")

# @()は省略可
$a = "a", "b", "c" # @("a", "b", "c")と同じ

# 連続値の配列
$a = 1..5   # @(1, 2, 3, 4, 5) と同じ

ハッシュテーブル(連想配列)

# 空のハッシュテーブル
$map = @{}

# ハッシュテーブル
$map = @{ a = 1; b = 2; c = 3 }

リスト

PowerShellの組み込み型にリストはないため.NETのクラスを利用します。

$list = New-Object System.Collections.ArrayList

[void]$list.Add("A")
[void]$list.Add("B")
[void]$list.Add("C")

ループ(繰り返し)処理

for文

for (<初期化式>; <条件式>; <変化式>) {
    <処理>
}
for ($i = 0; $i -lt 3; $i++) {
    Write-Host $i
}
実行結果 0
1
2

foreach文

foreach (<変数名> in <コレクション>) {
    <処理>
}
$array = "a", "b", "c"
foreach ($s in $array) {
    Write-Host $s
}
実行結果 a
b
c

while文

while (<条件式>) {
    <処理>
}
$i = 0
while ($i -lt 3) {
    Write-Host $i
    $i++
}
実行結果 0
1
2

do-while文

do {
    <処理>
} while (<条件式>)

do-until文

do {
    <処理>
} until (<条件式>)

ループ制御

break文

forforeachwhileなどのループ内で現在のループを終了します。

for ($i = 0; $i -lt 4; $i++) {
    for ($j = 0; $j -lt 4; $j++) {
        if ($j -eq 2) { break }
        Write-Host $i $j
    }
}
実行結果 0 0
0 1
1 0
1 1
2 0
2 1
3 0
3 1

ラベル付きbreak文

現在のループを終了するのではなく、ラベル付きのループを終了します。

:loop for ($i = 0; $i -lt 4; $i++) {
    for ($j = 0; $j -lt 4; $j++) {
        if ($j -eq 2) { break loop }
        Write-Host $i $j
    }
}
実行結果 0 0
0 1

continue文

forforeachwhileなどのループ内で現在のループの先頭に処理を戻します。

for ($i = 0; $i -lt 4; $i++) {
    for ($j = 0; $j -lt 4; $j++) {
        if ($j -eq 2) { continue }
        Write-Host $i $j
    }
}
実行結果 0 0
0 1
0 3
1 0
1 1
1 3
2 0
2 1
2 3
3 0
3 1
3 3

ラベル付きcontinue文

現在のループの先頭に処理を戻すのではなく、ラベル付きのループの先頭に処理を戻します。

:loop for ($i = 0; $i -lt 4; $i++) {
    for ($j = 0; $j -lt 4; $j++) {
        if ($j -eq 2) { continue loop }
        Write-Host $i $j
    }
}
実行結果 0 0
0 1
1 0
1 1
2 0
2 1
3 0
3 1

分岐処理

if文

if (<条件1>) {
    <処理>
}
elseif (<条件2>) {
    <処理>
}
else {
    <処理>
}
$n = 2

if ($n -eq 1) {
    Write-Host "one"
}
elseif ($n -eq 2) {
    Write-Host "two"
}
elseif ($n -eq 3) {
    Write-Host "three"
}
else {
    Write-Host "else"
}
実行結果 two

switch文

switch (<>) {
    <条件1> {<処理>}
    <条件2> {<処理>}
    default {<処理>}
}
$n = 2

switch ($n) {
    1 { Write-Host "one" }
    2 { Write-Host "two" }
    3 { Write-Host "three" }
    default { Write-Host "default" }
}
実行結果 two

例外処理(try-catch-finally)

try {
    <処理>
}
catch [<例外>] {
    <処理>
}
finally {
    <処理>
}
try {
    Write-Host "try"

    # FileNotFoundExceptionをスロー
    throw [IO.FileNotFoundException]::new()
}
catch [IO.FileNotFoundException] {
    Write-Host "FileNotFoundException"
}
catch [IO.IOException] {
    Write-Host "IOException"
}
catch {
    Write-Host "Exception"
}
finally {
    Write-Host "finally"
}
実行結果 try
FileNotFoundException
finally

関数

関数定義

function <関数名> (<引数>) {
    <処理>
}

引数はparamで関数内に指定することもできます。

function <関数名> {
    param (<引数>)
    <処理>
}
# 関数定義
function Add-Numbers ([int]$a, [int]$b) {
    return $a + $b
}

# 関数呼び出し
Add-Numbers 1 2
実行結果 3

デフォルト引数

「引数 = 値」で引数を省略した場合のデフォルト値を設定可能です。

function Hoge ($a, $b = "default") {
    echo ('$a = ' + $a + ', $b = ' + $b)
}

Hoge
Hoge "aaa"
Hoge "aaa" "bbb"
Hoge -b "bbb" -a "aaa" # 名前指定で引数渡し(引数の順序は任意)
実行結果 $a = , $b = default
$a = aaa, $b = default
$a = aaa, $b = bbb
$a = aaa, $b = bbb

関数へのパイプライン処理

function <関数名> {
    begin   {<処理>}
    process {<処理>}
    end     {<処理>}
}

process処理はパイプラインの各オブジェクトに対して1回ずつ実行されます。
$_はパイプラインオブジェクト内の現在のオブジェクトを表す変数です。

function Get-Pipeline {
    process { "The value is: $_" }
}

1, 2, 4 | Get-Pipeline
実行結果 The value is: 1
The value is: 2
The value is: 4

begin処理は入力を渡す前に実行、end処理は入力を取得した後に実行します。
$inputは関数に渡されるすべての入力です。

function Get-PipelineBeginEnd {
    begin { "Begin: The input is $input" }
    end { "End:   The input is $input" }
}

1, 2, 4 | Get-PipelineBeginEnd
実行結果 Begin: The input is
End: The input is 1 2 4

process処理で入力を使用すると$inputは空となります。

function Get-PipelineInput {
    process { "Processing:  $_ " }
    end { "End:   The input is: $input" }
}

1, 2, 4 | Get-PipelineInput
実行結果 Processing: 1
Processing: 2
Processing: 4
End: The input is:

クラス

クラス定義

class <クラス名> {
    <プロパティ>
    <コンストラクタ>
    <メソッド>
}

インスタンス化は以下構文のいずれかを使用します。

<変数名> = New-Object <クラス名>(<引数>)

<変数名> = [<クラス名>]::new(<引数>)
class Person {
    # プロパティ
    [string]$name
    [int]$age

    # コンストラクタ(クラス名と同名のメソッドがコンストラクタとなる)
    Person([string]$name, [int]$age) {
        $this.name = $name
        $this.age = $age
    }

    # メソッド
    [void]Display() {
        Write-Host "Name:$($this.name)、Age:$($this.age)"
    }
}

# インスタンス化(New-Object)
$p1 = New-Object Person("Tanaka", 20)
$p1.Display()

# インスタンス化([クラス名]::new())
$p2 = [Person]::new("Yamada", 30)
$p2.Display()

# プロパティのアクセス権はpublicなので直接更新可能
$p1.age = 40
$p1.Display()
実行結果 Name:Tanaka、Age:20
Name:Yamada、Age:30
Name:Tanaka、Age:40

クラスの継承

「クラス名:継承するクラス名」で継承します。

class <クラス名>: <継承するクラス名> {
    <プロパティ>
    <コンストラクタ>
    <メソッド>
}
class Person {
    # プロパティ
    [string]$name
    [int]$age

    # コンストラクタ(クラス名と同名のメソッドがコンストラクタとなる)
    Person([string]$name, [int]$age) {
        $this.name = $name
        $this.age = $age
    }

    # メソッド
    [void]Display() {
        Write-Host "Name:$($this.name)、Age:$($this.age)"
    }
}

# Personクラスを継承
class Student:Person{
    [int]$grade

    # base()で親クラスのコンストラクタ呼び出し
    Student([string]$name, [int]$age, [int]$grade) : base($name, $age) {
        $this.grade =$grade
    }

    # オーバーライド
    [void]Display() {
        Write-Host "Name:$($this.name)、Age:$($this.age), Grade:$($this.grade)"
    }
}

$p3 = [Student]::new("Suzuki", 18, 1)
$p3.Display()
実行結果 Name:Suzuki、Age:18, Grade:1

.NETクラスライブラリの使用

Add-Typeまたは[Reflection.Assembly]を使用します。

# Add-Type
Add-Type -AssemblyName System.Net.Http

# Reflection.Assembly
[void][Reflection.Assembly]::LoadWithPartialName("System.Net.Http")