PowerShellの配列の使い方|追加・削除・検索・ループ処理を解説

当ページのリンクには広告が含まれています。
PowerShellの配列への要素追加・削除・検索と、foreachで順番に処理するイメージ

PowerShellでちょっとしたスクリプトを書こうとして配列に要素を追加する書き方をど忘れしてしまうことってありませんか。自分用の備忘録も兼ねて配列の作成から取得、追加、削除、検索、そしてforeachでのループ処理までを一通りメモメモしました。

検証環境(確認日:2026年9月)
OS

Windows 11 Home 25H2

pwsh.exe

7.6.5

powershell.exe

5.1.26100.9278

目次

配列操作の早見表

やりたいこと書き方
配列を作る$a = @("A","B","C")
空の配列を作る$a = @()
連番の配列を作る$a = 1..10
先頭の要素を取得する$a[0]
末尾の要素を取得する$a[-1]
要素数を確認する$a.Count
要素を追加する$a += "D"
要素を削除する$a = @($a | Where-Object { $_ -ne "B" })
値が含まれるか確認する$a -contains "B"
条件で絞り込む$a | Where-Object { $_ -like "A*" }
重複を除いて並べ替える$a | Sort-Object -Unique
順番に処理するforeach ($x in $a) { Write-Output $x }

PowerShellの配列とは

配列複数の値をひとつの変数にまとめて管理できる仕組みです。フォルダ内のファイル名を1つずつ別々の変数に入れる代わりに、配列にまとめて入れておけば後からforeachなどで一括処理できます。

PowerShell
$fruits = @("Apple", "Banana", "Orange")

@()は配列を作るための記号(配列サブ式演算子)です。中の値をカンマで区切って並べればそれだけで配列になります。$fruits.GetType().FullNameを実行するとSystem.Object[]と表示され、配列として扱われていることが確認できます。


$を付けた変数への代入やGetType()による型の確認から整理したい場合は変数の基本操作をまとめた記事も参考にしてください。

配列を作成する方法

複数の値から配列を作る

PowerShell
$fruits = @("Apple", "Banana", "Orange")

実は@()を省略して次のように書いても配列になります。

PowerShell
$fruits = "Apple", "Banana", "Orange"

@()を付けたほうが「配列を作っている」という意図が伝わりやすいので、筆者的には付けたほうが良いんじゃないかなと思います。

空の配列を作る

PowerShell
$empty = @()

これから+=などで要素を追加していく土台として使うことが多いです。

数値の連続した配列を作る

PowerShell
$numbers = 1..10

..は範囲演算子と呼ばれ、1から10までの連続した整数が入った配列を一発で作れます。10..1のように書けば降順の配列になります。

1要素でも配列として扱う

下記のように記載すると$singleは配列ではなく文字列型になりますよね。

PowerShell
$single = "Apple"

要素が1つでも配列にしたいときは@()か、先頭にカンマを付ける書き方を使います。

PowerShell
$single = @("Apple")
$single = ,"Apple"

配列の要素を取得・変更する

インデックスは0から始まります。先頭は[0]、末尾は[-1]で取得できます。

PowerShell
$fruits[0]
$fruits[-1]
実行結果
Apple
Orange

値の書き換えも代入するだけです。

PowerShell
$fruits[1] = "Grape"

複数の要素をまとめて取り出したいときはインデックスをカンマで並べるか範囲を指定します。

PowerShell
$fruits[0,2]
$fruits[0..1]

配列の要素数を確認する

要素数の確認には.Count(または.Length)を使います。

PowerShell
$fruits.Count

コマンドの結果をそのまま変数へ代入すると1件だけ返った場合は配列ではなく、そのオブジェクト自体が入ることがあります。PowerShell 3.0以降は多くの単一オブジェクトでも.Countを使えますが、Windows PowerShell 5.1のPSCustomObjectなどには例外があります。件数にかかわらず配列として扱いたい場合は、コマンドの実行結果を@()で囲んで受け取ります。

配列が空(変数としては存在しているが内容が全くない)かどうかを判定したいときは次のように書きます。

PowerShell
if ($fruits.Count -eq 0) {
    Write-Output "配列は空です"
}

