PowerShell For Loop:包括的なガイド

PowerShellスクリプトを使用してシステムを管理したり、一括タスクを処理したりする際には、スクリプトの一部としてループ構造を使用する必要が生じることでしょう。PowerShellにはさまざまな種類のループがあり、その1つがforループです。PowerShellのforループを使用すると、複数のアイテムに対して同じセットのコマンドを素早く実行し、一貫した結果を得ることができます。

この記事では、PowerShellのforループとは何か、その構文とforループ文を構成する要素について理解することができます。さらに、例からさまざまな方法でforループを使用する方法も学ぶことができます。

PowerShellのforループ文とプレースホルダの理解

PowerShellのforループは、コマンドやプロセスの実行回数(繰り返し回数)が既にわかっている場合によく使用されます。例えば、配列内の値の一部のみを処理したい場合(例: X個のアイテムのうち10個のみを処理する)、forループを使用します。

forループを使用すると、コードが終了する条件や制限をより細かく制御することができます。これは、foreachループForEach-Objectコマンドレットとは異なり、コレクション内の最後のアイテムの処理後に反復が停止する点と比較されます。

以下は、forループ文の構文です。

for (<Initial iterator value>; <Condition>; <Code to repeat>)
{
    <Statement list>
}

上記の構文の通り、PowerShellのforループ文は4つのプレースホルダに分解することができます。これらは初期化条件繰り返し、およびステートメントリストのプレースホルダです。

  • 初期プレースホルダーは、開始値を指定する場所です。この値はステートメントによって一度だけ読み取られます。通常、スクリプターはこの変数にゼロの値を割り当てます。
  • 条件プレースホルダーは、ループを続行するか終了するかを決定する制限または条件を指定します。このプレースホルダーで使用される式はtrueに評価されます。
  • 繰り返しプレースホルダーは複数のコマンドを受け入れます。このプレースホルダーで提供されるコマンドは、各ループの繰り返し後、条件が再評価される前に実行されます。スクリプターは通常、初期プレースホルダー内の値を増やすか減らすための式を提供するためにこれを使用します。
  • 最後に、ステートメントリストプレースホルダーには実行したいメインのコードが配置されます。このプレースホルダー内のコードは、条件$Falseを返すまで、ループで繰り返されます。

PowerShellのForループの実行フローを理解する

PowerShellのForループの動作をさらに理解するには、その実行フローを把握する必要があります。Forループは最初は4つのステッププロセスで始まり、初回実行後に3つのステッププロセスに変わります。詳細を説明するために、以下のアルゴリズムを読み続けてください。

ステップ1

Forループステートメントの開始時に、初期の値が読み取られ、メモリに格納されます。

例:$num = 0

ステップ2

forループ文は、Conditionプレースホルダー内の式のブール結果を評価します。結果が$falseである場合、forループは終了します。結果が$trueである場合、forループは次のステップに進みます。

例:$num -lt 10

ステップ3

PowerShellは、ステートメントリストプレースホルダー内のコードを実行します。1つまたは複数のコマンド、スクリプトブロック、または関数が含まれている場合があります。

例:"I count $num "

ステップ4

このステップでは、繰り返しプレースホルダー内の式が実行され、初期値プレースホルダーの現在の値が更新されます。その後、フローはステップ2に戻ります。

例:$num++

PowerShellのForループの使用方法(例)

次のセクションでは、さまざまな方法でforループを使用するいくつかの例を紹介します。これらの例は、そのままでは実用的または現実的な用途があるかもしれません。ただし、学んだ技術を使用して、実際に必要な場合にforループを使用する際のガイドとなることができます。

forループの動作原理がわかったので、基本的なコードを使用して全体がどのように組み合わされるかを見てみましょう。

数のシーケンスを取得する

以下のコードは、$numの値が10になるまで、1から始まる文字列"I count $num"をコンソールに繰り返し表示します。

for ($num = 1 ; $num -le 10 ; $num++){    "I count $num"}

上記のコードをコピーしてPowerShellセッションに貼り付けて実行すると、以下のスクリーンショットの結果が表示されます。

For loop example to display numbers less than 10

文字列の連結

forループ文は、加算、減算、乗算などの数式だけでなく、文字列の値を連結するためにも使用することができます。

以下の例では、「x」という文字を行ごとに1文字ずつ増やしながら、行の文字数が30になるまで繰り返します。

上記のコードでは、$xの値は0文字を含む''で初期化されていることがわかります。条件に基づく制限は、$xの値の文字数が30に達するまでです。各繰り返しの後、文字「x」が$xの値に追加されます。

for ($x='' ;$x.length -le 30;$x=$x+'x'){
    Write-Host $x
    Start-Sleep -Milliseconds 20
}

以下の出力は、上記のコードをPowerShellで実行した場合の予想される結果を示しています。

String concatenation example using For Loop

複数の初期値と繰り返し式を使用した文字列の連結

forループ文のInitialおよびRepeatのプレースホルダーは、複数の式を受け入れることができます。

前の例のコードを使用して、Repeatプレースホルダーに新しい式を追加してランダムな色を選択できるようにコードを変更することができます。ランダムな色は、コンソールに表示される文字列の前景色として使用されます。

最初の行で、色の名前が含まれる配列が定義されていることがわかります。forループ操作は、この配列からランダムに色名を選択します。

