【PowerShell】ps1が実行できない原因と対処|ExecutionPolicy・Unblock-File

【PowerShell】スクリプトが実行できない場合の対処方法 PowerShell

PowerShellで.ps1ファイルを実行しようとして、「このシステムではスクリプトの実行が無効になっているため」「running scripts is disabled on this system」と表示されることがあります。原因は実行ポリシーだけとは限らず、ダウンロードしたファイルのブロック、管理者権限不足、パス指定ミス、VS Codeやタスクスケジューラの起動方法が関係することもあります。

まずは設定を広く緩めるのではなく、どの理由で止まっているかを確認してから、必要な範囲だけ変更するのが安全です。この記事では、エラー別に確認コマンドと対処方法を整理します。

先に結論

  • 最初にGet-ExecutionPolicy -Listで全スコープを確認します。
  • 一度だけ実行するなら-ExecutionPolicy Bypassをプロセス単位で使います。
  • 普段使いならCurrentUserRemoteSignedを設定します。
  • インターネット由来のファイルはZone.Identifierを確認し、必要ならUnblock-Fileします。
  • GPOのMachinePolicyUserPolicyが有効なら、手元のSet-ExecutionPolicyでは上書きできません。
  • 実行ポリシーは安全機能の一部ですが、マルウェア対策の境界ではありません。内容を確認せずに実行しないでください。

PowerShellをバッチファイルから呼び出す場合はPowerShellをバッチファイルから呼び出す方法、管理者権限の扱いはバッチファイルで管理者権限を自動取得する方法も参考になります。

スポンサーリンク

エラー別の対処早見表

まず表示されたエラー文から、最初に確認する場所を決めます。原因が違うのに実行ポリシーだけを変更しても解決しません。

  • このシステムではスクリプトの実行が無効:Get-ExecutionPolicy -Listで全スコープを確認します。
  • 署名されていません:Zone.Identifierを確認し、信頼できるファイルだけUnblock-Fileします。AllSigned環境では署名済みスクリプトが必要です。
  • 用語として認識されません:.\script.ps1、フルパス、呼び出し演算子&を確認します。
  • アクセスが拒否されました:管理者権限、実行ユーザー、ファイル権限を確認します。
  • VS Codeでだけ失敗する:VS Code内のPowerShellバージョン、プロファイル、実行ポリシーを確認します。
  • タスクスケジューラでだけ失敗する:-NoProfile-ExecutionPolicy Bypass、開始フォルダ、実行ユーザーを確認します。
  • Set-ExecutionPolicyしても変わらない:MachinePolicyまたはUserPolicyが優先されていないか確認します。

よくあるエラーメッセージ

実行ポリシーで止まっている場合は、次のようなエラーになります。

execution-policy-error.txt
.\test.ps1 : このシステムではスクリプトの実行が無効になっているため、
ファイル C:\work\test.ps1 を読み込むことができません。
詳細については、「about_Execution_Policies」を参照してください。

CategoryInfo          : セキュリティ エラー: (:) []、PSSecurityException
FullyQualifiedErrorId : UnauthorizedAccess

一方で、次のようなメッセージなら原因が異なります。

  • 用語として認識されません:ファイルパスやカレントディレクトリの指定ミス
  • アクセスが拒否されました:管理者権限やファイル権限の不足
  • 署名されていません:RemoteSignedまたはAllSignedで、インターネット由来の未署名ファイルを実行している
  • この操作は制限されています:企業や学校のグループポリシーで制御されている可能性

まず実行ポリシーを全スコープで確認する

Get-ExecutionPolicyだけだと有効な結果しか見えません。原因を切り分けるには-Listで全スコープを確認します。

check-execution-policy-list.ps1
Get-ExecutionPolicy -List

代表的なスコープは次のとおりです。

  • MachinePolicy:グループポリシーでコンピューター単位に設定。最優先。
  • UserPolicy:グループポリシーでユーザー単位に設定。
  • Process:現在のPowerShellプロセスだけに有効。閉じると消えます。
  • CurrentUser:現在のユーザーだけに有効。管理者権限なしで設定しやすい。
  • LocalMachine:PC全体に有効。通常は管理者権限が必要。

MachinePolicyまたはUserPolicyに値が入っている場合、Set-ExecutionPolicyCurrentUserLocalMachineを変更しても、実際の動作はポリシー側が優先されます。会社PCでは管理者や情シスのルールに従ってください。