配列へ要素を追加する

要素の追加には+=を使います。

PowerShell
$fruits += "Grape"

.NETの配列はサイズが固定です。固定とはいっても追加できないワケではないですが、Windows PowerShell 5.1やPowerShell 7.4以前では+=による配列への追加を繰り返すと配列の作り直しとコピーが処理の負担になります。

PowerShell 7.5ではオブジェクト配列への+=が最適化されました。「大量に追加するなら必ずListの方が速い」とは言い切れません。追加や削除をメソッドで扱いたい場合はSystem.Collections.Generic.Listが便利です。

PowerShell
$list = [System.Collections.Generic.List[string]]::new()
$list.Add("Apple")
$list.Add("Banana")

新しく可変長のコレクションを使う場合MicrosoftはArrayListよりList<T>を推奨しています。性能を比較するときは、使用するPowerShellのバージョンと実際の処理内容を揃えて確認してください。

配列の追加、Listの追加動作の実測比較をしてみた

同じPCでWindows PowerShell 5.1とPowerShell 7.6.5を動かし、配列への+=とListへの追加を比較しました。今回の環境では、7.6.5の+=は5.1より大幅に短時間になったものの、Listへの追加の方が速い結果でした。

CPUはAMD Ryzen 7 9700Xを使用し、両方とも64bitプロセスで実行しています。

項目検証条件
入力データあらかじめ作成した文字列入りの object[]
Listの型System.Collections.Generic.List[object]
計測回数各件数・各方式で2回ウォームアップ後、8回計測
掲載値処理時間の中央値。単位はミリ秒

入力データの生成、画面表示、結果の検証、CSV保存は計測に含めていません。各試行の前にGCを実行し、方式の実行順を入れ替えています。Listから配列へ変換する時間も対象外です。

Windows PowerShell 5.1の結果

作成方法1,000件10,000件30,000件
配列へ+=で追加10.1551,233.55013,410.610
ListへAdd()で追加0.0450.4891.480
Listの初期容量を指定して追加0.0480.4721.445
foreachの出力をまとめて配列へ格納0.0420.4351.355

5.1では+=を繰り返した場合の所要時間が件数とともに大きく増えました。30,000件では約13.4秒かかっており、ループ内で大量に追加する処理では差がはっきり出ています。

PowerShell 7.6.5の結果

作成方法1,000件10,000件30,000件
配列へ+=で追加0.23511.212279.531
ListへAdd()で追加0.1932.6562.587
Listの初期容量を指定して追加0.1952.6452.573
foreachの出力をまとめて配列へ格納0.0360.5570.482

7.6.5では30,000件の+=が約280ミリ秒で完了しました。5.1の約13.4秒と比べると所要時間は約48分の1です。

同じ7.6.5のListへの追加は約2.59ミリ秒で+=はその約108倍の時間がかかりました。今回の測定ではListの初期容量を指定しても、通常のListへの追加と大きな差はありませんでした。

比較した4方式のうち、各条件で中央値が最も小さかったのはforeachの出力をまとめて配列へ格納する方法です。ループで値を生成して最後にまとめて受け取る用途ではこの書き方も選択肢になります。

7.6.5のListなどでは10,000件より30,000件の中央値が小さくなる箇所があり、試行間のばらつきも確認できました。短時間の処理の小さな差や、件数に対する増加率は参考として見てください。また、5.1と7.6.5では.NETなどの実行環境も異なるため、バージョン間の差をすべて7.5の最適化だけによる効果とは断定できません

今回の環境ではループ内で大量に追加する用途にはListが有利でした。


手元のPowerShellのバージョン確認やWindows PowerShell 5.1と併用する7系の導入手順はこちらの記事で確認できます。

配列から要素を削除する

PowerShellの通常の配列には特定の要素だけを直接削除するメソッドがありません。配列自体がサイズ固定のオブジェクトだからです。実務ではWhere-Objectで対象を除外した新しい配列を作り直す形が基本になります。

PowerShell
$fruits = @("Apple", "Banana", "Orange")
$fruits = @($fruits | Where-Object { $_ -ne "Banana" })

