PowerShellの変数の使い方|宣言・型・スコープ・文字列展開を解説

当ページのリンクには広告が含まれています。
PowerShellの変数の宣言・型・スコープ・文字列展開

PowerShellのスクリプトを書き始めると真っ先に登場するのが変数です。$を付けて名前を決めるだけなので簡単そうに見えますが、いざ使ってみると文字列に埋め込むところで思った表示にならなかったり、代入したはずの値がいつの間にか消えていたりすることってありますよね。

この記事では変数の宣言から型の指定、スコープの違い、文字列への埋め込み方まで、実際にコマンドを動かしながら確認した内容を中心に解説します。特に文字列展開のところは実際に試してみると地味にハマりやすいポイントがあります。

PowerShellの変数は$変数名 = 値で作成し$変数名で参照します。型は代入した値から自動的に決まりますが、[int]のように型を指定することも可能です。文字列へ埋め込むときはダブルクォートを使い、変数名の直後に文字やコロンが続く場合は${変数名}で区切ります。

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

Windows 11 Home 25H2

PowerShell

7.6.5

※変数まわりの動作はWindows・macOS・Linuxで共通の言語仕様のため環境が違っても結果はほぼ変わりません。$env:USERNAMEなどはWindows固有の項目です。

目次

PowerShellの変数とは

変数は値を一時的に保存しておく入れ物です。PowerShellでは変数名の先頭に$を付けて表します。

PowerShell
$name = "Chun"

$nameという名前の箱に"Chun"という文字列を入れているイメージです。一度代入した値は同じセッション内であれば何度でも呼び出せます。

PowerShell
$name
実行結果
Chun

型を宣言しなくてもそのまま使えるのがPowerShellの特徴です。この点は後述の「型を確認・指定する」で改めて触れます。

変数を宣言して値を取得する

文字列だけでなく数値や真偽値もそのまま代入できます。

PowerShell
$str = "Hello, PowerShell"
$num = 100
$bool = $true

値を確認する方法としてWrite-HostWrite-Outputのふたつがよく使われますが、この2つは似ているようで役割が違います。

PowerShell
Write-Host $str
Write-Output $num
実行結果
Hello, PowerShell
100

見た目の出力結果は同じに見えますが実際に動かして比べてみると挙動に差がありました。

PowerShell
$resultA = Write-Host "test"
$resultB = Write-Output "test"
"resultA is: [$resultA]"
"resultB is: [$resultB]"
実行結果
test
resultA is: []
resultB is: [test]
PowerShellでWrite-HostとWrite-Outputを変数へ代入したときの実行結果の違い
Write-Hostは画面表示、Write-Outputは成功出力ストリームへ値を送る

Write-Hostは画面表示向けのコマンドで、Write-Outputが使う成功出力ストリームにはオブジェクトを流しません。そのため、この例では$resultAに値が入りません。PowerShell 5.0以降のWrite-Hostは情報ストリームへ書き込むため、情報ストリームとして抑止やリダイレクトが可能です。一方、Write-Outputは成功出力ストリームへ値を送り、変数への代入や後続のパイプライン処理に利用できます。後で値を使う場合は、Write-Outputまたは式をそのまま出力します。

変数の値を変更・削除する

値を再代入する

変数の値は代入し直すだけで上書きされます。

PowerShell
$name = "1st Chun"
$name = "2nd Chun"
$name
実行結果
2nd Chun

Clear-Variableで値だけを消す

値だけを空にしたい場合はClear-Variableを使います。

PowerShell
$name = "Chun"
Clear-Variable -Name name
"Clear-Variable後: [$name]"
実行結果
Clear-Variable後: []

値は空になりましたが変数自体は残っています。Get-Variableで確認すると存在していることがわかります。

PowerShell
Get-Variable -Name name -ErrorAction SilentlyContinue | ForEach-Object { "あるよ!" }
実行結果
あるよ!

参考:Microsoft公式のClear-Variable

Remove-Variableで変数ごと消す

変数そのものを削除したい場合はRemove-Variableを使います。

PowerShell
$name2 = "Chun"
Remove-Variable -Name name2
Get-Variable -Name name2 -ErrorAction SilentlyContinue | ForEach-Object { "あるよ!" }
実行結果
(何も表示されない = 存在しない)

