結論
<# :
@echo off & setlocal EnableDelayedExpansion
set BATCH_ARGS=%*
for %%A in (!BATCH_ARGS!) do set "ARG=%%~A" & set "ARG=!ARG:'=''!" & set "PWSH_ARGS=!PWSH_ARGS! "'!ARG!'""
endlocal & Powershell -ExecutionPolicy RemoteSigned -NoProfile -Command "$input|&([ScriptBlock]::Create((gc '%~f0'|Out-String)))" %PWSH_ARGS%
exit/b
: #>
ここ以降にPowerShellコードを書く
上記を作成し、拡張子.bat
で保存して実行。
2024/11/08 追記: 実はExecutionPolicy
を変えなくても、Powershell
コマンドへの外部流し込みの場合は動くようです。また、プロファイル(末尾URL参照)で環境設定などを特に設定していなければ、-NoProfile
も必要無いそうです。それで良ければ以下のように少し短くできる。
<# :
@echo off & setlocal EnableDelayedExpansion
set BATCH_ARGS=%*
for %%A in (!BATCH_ARGS!) do set "ARG=%%~A" & set "ARG=!ARG:'=''!" & set "PWSH_ARGS=!PWSH_ARGS! "'!ARG!'""
endlocal & Powershell -Command "$input|&([ScriptBlock]::Create((gc '%~f0'|Out-String)))" %PWSH_ARGS%
exit/b
: #>
ここ以降にPowerShellコードを書く
説明
PowerShell スクリプトをバッチファイル感覚で作ろうとすると・・・。
デフォルトだと、 PowerShell の ExecutionPolicy がRestricted
になっていて.ps1
スクリプトを実行できない。
Get-ExecutionPolicy
# → Restricted
管理者権限があり、RemoteSigned
以下に設定を落とせば、以後実行出来るようになる。ただし、セキュリティに懸念があるとか、そもそも管理者権限が無い事もある。
Set-ExecutionPolicy RemoteSigned
ExecutionPolicy にはスコープがあり、 Process スコープ(システム全体ではなくそのプロセスのみに有効)であれば管理者権限が無くても変更可能。また、 PowerShell 起動時にそれを指定出来る。
つまり、バッチファイルから ExecutionPolicy が RemoteSigned な PowerShell を起動し、そこにスクリプトを流し込めばいけそう。
その方法として、「バッチファイルとして起動し、自分自身を PowerShell スクリプトとして起動し直す (この時に PowerShell の設定を変えて起動)」という方法がある。
(セキュリティ的にダメな気がするんですが、出来てしまう。)
※ 本スクリプトは、特殊文字非対応だったり、一部のPathが空になるようです。もっと踏み込みたい方は、以下の参考元をお読みください。
別解
どこかで知りましたが、バッチファイルからtype
コマンドからのリダイレクトで流し込んでも動くそうです。
rem `hoge.ps1`を用意した上で、以下を実行
type hoge.ps1 | powershell
ワンラインならこういうのもアリ
echo Get-ExecutionPolicy | powershell
;
(セミコロン)で区切れば、複数コマンドも流し込めます。
echo Get-ExecutionPolicy; dir | powershell
とっっても参考にさせて頂いた記事
マイナー加工してますが、ほぼ、以下の焼き直しというレベルです。
前者のスクリプトに、後者のポリシー変更を組み込んだだけです。