この書き方は値が「Banana」の要素をすべて除外します。結果を@()で囲んでいるため、残る要素が0件や1件でも配列として扱えます

削除前後を比べるとこんな感じです。

実行前
Apple
Banana
Orange
実行後
Apple
Orange

追加・削除を頻繁に繰り返す配列であれば、先ほど紹介したListを使うとRemove()RemoveAt()でそのまま削除できるので扱いやすくなります。

PowerShell
$list.Remove("Banana")

配列から値を検索・抽出する

検索は「存在するかどうかを確認したいだけ」なのか「条件に合う要素を取り出したいのか」で使うものが変わります。ごちゃまぜにすると回りくどいコードになりがちなので、ここは分けて覚えておくのがおすすめです。

目的使うもの戻り値
値が含まれるか確認する-containsTrue / False
値が配列に含まれるか確認する(左右逆)-inTrue / False
条件に合う要素を取り出すWhere-Object条件に合う要素(複数可)
パターンに一致する要素を取り出す-match一致した要素(複数可)
値の位置(インデックス)を調べる[Array]::IndexOf()インデックス番号(見つからなければ-1)

存在確認

存在確認だけなら-containsが手軽です。

PowerShell
$fruits = @("Apple", "Banana", "Orange")
$fruits -contains "Apple"

-inは調べたい値を左側、配列を右側に書きます。1つの値が配列に含まれるかを確認する演算子です。

PowerShell
"Apple" -in $fruits

条件に合う要素を抽出する

条件付きで絞り込みたいときはWhere-Objectを使います。

PowerShell
$fruits | Where-Object { $_ -like "A*" }

正規表現を使う

正規表現で調べたいときは-matchが使えます。配列に対して使うとパターンに一致した要素だけが返ってきます。

PowerShell
$fruits -match "an"

要素の位置を把握する

位置そのものが知りたいときは[Array]::IndexOf()です。

PowerShell
[Array]::IndexOf($fruits, "Banana")

見つからない場合は-1が返ってくるので存在チェックとしても応用できます。

文字列を比較する-contains既定では大文字・小文字を区別しません。区別したい場合は-ccontainsを使います。文字列の配列に対する[Array]::IndexOf()は大文字・小文字を区別するため、検索方法によって結果が異なることがあります。

配列を並べ替えて重複を削除する

並べ替えはSort-Objectです。

PowerShell
$items = "Banana", "Apple", "Banana", "Orange", "Apple"
$items | Sort-Object

降順にしたいときは-Descendingを付けます。重複を除きながら並べ替えたい場合は-Uniqueです。

PowerShell
$items | Sort-Object -Unique

ここで意外と混同しやすいのがSelect-Object -Uniqueとの違いです。Sort-Object -Uniqueは並べ替えと同時に重複を除去しますが、Select-Object -Unique並び順を変えずに重複だけを取り除きます。順番を保ったまま重複だけ消したいのか、ソートしてから重複を消したいのかで使い分けるとよいです。

Select-Object -Uniqueは、既定では大文字・小文字を区別します。「Apple」と「apple」は別の値として残るため、順番だけでなく重複の判定方法にも注意してください。

PowerShell
$items | Select-Object -Unique

公式ドキュメントのSelect-Objectにも、-Uniqueが他のパラメーターの後に適用される点が説明されているので-Firstなどと組み合わせるときは一度目を通しておくと安心です。

foreachで配列を順番に処理する

配列を順番に処理する方法は大きく2つあります。foreach文とForEach-Objectコマンドレットです。

PowerShell
foreach ($fruit in $fruits) {
    Write-Output $fruit
}
PowerShell
$fruits | ForEach-Object { Write-Output $_ }

foreachは言語のキーワードで、配列をまるごと受け取ってから順番に処理します。ForEach-Objectはパイプラインで使うコマンドレットで、1件ずつ流れてくるデータをその場で処理していくイメージです。他のコマンドとパイプでつなげたいときや、パイプラインの途中に組み込みたいときはForEach-Objectのほうが書きやすいことが多いです。細かい使い分けまで踏み込むと長くなるので、ここでは基本的な違いだけ押さえておきます。