Clear-Variableは「値だけ空にする」、Remove-Variableは「変数そのものをなくす」という違いですね。削除した変数をそのまま参照してもエラーにはならず、黙って空の値($null扱い)が返ってくるだけでした。これは後述の「よくある間違い」でも触れる、PowerShellの少し独特な挙動です。

なお$name = $nullとしても見た目の結果はClear-Variableとほぼ同じになります。$nullの代入は値そのものを書き換える操作なのに対し、Clear-Variableは「値のリセット」を意図した専用のコマンドレットです。スクリプトの意図を明確にしたい場合はClear-Variableを使うのがおすすめです。

参考:Microsoft公式のRemove-Variable

文字列の中へ変数を埋め込む

ダブルクォートとシングルクォートの違い

PowerShellでは文字列の展開がダブルクォートとシングルクォートで変わります。

PowerShell
$name = "Chun"
"Hello, $name"
'Hello, $name'
実行結果
Hello, Chun
Hello, $name

ダブルクォートは変数を展開する「展開文字列」、シングルクォートは書いた通りに扱う「リテラル文字列」です。変数をそのまま文字として表示したい場合はシングルクォートを使うと覚えておくとよいです。

$()で式やプロパティを展開する

プロパティやメソッドの結果、計算式などを文字列に埋め込みたいときは$()(サブ式演算子)を使います。

PowerShell
$now = Get-Date
"現在時刻は $($now.ToString("HH:mm:ss")) です"
"1 + 1 の結果は $(1 + 1) です"
実行結果
現在時刻は 18:14:33 です
1 + 1 の結果は 2 です

$now.ToString(...)のようにプロパティやメソッドを呼び出す場合は$()で囲む必要があります。"$now.ToString(...)"のように直接書いてしまうと.ToString(...)の部分がただの文字として扱われてしまうので注意してください。

コロンや日本語が直後に続くと起きること

変数名の直後に別の文字が続く場合、区切りが曖昧になって思わぬ結果になることがあります。

まずはコロンのケースです。

PowerShell
$name = "Chun"
"$name:test"
実行結果
(何も表示されない)

エラーにもならず、ただ空文字が返ってきました。PowerShellは$name:の部分を「nameという名前のスコープにあるtestという変数」($スコープ名:変数名という書き方)だと解釈してしまうため、該当するスコープが存在せず黙って空の値になってしまうようです。

さらに紛らわしいのが、コロンの直後に続く文字によって挙動が変わる点です。Microsoft公式ドキュメントにある$HOME:を使った例では、コロンの直後が半角スペースだとパースエラーになりました。

PowerShell
"$HOME: where the heart is."
実行結果
ParserError:
Line |
   1 |  "$HOME: where the heart is."
     |   ~~~~~~
     | Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using ${} to
     | delimit the name.

⚠️ 注意 同じ「コロンの後に文字が続く」パターンでも、変数名として解釈できる文字が続くと$name:testのように黙って空文字になり、変数名として使えない文字(スペースなど)が続くとエラーになるという違いがあります。地味に厄介なのは前者で、エラーにならない分バグに気づきにくいところです。

日本語ならではの落とし穴もありました。ひらがなやカタカナも変数名に使える文字として扱われるため、変数のすぐ後ろに日本語を続けると意図しない結果になります。

PowerShell
$name = "Chun"
"$nameさん"
実行結果
(何も表示されない)

これは$nameさん全体をひとつの変数名として解釈してしまうためです(ひらがなも変数名に使える文字に含まれます)。日本語の文章に変数を埋め込むとき、地味にハマりやすいパターンだと思います。

対策は${}で変数名を明示的に区切ることです。

PowerShell
$name = "Chun"
"${name}:test"
"${name}さん"
実行結果
Chun:test
Chunさん

変数の直後に文字や記号を続けて文章にする場合は、とりあえず${変数名}の形にしておくと安心です。半角スペースを1つ挟むだけでも回避できますが、レイアウトの都合でスペースを入れたくない場面もあると思うので${}で囲む方法を覚えておくと便利です。

参考:Microsoft公式のabout_Quoting_Rules

PowerShellの変数の型を確認・指定する

GetType()で型を確認する

代入した値の型はGetType()メソッドで確認できます。

