コマンドプロンプトから PowerShell を実行する

にメンテナンス済み

コマンドプロンプトだけでは難しい処理(ZIP 圧縮、日付の書式変換、JSON の解析など)は、PowerShell をコマンドプロンプトから呼び出すことで実現できます。powershellコマンドを使えば、バッチファイルの中にも PowerShell の処理を組み込めます。

この記事では、powershellコマンドの基本的な使い方と、つまずきやすい引用符・エスケープ・実行ポリシーの扱いを解説します。

powershellコマンドの基本構文

powershell [-NoProfile] [-ExecutionPolicy <ポリシー>] -Command "<コマンド>"
powershell [-NoProfile] [-ExecutionPolicy <ポリシー>] -File <スクリプトのパス> [引数...]

コマンドプロンプトでpowershellだけを入力すると、プロンプトがPS C:\>に変わり、PowerShell の対話モードに入ります。元に戻るにはexitと入力します。

powershell と pwsh

Windows に標準で入っているpowershellは Windows PowerShell 5.1 です。別途インストールする PowerShell 7 以降はpwshコマンドで起動します。この記事のオプションは、どちらでも同じように使えます。

コマンドを1つだけ実行する(-Command)

-Commandにコマンドを渡すと、実行後にコマンドプロンプトへ戻ります。

powershell -Command "Get-Date"

-Commandは省略できます(powershell "Get-Date")。ただし、引数の解釈が分かりにくくなるため、明示しておくのがおすすめです。

PowerShell のコマンド(コマンドレット)はGet-ChildItemのような「動詞-名詞」形式が基本です。たとえば、カレントフォルダーのファイルを更新日時の新しい順に5件だけ表示するには、次のようにします。

powershell -NoProfile -Command "Get-ChildItem | Sort-Object LastWriteTime -Descending | Select-Object -First 5 Name, LastWriteTime"

|が二重引用符"の内側にあるため、コマンドプロンプトではなく PowerShell のパイプとして処理されます。

よく使うオプション

オプション説明
-Command指定した文字列を PowerShell のコマンドとして実行する
-File指定した.ps1スクリプトを実行する
-NoProfileプロファイル(起動時の設定スクリプト)を読み込まない。起動が速くなり、環境差も出にくい
-NonInteractiveユーザーへの入力待ちをしない。確認が必要な処理はエラーになる
-ExecutionPolicy <ポリシー>このプロセスだけ実行ポリシーを指定する(Bypassなど)
-NoExitコマンドを実行した後も PowerShell を終了しない
-EncodedCommandUTF-16LE の文字列を Base64 でエンコードしたコマンドを渡す(引用符の問題を避けたいとき)

バッチファイルから呼び出すときは、-NoProfileを付けておくと安定します。

スクリプトファイルを実行する(-File)

処理が長くなる場合は、PowerShell の処理を.ps1ファイルに分けて-Fileで実行するのが安全です。

hello.ps1
param([string]$Name = 'World')
Write-Host "Hello, $Name!"
powershell -NoProfile -ExecutionPolicy Bypass -File .\hello.ps1 -Name Taro
- □ ×
コマンド プロンプトのアイコン
コマンド プロンプト
Microsoft Windows [Version xx.x.xxxxx.xxx]
(c) 2026 Ribbit App Development All rights reserved.
 
C:\users\user>powershell -NoProfile -ExecutionPolicy Bypass -File .\hello.ps1 -Name Taro
Hello, Taro!
C:\users\user>

実行ポリシーのエラーが出たとき

.ps1ファイルを実行しようとして「このシステムではスクリプトの実行が無効になっているため…」というエラーが出る場合は、実行ポリシーが原因です。-ExecutionPolicy Bypassを付けると、そのプロセスに限ってポリシーを回避できます。システム全体の設定は変更されません。

-Command には実行ポリシーは関係しません

実行ポリシーが制限するのは.ps1ファイルの実行です。-Commandで渡した文字列そのものは、実行ポリシーの制限を受けません。ただし、-Commandの中から.ps1を呼び出す場合は、そのスクリプトにポリシーが適用されます(-NoProfileを付けないと、プロファイルの読み込みでもエラーになることがあります)。また、-ExecutionPolicy Bypassは信頼できるスクリプトにだけ使いましょう。組織の管理者がグループポリシーで実行ポリシーを設定している場合は、-ExecutionPolicyで上書きできません。

引用符・特殊文字の扱い

コマンドプロンプトと PowerShell の両方を通るため、特殊文字の扱いに注意が必要です。

文字コマンドプロンプト(cmd)での注意対処
"-Commandの全体を囲むのに使う内側では'(一重引用符)を使うと楽
%バッチファイル内では変数展開される%%と書く
| & >二重引用符の外にあると cmd が解釈する二重引用符の中に入れる、または^で退避
$cmd では特別な意味なし。PowerShell の変数として扱われるそのまま書ける
!遅延展開が有効なとき消える遅延展開を無効にして実行する