一度だけ実行したい場合はProcessスコープにする

検証中のスクリプトを一度だけ実行したいなら、システム全体の設定を変更せず、起動したPowerShellプロセスだけに適用する方法が安全です。

run-once-with-bypass.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\test.ps1"

# PowerShell 7の場合
pwsh.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\test.ps1"
Bypassは一時実行に限定する
Bypassは確認や警告をほぼ出さずに実行する指定です。ダウンロード直後の中身を確認していないスクリプト、送信元が不明なスクリプト、業務端末のルールで禁止されているスクリプトには使わないでください。毎回この指定が必要になるなら、次のCurrentUser設定や署名運用を検討します。

普段使いはCurrentUserにRemoteSignedを設定する

自分で作成したローカルスクリプトを実行したいだけなら、PC全体ではなく現在のユーザーに限定してRemoteSignedを設定します。管理者権限なしで済むことが多く、影響範囲も小さくできます。

set-currentuser-remotesigned.ps1
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
Get-ExecutionPolicy -List

RemoteSignedでは、ローカルで作成したスクリプトは実行できます。一方、インターネットからダウンロードした未署名スクリプトは、ブロック情報が付いていると実行できません。その場合は、次のUnblock-Fileを使います。

PC全体へ変更するLocalMachineは、複数ユーザーへ影響します。共有PCや業務端末では安易に使わず、必要な場合だけ管理者権限で実行します。

set-localmachine-remotesigned.ps1
# 管理者としてPowerShellを開いた場合のみ
Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy RemoteSigned

ダウンロードしたps1はZone.Identifierを確認する

メール、ブラウザ、チャット、ZIPファイルなどから取得したスクリプトには、インターネット由来であることを示すZone.Identifierが付くことがあります。RemoteSignedで止まる場合は、この情報を確認します。

check-zone-identifier.ps1
Get-Item "C:\Scripts\test.ps1" -Stream Zone.Identifier

# 内容を確認する場合
Get-Content "C:\Scripts\test.ps1" -Stream Zone.Identifier

内容を確認して問題ないと判断できるファイルだけ、ブロックを解除します。

unblock-file.ps1
Unblock-File -Path "C:\Scripts\test.ps1"

# フォルダ内のps1をまとめて解除する場合
Get-ChildItem "C:\Scripts" -Filter *.ps1 -Recurse |
  Unblock-File
ZIPから展開したファイルに注意
ZIPファイル自体にブロック情報が付いていると、展開後のファイルにも影響することがあります。可能ならZIPを展開する前に、ZIPファイルを右クリックして「ブロックの解除」を確認するか、Unblock-Fileを実行してから展開します。

パス指定ミスを切り分ける

実行ポリシーではなく、ファイルの呼び出し方が原因で実行できないことも多いです。PowerShellでは、現在のフォルダにあるスクリプトでもscript.ps1だけでは実行できません。明示的に.\を付けます。

run-script-path.ps1
# 現在のフォルダにある場合
.\test.ps1

# スペースを含むパスの場合
& "C:\Work Folder\test script.ps1"

# カレントディレクトリを移動してから実行
Set-Location "C:\Scripts"
.\test.ps1

&は呼び出し演算子です。スペースを含むパスを文字列として渡すだけでは実行されないため、& "C:\path\script.ps1"の形にします。

管理者権限が必要な処理か確認する

実行ポリシーを変更しても、管理者権限が必要な操作は失敗します。たとえばサービス操作、Program Files配下への書き込み、システム設定変更などです。

run-as-admin.ps1
Start-Process powershell.exe -Verb RunAs -ArgumentList @(
  '-NoProfile',
  '-ExecutionPolicy', 'Bypass',
  '-File', 'C:\Scripts\admin-task.ps1'
)

管理者として開くべきか、実行ポリシーを変更すべきかは別問題です。エラーがPSSecurityExceptionなら実行ポリシー、Access is deniedなら権限不足を疑います。

VS Codeでだけ実行できない場合

VS CodeのターミナルやPowerShell拡張では、通常のPowerShellとは異なるプロファイルやPowerShell 7が使われることがあります。まず実行中の環境を確認します。

check-vscode-powershell.ps1
$PSVersionTable.PSVersion
$PSHOME
$PROFILE
Get-ExecutionPolicy -List

