ijsのガラクタ倉庫

ijs01140の作業メモ等

PowerShellでの画面ロックで苦労した話

それは、スタートアップに登録したスクリプトから画面ロックをしようとした際の出来事だった・・・

事件発生

ijsはバッチファイルからPowerShellスクリプトへの全面移行を進めており、今回もその一環として、(自動サインインでスタートアップスクリプトを起動した後に)画面ロックをする部分を作っていた。それが以下のコードである。

rundll32.exe user32.dll,LockWorkStation

複数サイト漁ったから間違いないはずだ。実は、バッチファイルのときから一切変わっていないこれをスタートアップに登録したスクリプトに入れておけば、自動で画面ロックしてくれるはずだ。
とりあえず再起動してみよう。

・・・あれ、セキュリティポリシーの変更を要求されて実行が止まってる。いや、でも、ijsはすでにセキュリティポリシーをRemoteSignedに変更していたはずだが・・・(もし変更していないと、PostRecEnd.ps1は実行されないはずだしう~ん)

必死で回避方法を探る

PowerShellがダメなら、従来どおりcmd.exe使うしかないだろうと、

解決策1
Start-Process 'cmd' -ArgumentList '/c rundll32.exe user32.dll,LockWorkStation'

cmd.exeで/cオプションを使うと、それ以降に書いたコマンドを実行させることができる。これで、バッチファイルからrundll32.exe user32.dll,LockWorkStationしていたときと同じ挙動になるはず 。

・・・

・・・ならなかった。セキュリティポリシーの変更を要求されてまたもや止まった。またさっきと同じパターンだよ、もう! !
これはもう、画面ロックのみのバッチファイル作って実行させるしかなさそうだ(白目)

解決策2
Write-Output 'rundll32.exe user32.dll,LockWorkStation' | Out-File 'D\temp\locktmp.bat'
Start-Process 'D\temp\locktmp.bat' -Wait
Remove-Item 'D\temp\locktmp.bat'

具体的にこれが何をしているのかというと、

  1. 画面ロック用のコマンドをバッチファイルとして保存
  2. さきほど作成したバッチファイルを別プロセスで起動して、終了まで待機
  3. さきほど作成したバッチファイルはもう洋梨用なしなので粛清

という流れ。・・・って、あれ?1と3無駄じゃね?
じゃあもうそれ用のバッチファイル作って、画面ロックしたいときに都度都度実行すればよくね?

・・・ということで、結局こうなった

解決策3
Start-Process 'C:\tools\script\PCLock.bat'

ちなみに-Waitオプションを外してるのは、バッチファイルの削除をしなくなったので実行終了まで待機する必要がなくなったから。
もちろん、PCLock.batの中身はrundll32.exe user32.dll,LockWorkStationだ。

これで、PowerShellから画面ロックできない問題は回避(←ココ重要)された。解決ではない、あくまでも回避である。

結論

セキュリティを厳しくしすぎると抜け道(回避策)使われる好例ですな(謎理論) 皆さんも気をつけましょう(?)