PowerShell
$count = 10
$count.GetType()
実行結果
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType

文字列を代入した場合はString型になります。

PowerShell
$name = "Chun"
$name.GetType()
実行結果
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

PowerShellの変数は宣言時に型を指定しなくても代入した値に応じて自動的に型が決まる「動的型付け」です。ひとつの変数に別の型の値を入れ直すこともできてしまいます。

[string]や[int]で型を指定する

変数の型を固定したい場合は変数名の前に[型名]を付けます。

PowerShell
[int]$count = 10
$count.GetType()
実行結果
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType

数値に変換できる文字列であれば代入時に自動で変換してくれます。

PowerShell
[int]$count = "20"
"文字列'20'を代入 -> $count ($($count.GetType().Name))"
実行結果
文字列'20'を代入 -> 20 (Int32)

型に合わない値を代入したときの動き

数値に変換できない文字列を代入しようとするとエラーになります。

PowerShell
[int]$count2 = "abc"
実行結果
MetadataError: Cannot convert value "abc" to type "System.Int32". Error: "The input string 'abc' was not in a correct format."

⚠️ 注意 実際に試してみると、このエラーはスクリプトの実行自体を止めるものではなく、エラーメッセージを表示したまま次の行の処理へ進んでしまいました。「エラーが出ているのに処理が続いている」という状態に気づきにくいので、型を指定した変数へ外部入力(CSVの値やユーザー入力など)を代入する場合は、あらかじめtry/catchで挟んでおくと安心です。

型の詳しい仕様はMicrosoft公式のabout_Variablesにもまとまっているので、より詳しく知りたい方はあわせてチェックしてみてください。

変数のスコープを理解する

変数には「どこから参照できるか」を示すスコープという概念があります。

スコープ説明
ローカル現在のスコープです。関数の中で作った変数は基本的にこのスコープになります。
スクリプトスクリプトファイル全体で有効なスコープです。$script:を付けて明示できます。
グローバルセッション全体で有効なスコープです。$global:を付けて明示できます。

関数の中で変数を作ると関数の外の同名変数には影響しません

PowerShell
$name = "スクリプト全体のChun"

function Show-Name {
    $name = "関数内だけのChun"
    "関数内での値: $name"
}

Show-Name
"関数呼び出し後、スクリプト側の値: $name"
実行結果
関数内での値: 関数内だけのChun
関数呼び出し後、スクリプト側の値: スクリプト全体のChun

関数の中で$nameに代入していますが、これは関数内だけで有効な別の変数として扱われるためスクリプト側の$nameは変わりません。

.ps1スクリプト内の関数から、そのスクリプトのスコープにある変数を更新する場合は$script:を付けます。次の例はコードを.ps1ファイルとして保存し、スクリプトとして実行することを前提にしています。

PowerShell
$counter = 0

function Add-Counter {
    $script:counter = $script:counter + 1
    "関数内でのカウンター: $script:counter"
}

Add-Counter
Add-Counter
"スクリプト側のカウンター最終値: $counter"
実行結果
関数内でのカウンター: 1
関数内でのカウンター: 2
スクリプト側のカウンター最終値: 2

$script:を付けることで関数呼び出しをまたいでカウンターの値を積み上げられるようになりました。単純なカウンターやフラグを関数間で共有したいときによく使う書き方です。スコープの詳しい仕様はMicrosoft公式のabout_Scopesで確認できます。

環境変数と通常の変数の違い

$env:Pathのようにenv:が付いた変数を見かけたことがあるかもしれませんが、これは通常の変数とは別物です。OS側が管理する環境変数を参照・設定するための書き方になります。

以下はWindowsでの例です。macOSやLinuxではユーザー名の取得に$env:USERが使われることが多く、環境変数名の大文字と小文字も区別されます。

PowerShell
$name = "Chun"
$env:MY_APP_NAME = "ChunLog"

"通常の変数 name : $name"
"環境変数 MY_APP_NAME : $env:MY_APP_NAME"
"env:を付けずに参照した場合 : $MY_APP_NAME"
実行結果
通常の変数 name : Chun
環境変数 MY_APP_NAME : ChunLog
env:を付けずに参照した場合 :

