Lazy Diary @ Hatena Blog

PowerShell / Java / miscellaneous things about software development, Tips & Gochas. CC BY-SA 4.0/Apache License 2.0

タスク スケジューラからPowerShellを起動するとき-Commandオプションのパラメタをシングルクォートで囲んではいけない

前提

タスク スケジューラで作ったタスクで、操作に「プログラムの開始」でpowershell.exeを指定し、「引数の追加」で-Commandオプションと実行したいスクリプトを指定すれば、タスク スクリプトから任意のコマンドを実行できる。

参考: https://www.netspi.com/blog/technical/network-penetration-testing/15-ways-to-bypass-the-powershell-execution-policy/

問題

PowerShell ISE上からpowershell.exeを実行した場合は問題なく動く内容が、タスク スケジューラからだと正しく動作しない。 たとえばpowershell.exe -Command " Start-Sleep -Seconds 5"をタスク スケジューラから起動した場合、PowerShellのウィンドウが一瞬だけ表示されてすぐに消えてしまう。

原因

PowerShell上から起動した場合と、それ以外のシェル(cmd.exeとか、エクススプローラのアドレスバーとか)でシングルクォートの解釈が異なるため。

たとえばStart-Sleep -Seconds 5だったら結果はこうなる。

# コマンド PowerShellから実行 cmd.exeから実行
1 powershell.exe -Command 'Start-Sleep -Seconds 5' 5秒間ウィンドウが表示される 「Start-Sleep -Seconds 5」がエコーされる
2 powershell.exe -Command "Start-Sleep -Seconds 5" 5秒間ウィンドウが表示される 5秒間ウィンドウが表示される

対策

-Commandオプションのパラメタに渡す文字列はダブルクォートで囲む。それに合わせて、渡すスクリプト内でダブルクォートを使っていた場合はシングルクォートで置き換えるよう処理を修正する。