最も簡単な対策は、コマンド全体を"で囲み、中の文字列リテラルには'を使うことです。

powershell -NoProfile -Command "Write-Host 'こんにちは' ; (Get-Date).ToString('yyyy-MM-dd')"

"をどうしても内側で使う場合は、\"と書くことで渡せます。

powershell -NoProfile -Command "Write-Host \"現在の時刻: $((Get-Date).ToString('HH:mm'))\""
複雑になったら .ps1 に分ける

エスケープが2重3重になって読みにくくなってきたら、-Commandで頑張らずに.ps1ファイルに切り出して-Fileで実行しましょう。保守もしやすくなります。

実行結果をバッチファイルで使う

出力を変数に格納する

for /fを使うと、PowerShell の出力をバッチファイルの変数に取り込めます。バッチファイルの中では%を%%にします。

get-date.cmd
@echo off

for /f "usebackq delims=" %%d in (`powershell -NoProfile -Command "Get-Date -Format yyyyMMdd_HHmmss"`) do set TIMESTAMP=%%d
echo %TIMESTAMP%

for /fにusebackqを付けると、コマンドを逆引用符(`)で囲めるようになります。PowerShell 側で一重引用符'を使っても、for /fの構文と衝突しません。

日付の書式変換は PowerShell が楽

コマンドプロンプトの%date%は地域設定によって形式が変わりますが、PowerShell のGet-Date -Formatなら設定に左右されず同じ形式の文字列を得られます。

終了コードを受け取る

-Commandで実行した場合、最後に実行したコマンドが成功すれば0、失敗すれば1がERRORLEVELに入ります。外部プログラムの終了コードはそのまま引き継がれないことがあるため、確実に伝えたいときや細かく制御したいときは、exitで終了コードを指定します。

powershell -NoProfile -Command "if (Test-Path 'C:\data') { exit 0 } else { exit 2 }"
echo %ERRORLEVEL%

-Fileで実行したスクリプトも、exit <数値>で終了コードを返せます。

実用例:ZIP 圧縮・解凍

Compress-ArchiveとExpand-Archiveを使うと、コマンドプロンプトから ZIP を扱えます。

フォルダーを
powershell -NoProfile -Command "Compress-Archive -Path 'C:\data\*' -DestinationPath 'C:\backup\data.zip' -Force"
ZIP
powershell -NoProfile -Command "Expand-Archive -Path 'C:\backup\data.zip' -DestinationPath 'C:\restore' -Force"

Compress-Archiveの-Forceは既存の ZIP ファイルを、Expand-Archiveの-Forceは解凍先にある同名のファイルを上書きします。

実用例:テキストの置換

ファイル内の文字列を置換する処理は、コマンドプロンプトだけでは難しいですが、PowerShell なら簡単です。

powershell -NoProfile -Command "(Get-Content 'a.txt' -Raw -Encoding UTF8) -replace 'foo','bar' | Set-Content 'b.txt' -Encoding UTF8"
文字コードに注意

Windows PowerShell 5.1 のSet-Contentは、-Encodingを省略するとシステムの既定コードページ(日本語環境では Shift_JIS 系)で書き出します。文字化けを避けるため、読み込みと書き込みの両方で-Encodingを明示しましょう。なお、5.1 の-Encoding UTF8は BOM 付きで書き出します(PowerShell 7 では BOM なし)。また、バッチファイル自体を UTF-8 で保存していると、-Command内の日本語が文字化けすることがあります。文字コードについては、関連記事も参照してください。

まとめ

やりたいことコマンド
PowerShell を対話モードで起動するpowershell
1つのコマンドを実行するpowershell -NoProfile -Command "..."
.ps1スクリプトを実行するpowershell -NoProfile -ExecutionPolicy Bypass -File a.ps1
PowerShell 7 を使うpwsh -NoProfile -Command "..."
出力を変数に取り込むfor /f "delims=" %%x in ('powershell ...') do set VAR=%%x
終了コードを受け取る%ERRORLEVEL%

関連記事

練習問題

練習問題

.ps1ファイルを、実行ポリシーのエラーを回避しながら実行する書き方として適切なものはどれでしょうか?

正しいものを 1 つ選んでください。

  1. powershell -NoProfile -ExecutionPolicy Bypass -File .\a.ps1
  2. powershell -NoProfile -Command Bypass .\a.ps1
  3. powershell -NoExit -File

練習問題

バッチファイルの中で-Commandに渡す文字列に%を含めたいとき、どのように書けばよいでしょうか?

正しいものを 1 つ選んでください。

  1. \%と書く
  2. %%と書く
  3. ^%と書く
#コマンドプロンプト #バッチファイル #コマンドライン #PowerShell #コマンド