InitialおよびRepeatのプレースホルダーには、今では2つの式が含まれていることに注意してください。各式は括弧で囲まれ、カンマで区切られています。

$colors = @("Green","Cyan","Red","Magenta","Yellow","White")
for (($x=''),($fgcolor = $colors | Get-Random) ;$x.length -le 30;($x=$x+'x'),($fgcolor = $colors | Get-Random)){
    Write-Host $x -ForegroundColor $fgcolor
    Start-Sleep -Milliseconds 20
}

変更されたコードをPowerShellで実行すると、予想される結果は以下の通りです。

String concatenation example using For Loop

進行状況の表示

forループの最も一般的な使用法は、進行状況インジケータを表示するためです。これは、時間がかかる可能性がある複数のアイテムに対してタスクを実行する場合によく使用されます。たとえば、Exchange組織内のすべてのメールボックスのサイズのレポートを作成したり、複数のユーザーの属性を更新したりする場合です。

以下のサンプルコードは、1から100%までの進行状況を表示する基本的な方法を示しています。初期値$counterは1であり、条件は$counterの値が100に達するまでこのループが続行されることを示しています。

for ($counter = 1; $counter -le 100; $counter++ )
{
		# ここにコードを追加
    Write-Progress -Activity "Update Progress" -Status "$counter% Complete:" -PercentComplete $counter;
}

上記のコードをPowerShellで実行すると、以下のような出力が表示されるはずです。

Progress counter driven by for loop

カウントダウンタイマーの表示

次のコードは、forループを使用してカウントダウンタイマーを表示する方法を示しています。このカウントダウンタイマーは、10から始まる残りの秒数のみを表示します。

開始数を変更したい場合は、初期のプレースホルダ内の$seconds変数の値を変更するだけです。

for ($seconds=10; $seconds -gt -1; $seconds--) {
    Write-Host -NoNewLine ("`rseconds remaining: " + ("{0:d4}" -f $seconds))
    Start-Sleep -Seconds 1
}

上記のコードをPowerShellで実行すると、以下のサンプル出力が表示されます。

A countdown timer that is driven by for loop

カウントダウンタイマーの表示(ネストされたforループ)

minutes:seconds形式でカウントダウンタイマーを表示したい場合はどうすればよいですか?ネストされたforループを使用してそれを実現することができます。ネストされたforループは、単に別のforループ内にあるforループです。

以下のサンプルコードには、2つのforループステートメントが含まれています。

最初のforループは、タイマーの部分のカウントダウンを処理します。forループの前に$minutes変数があり、forループがカウントダウンする分数を指定する必要があります。

2番目のforループは、タイマーの部分のカウントダウンを処理します。各反復後、ループは再開する前に1秒間一時停止します。$secondsの値が0になるまで続けます。

# カウントダウンする分数を設定します
$minutes = 1

for ($minutes--; $minutes -gt -1; $minutes--)
{
    for ($seconds = 59 ; $seconds -gt -1 ; $seconds--)
    {
        $remaining = ("{0}:{1}" -f ("{0:d4}" -f $minutes),("{0:d2}" -f $seconds))
        Write-Host "`r$remaining" -NoNewline
        Start-Sleep -Seconds 1
    }
}

上記のコードを実行すると、以下のようなカウントダウンタイマーが表示されます。

A Countdown timer using nested for loop

素数を判定する

PowerShellのforループは数学的な操作にも適しています。この例では、forループを使用して指定された数が素数かどうかを判定します。

A prime number is a number that is only divisible by 1 and N, where N is the number itself. For example, if the value of N is 7, then N divided by 1 is 7 divided by 1.

以下のスクリプトは、実行されると以下の操作を行います:

  • ユーザーに数値の入力を促します。
  • 入力数値を被除数とし、除数は2から入力数値から1を引いた数です。つまり、入力値が7の場合、除数は2、3、4、5、6の順になります。
  • 商が整数である場合、入力された数は素数ではなく、forループは終了します。
  • 商が整数でない場合、入力された数は素数です。

このスクリプトをisPrime.ps1としてコピーして保存してください。

$num = Read-Host "Input a number"

$isPrime = $true
for ($y = 2 ; $y -lt $num ; $y++ )
{
    if (($num / $y) -is [int]) {
        Write-Host "$num is not a prime number"
        $isPrime = $false
        break
    }
}

if ($isPrime -eq $true) {
    Write-Host "$num is a prime number"
}

isPrime.ps1スクリプトを保存したら、PowerShellで実行してテストしてください。以下はサンプル出力です。

Using for loop in a script to determine a prime number

概要

PowerShellのforループは、他の言語で使用されるforループ機能と比較しても驚くべきことはありません。これにより、概念に慣れていない場合でも適応しやすくなります。

この記事では、PowerShellのforループステートメントの基本を学びました。構文、ロジック、フローについて学び、さまざまな目的に使用する方法についていくつかの例からも学びました。

PowerShellには他の種類のループがあるとはいえ、どれが他よりも優れていると言うのは不公平です。コードの目的とコードを書いている人の好みによります。

この記事から得た知識を活用して、forループを使用して通常の面倒なタスクを自動化する方法を見つけることができるはずです。

さらに学習するための資料

Source:
https://adamtheautomator.com/powershell-for-loop/