$env:を付けずに$MY_APP_NAMEと書いてもそれは環境変数とは無関係の別の(未定義の)変数として扱われます。名前が似ているだけでまったくの別物なので、環境変数のつもりで$だけを付けて参照してしまうと空振りすることになります。


環境変数の詳しい仕組みやPathの優先順位については以下の記事で解説しているのであわせて確認してみてください。

変数を使うときによくある間違い

変数名のスペルミス

存在しない変数を参照してもエラーにはならず、黙って空($null)が返ってきます。タイプミスに気づきにくい原因のひとつです。

PowerShell
$myValue = "test"
"スペルミスした変数を参照: [$myVal]"
実行結果
スペルミスした変数を参照: []

数値のつもりが文字列になっている

文字列と数値を+で結合するとき、左側の変数の型によって結果が変わります。

PowerShell
$a = "5"
$b = 3
"文字列'5' + 数値3 = $($a + $b)"

$c = 5
$d = "3"
"数値5 + 文字列'3' = $($c + $d)"
実行結果
文字列'5' + 数値3 = 53
数値5 + 文字列'3' = 8

左が文字列だと文字列結合(53)に、左が数値だと数値の加算(8)になります。CSVやユーザー入力から読み込んだ値は文字列型であることが多いので、計算に使う前に[int]などで型変換しておくと事故を防げます。

変数を使った簡単なスクリプト例

ここまでの内容を組み合わせた簡単な例です。フォルダーのパスと繰り返し回数を変数にして、簡易的なメッセージを表示します。

PowerShell
$folderPath = "C:\Work\Reports"
$userName = $env:USERNAME
$repeatCount = 3

"対象フォルダ: $folderPath"
"実行ユーザー: $userName"

for ($i = 1; $i -le $repeatCount; $i++) {
    "${i} 回目の処理を実行中です(${userName} さんの ${folderPath} に対して)"
}

$env:USERNAMEはWindowsでログイン中のユーザー名が自動的に入る環境変数です。ファイルパスやユーザー名のような「後で変わるかもしれない値」を変数にしておくと、スクリプトの使い回しがしやすくなります。


CSVファイルを読み込みながら変数を使う実践的な例は以下でも紹介しているので興味があれば見てみてください。


作成したスクリプトを.ps1ファイルとして保存して実行しようとすると実行ポリシーのエラーに当たることがあります。その場合は以下の記事も参考にしてください。

よくある質問

変数に型を書かなくても動くのはなぜ?

PowerShellの変数は動的型付けのため代入した値に応じて型が自動的に決まります。厳密に型を固定したい場合のみ[int][string]を付ければ十分です。

$null$falseは同じ扱いですか?

$nullは「値が存在しない」ことを表し、$falseは真偽値の値そのもので異なるものです。条件式の中では両方とも偽として扱われる場面がありますが、意味は別物なので使い分けを意識しておくとよいです。

変数名にはどんな文字が使える?

英数字とアンダースコアが基本ですが、実はひらがな・カタカナ・漢字などのUnicode文字も変数名として使えてしまいます。ですが、この記事で紹介したコロンや日本語直後の展開トラブルの原因にもなっているので変数名自体は半角英数字とアンダースコアにとどめておくのが無難です。

環境変数を変更するとPC全体の設定も変わる?

PowerShellで$env:変数名に代入した変更は既定では現在のプロセス(開いているPowerShellセッション)にだけ反映されます。PowerShellを閉じるとその変更は引き継がれません。ユーザー単位やシステム全体の環境変数を恒久的に変更する場合は、Windowsの環境変数設定や[Environment]::SetEnvironmentVariable()など別の方法を使用します。

まとめ

  • 変数は$変数名 = 値で宣言できて型は自動で決まるよ。
  • 値だけ消すならClear-Variable、変数ごと消すならRemove-Variableを使い分けてね。
  • 文字列に埋め込むときはダブルクォートを使って$()でプロパティや式も展開できるよ。
  • 変数名の直後にコロンや日本語を続けるとうまく展開されないことがあるから${}で囲むと安心だよ。
  • スコープを意識しないと関数の中と外で値が食い違うことがあるから$script:も覚えておいてね。

PowerShellの基本操作やファイル操作、ログ監視、文字列検索などもまとめて確認したい場合はこちら。

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