プロファイルの読み込みで止まっている場合は、プロファイルファイル自体がRemoteSignedに引っかかっていることがあります。内容を確認したうえで、対象ファイルだけUnblock-Fileします。

unblock-profile.ps1
Test-Path $PROFILE
Get-Item $PROFILE -Stream Zone.Identifier
Unblock-File -Path $PROFILE

タスクスケジューラで実行できない場合

手動では動くのにタスクスケジューラでは動かない場合、実行ポリシー、作業フォルダ、プロファイル読み込み、実行ユーザーの違いを確認します。タスクの操作には次のように設定します。

task-scheduler-action.txt
プログラム:
powershell.exe

引数:
-NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\job.ps1"

開始:
C:\Scripts

スクリプト側ではログを必ず出力し、タスクの実行ユーザーでファイルやネットワーク共有へアクセスできるか確認します。SSHやログ収集の定期実行はPowerShellでSSH経由のログ取得をタスクスケジューラ連携する方法も参考になります。

グループポリシーで変更できない場合

MachinePolicyUserPolicyが設定されている環境では、ユーザー側で実行ポリシーを変更しても上書きされます。次のような状態です。

policy-overridden-example.txt
Scope          ExecutionPolicy
-----          ---------------
MachinePolicy  AllSigned
UserPolicy     Undefined
Process        Undefined
CurrentUser    RemoteSigned
LocalMachine   RemoteSigned

この場合、実際にはMachinePolicyAllSignedが優先されます。業務端末なら、署名済みスクリプトを使う、配布ルールに沿う、管理者へ相談する、のいずれかが必要です。

AllSigned環境では署名状態を確認する

AllSignedでは、ローカルで作成したスクリプトも含め、信頼された発行元による署名が必要です。実行できない原因が署名なのかを確認するには、対象ファイルの署名状態を見ます。

check-authenticode-signature.ps1
Get-AuthenticodeSignature -FilePath "C:\Scripts\test.ps1"

# 署名状態だけを見たい場合
(Get-AuthenticodeSignature -FilePath "C:\Scripts\test.ps1").Status

StatusNotSignedなら未署名、UnknownErrorNotTrustedなら証明書の信頼関係を確認します。業務端末では自己署名証明書で回避するより、組織の配布ルールやコード署名証明書の運用に合わせるのが基本です。

PowerShell 5.1と7で実行コマンドを分ける

Windows PowerShell 5.1はpowershell.exe、PowerShell 7以降はpwsh.exeです。タスクやバッチから呼ぶときは、どちらを使っているかを明示します。

check-powershell-version.ps1
$PSVersionTable
Get-Command powershell.exe
Get-Command pwsh.exe -ErrorAction SilentlyContinue

PowerShellからCSVを扱う処理はImport-CSVとExport-CSVの使い方、SSH接続を行う処理はPowerShellでSSH接続を行う方法もあわせて確認できます。

安全に切り分けるチェックリスト

  • エラーメッセージがPSSecurityExceptionか確認する
  • Get-ExecutionPolicy -Listで全スコープを見る
  • GPOのMachinePolicyUserPolicyがないか確認する
  • 一度だけなら-ExecutionPolicy Bypassをプロセス単位で使う
  • 普段使いならCurrentUserRemoteSignedを設定する
  • ダウンロードしたファイルはZone.Identifierを確認する
  • 信頼できるファイルだけUnblock-Fileする
  • パスにスペースがある場合は& "..."で実行する
  • 管理者権限が必要な処理か確認する
  • VS Codeやタスクスケジューラでは実行ユーザーと起動コマンドを確認する

まとめ

PowerShellの.ps1が実行できないときは、いきなりUnrestrictedへ変更するのではなく、まずGet-ExecutionPolicy -Listでスコープを確認します。一度だけならProcess相当の-ExecutionPolicy Bypass、普段使いならCurrentUserRemoteSignedが扱いやすい選択肢です。

インターネット由来のファイルはZone.IdentifierUnblock-File、権限エラーは管理者実行、パスの問題は.\script.ps1や呼び出し演算子で切り分けます。実行ポリシーは便利な安全機能ですが、スクリプトの内容を確認しなくてよい理由にはなりません。信頼できるファイルだけを、必要な範囲で実行してください。