社内SEの話

日々起きたことの記録用

PowerShellで使えるループ処理大全

↓プログラミングで副業を考えたらこちら↓

こんにちは、はじめまして。めじろです。
PowerShellで使えるループ処理について日々使っていてナレッジがある程度溜まったので、メモとしてまとめてみました。 大半は

docs.microsoft.com ここに書かれている通りですが、それ以外にも例外的な動きや、このページに書かれていないループ処理などがあるので、まとめました。
もしよければ活用してもらえると、嬉しいです。

ForEach

構文

foreach(アイテム in オブジェクト){

    処理内容

 }

サンプル

$ComputerName = 'hogehoge', 'fugafuga'

foreach ($Computer in $ComputerName) {

  Write-Host $Computer

}

実行結果

hogehoge

fugafuga

For文

構文

for(初期化式; 条件式; 更新式){

 処理内容

}

サンプル

for ($i = 0; $i -lt 10; $i++) {

    Write-Host " $i 回目"

  }

実行結果

 0 回目

 1 回目

 2 回目

 3 回目

 4 回目

 5 回目

 6 回目

 7 回目

 8 回目

 9 回目

注意点

サンプル

for ($i = 0; $i -lt 10; $i++) {

    Write-Host " $i 回目"

}

Write-Host " $i 回目"

実行結果

 0 回目

 1 回目

 2 回目

 3 回目

 4 回目

 5 回目

 6 回目

 7 回目

 8 回目

 9 回目

 10 回目 ←カウントアップしている

まずfor文の外でも使えます。
またfor文の外で$iを使用すると更新式が処理されています。

条件式で一致してすぐにループを抜けるのではなく、更新式で更新されてからループを抜けるので注意が必要です。

Do Until

自分はあまり使いませんが、VBAを書くときにはDoUntilが無限ループなのでよく使っていたので、個人意見ですがレガシー的ループな位置づけです

VBAではUntilのつける位置で処理回数などが変わりますが、PowerShellではUntilは処理が終わったあとに評価します。

構文

do {

処理内容

}

until (条件式)

サンプル

$number = Get-Random -Minimum 1 -Maximum 10

do {

  $guess = Read-Host -Prompt "What's your guess?"

  if ($guess -lt $number) {

    Write-Output 'Too low!'

  }

  elseif ($guess -gt $number) {

    Write-Output 'Too high!'

  }

}

until ($guess -eq $number)

Do While

Do Untilと同じ動きをしますが動くそうです。

VBAを使ったことがあるので、DoUntilを想像しがちですが、これでも同じだそうです。

サンプル

$number = Get-Random -Minimum 1 -Maximum 10

do {

  $guess = Read-Host -Prompt "What's your guess?"

  if ($guess -lt $number) {

    Write-Output 'Too low!'

  } elseif ($guess -gt $number) {

    Write-Output 'Too high!'

  }

}

while ($guess -ne $number)

While

条件に一致するまで実行します。

Whileを使う場合はこの様に一致するまで無限に繰り返すときのような際に自分は使います。

構文

while(条件式){

処理内容

}

サンプル

while($True){

    $d = Read-Host -Prompt "数値を入力してください"

    if($d -eq 1){

        break

    }

}

実行結果

数値を入力してください: 2

数値を入力してください: 3

数値を入力してください: 1

break

途中でループ処理を中断したいときに使います。

Whileに限らず全てのループ処理で使えます。

メインはWhileです。

サンプル

while($True){

    $d = Read-Host -Prompt "数値を入力してください"

    if($d -eq 1){

        break

    }

}

実行結果

数値を入力してください: 2

数値を入力してください: 3

数値を入力してください: 1

Continue

処理の途中でループを再開させる。

サンプル

while($True){

    $d = Read-Host -Prompt "数値を入力してください"

    if($d -eq 1){

        break

    }elseif ($d -eq 3) {

        Write-Host "アホになります"

        Continue

    }

    Write-Host "再挑戦してください"

}