実測比較で紹介した「foreachの出力をまとめて配列へ格納する」は次の書き方です。ループ内で出力した値をまとめて受け取り@()で配列にします。

PowerShell
$fruits = @("Apple", "Banana", "Orange")

$result = @(foreach ($fruit in $fruits) {
    $fruit
})

配列と連想配列(ハッシュテーブル)の違い

配列は順番(インデックス)で値を管理しますが、ハッシュテーブルは名前(キー)で値を管理します。

PowerShell
$user = @{
    Name = "Taro"
    Age  = 30
}

値を取り出すときはキー名を指定します。

PowerShell
$user.Name
$user["Name"]
配列ハッシュテーブル
アクセス方法インデックス番号キー名
順序保持される保証されない([ordered]を付けると保持可能)
向いている用途同じ種類の値をまとめて扱う名前と値をセットで扱う

ハッシュテーブルの細かい操作は内容が多いので、また別の機会にじっくり扱えればと思います。詳しくは公式のabout_Hash_Tablesも参考にしてください。

配列を使った実践例

実務でよく使う組み合わせを4つ紹介します。以下はWindows環境を想定した例です。C:\workC:\work\data.csvは、実在するフォルダやCSVファイルのパスへ変更してください。CSVの例ではStatus列を使います。

複数ファイルを順番に処理する

PowerShell
$files = @(Get-ChildItem -Path "C:\work" -File)
foreach ($file in $files) {
    Write-Output $file.Name
}

特定の拡張子だけ抽出する

PowerShell
$txtFiles = @(
    Get-ChildItem -Path "C:\work" -File |
        Where-Object { $_.Extension -eq ".txt" }
)

サービス一覧から実行中のものだけ抽出する

PowerShell
$runningServices = @(
    Get-Service | Where-Object { $_.Status -eq "Running" }
)
$runningServices.Count

CSVから取得したデータを条件で絞り込む

PowerShell
$data = @(Import-Csv -Path "C:\work\data.csv")
$filtered = @($data | Where-Object { $_.Status -eq "Active" })

絞り込んだデータをCSVへ保存したい場合はExport-Csv の使い方と日本語の文字化けを防ぐ文字コードの指定方法も確認してください。

迷いやすいポイント

配列から1つだけ要素を削除したい、RemoveAtのようなメソッドはない?

通常の配列はサイズが固定なのでRemoveAt()で要素数を減らすことはできません。また、Where-Object { $_ -ne "Banana" } は「Banana」をすべて除外するため、重複した値を1件だけ削除する用途とは異なります。List では、Remove("Banana") で最初に一致した1件を、RemoveAt(1) でインデックス1の要素を削除できます。

.Countと.Lengthはどちらを使えばいい?

配列に対してはどちらも同じ値を返すので基本的にはどちらでも問題ありません。ハッシュテーブルには.Lengthがないので、迷ったら.Countを使っておくのが無難でしょうか。

大量のデータを扱うときはPowerShellの配列を使わない方がいい?

読み込んだデータをまとめて処理する用途なら、配列で問題ありません。追加・削除を繰り返しAdd()RemoveAt()で操作したい場合はListが便利です。+=の性能はPowerShell 7.5で改善されているため、件数だけで使い分けずバージョンと処理内容で判断します。

PowerShell 5.1と7.xで配列の挙動に違いはある?

作成・インデックスによる取得・foreachなどの基本操作は共通です。Windows PowerShell 5.1では単一のPSCustomObject.Countに注意が必要です。また、PowerShell 7.5では配列への+=が最適化されています。追加処理の性能はバージョンによって異なります。

まとめ

  • 配列は@()で作れて、複数の値を1つの変数にまとめて管理できるよ。
  • 要素の追加は+=で書けるよ。追加・削除をメソッドで操作したいときはListが便利だよ。
  • 削除は基本的にWhere-Objectで除外した新しい配列を作る形になるよ。
  • 検索は存在確認なら-contains-in、条件で絞り込むならWhere-Objectを使い分けてね。
  • ループ処理はforeachForEach-Objectで役割が違うから、場面に応じて選んでね。

配列を使うスクリプトの実行方法やファイル操作・ログ監視などの実践例はPowerShellまとめから目的別に探せます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次