実行結果

数値を入力してください: 2

再挑戦してください

数値を入力してください: 3

アホになります

数値を入力してください: 1 

3を入力時に動きが違うことが確認できます。

比較演算子

演算子 等式 意味
= -eq 等しい
!= -ne 等しくない
> -gt より大きい
>= -ge 以上
< -lt 次の値未満
<= -le 以下

ポイントは右辺が左辺を比較するということになります。

Poweshell以外の言語は不等号の向き(< >など)で左辺、右辺を気にしませんが、PowerShellでは明確に指示しないと目的の処理と真逆の演算をしてしまいます。

docs.microsoft.com

Switch

Switch文はif文のように制御系のように思われがちですが、Powershellではループ処理と似た動きをさせる事ができます。
具体例をあげるとContinueとBreakが使えます。

サンプル

$i = 3
switch ($i) {
    1 { write-host "①です" }
    2 { write-host "②です" }
    3 { 
        write-host "③です" 
        break
    }
    Default {write-host "その他です" } 
}

こんな風に使うことができます。
この仕様は不都合になるケースがあります。
例えばFor文の中でSwitch文を使い条件に一致したら、Breakで抜ける。

サンプル

for($i = 0;$i -le 10;$i++)
{
    switch ($i) {
        1 { write-host "①です" }
        2 { write-host "②です" }
        3 { 
            write-host "③です" 
            break
        }
        Default {write-host "その他です" } 
    }
}

結果

その他です
①です
②です
③です
その他です
その他です
その他です
その他です
その他です
その他です
その他です

Forがすべて実行されてしまいました。
理由は3のBreakはSwitchでのBreakになりForを抜けるBreakにはなっていません。
ループ文とSwitch文を併用する場合はBreakラベルを使えば回避できます。

サンプル

:forlabel for($i = 0;$i -le 10;$i++)
{
    :switchlabel switch ($i) {
        1 { write-host "①です" }
        2 { write-host "②です" }
        3 { 
            write-host "③です" 
            break forlabel
        }
        Default {write-host "その他です" } 
    }
}

Breakラベルのループ処理を抜けることができます。

結果

その他です
①です
②です
③です

ワンライナー

PowerShellの特徴的な機能の一つにパイプ処理があります。

PowerShellはターミナルで処理を実行する事も想定しているので、前述のプログラムでは使い勝手が悪いシーンもあります。

プログラムを1行にまとめて、1つのコマンドとして処理させる事を可能にしています。

プログラムを結合する事をパイプといいます。

そして、パイプを繋いで1行として処理することをワンライナーと呼んでいます

ForEach-Object

ForEachと似ていますが、ワンライナーのループ文になります

サンプル

'hogehoge', 'fugahuga' | ForEach-Object {Write-Host $_}

$_ 引き継だ変数名($PSItemでも可)

For文

ループのページに書かれていませんが、ワンライナーでFor文を書くこともできます。

下記のページに当たり前に書かれているので、ちゃんと使えます。

docs.microsoft.com

サンプル

$min_count = 0

$max_count = 10

$min_count .. $max_count | %{ Write-Host "$_ 回目" }

実行結果

0 回目

1 回目

2 回目

3 回目

4 回目

5 回目

6 回目

7 回目

8 回目

9 回目

10 回目

一定の回数をただ回したい時に便利なのでよく使います。

変数以外にも

1..10 | %{ Write-Host "$_ 回目" }

でも可能です。

最後に

いかがでしたか? お役に立ちましたでしょうか? 今後もブログの方を更新していきますのでよろしくお願いします。 最後になりますが、もしよろしければ読者の皆様からご支援いただけるのであればご支援いただきたく思います。 Amazon欲しい物リストを公開していますので、ご支援よろしくお願いします。 www.amazon.jp
またTwitterYoutubeもやっています。よければフォロー、チャンネル登録をお願いします。
Twitter: @whiteye8780
www.youtube.com