PowerShell

PSRemotingでリモートPC上のデスクトップアプリを起動する

にはどうすればいいのでしょうか、誰か教えてください。

PowerShellは予め設定をしたうえで、Enter-PSSessionでネットワーク上の別のPCに接続し、各種コマンドを実行することができます。
ファイル操作したりコマンドラインのツールを実行したりといった作業に支障は無いのですが、しかしそこでデスクトップアプリを動作させることができないのです。

例えば「メモ帳」。ローカルPC上でPowerShellからメモ帳を起動するには

PowerShell
notepad

とやるだけです。

これをリモートセッション中にやるとどうなるかというと、確かにnotepadのプロセスは起動して存在するのですが、ウィンドウがどこにもないみたいなんです。
平行世界かなんかで動いてるんですかね?

タスクスケジューラでプロセスを起動する

PowerShellでリモート接続したときのセッションは通常の手順でサインインしたときのデスクトップのセッションとは異なるのでPSRemotingのセッションで起動したアプリがそっちのデスクトップで表示されたりはしないんですとかWindowsのその辺の事情はサッパリわからんのですが、とりあえず一筋縄ではいかんのです。

じゃあどうすんの、いやこっちが聞きたいわってことで冒頭の一文に繋がる訳なのですが…
ひとつの抜け道にタスクスケジューラを利用するという手段があります。
これ経由であれば対象のPCのデスクトップ上でアプリを起動させる事ができるのですね。

ああなんだそういうやつねと十を理解した人はもうお帰り頂いて良いと思います。ありがとうございました。
ですが私が個人的に後でコピペするために、このエントリはもうちっとだけ続くんです。

流れ

タスクスケジューラはタスクのスケジューラです。
ですからタスクのアクションと実行する時間を設定してやる必要があります。ですがタスクに対して任意のタイミングで手動実行させることも可能なので、今回は手動実行を利用します。
時間指定なしでタスクを登録することはできないようなので、ダミーの時間を入れておきましょう。

作成したタスクは自動消滅はしないようなので、不要になったらどこかで削除してください。まあ不要なタスクが残っていた所で何か祟りがあったりもしないでしょうが。

やること

  • タスクをコマンドラインで作成する
  • タスクをコマンドラインで実行させる
  • 使わなくなったタスクはいつの日か削除する

タスクのパラメータ

名前
起動するexe c:\windows\notepad.exe
タスクの名前 メモ帳の起動
繰り返し 1回だけ
時間 0:00

schtasks.exe の場合

接続先が PowerShell 2.0とかだった場合、ScheduledTasksのコマンドレット群が利用できない場合があるので、schtasks を使いましょう。

PowerShell
schtasks /create /tn "メモ帳の起動" /tr "c:\windows\notepad.exe" /sc once /st 00:00
schtasks /run /tn "メモ帳の起動"

削除

PowerShell
schtasks /delete /f /tn "メモ帳の起動"

リモート接続だと削除確認に答えられないようなので、強制オプションを指定しています。

ScheduledTasks モジュールが導入されている場合

ScheduledTasks のコマンドレットが使えるのであればそちらの方がよろしいでしょう。

PowerShell
$action = New-ScheduledTaskAction -Execute 'c:\windows\notepad.exe'
$trigger = New-ScheduledTaskTrigger -Once -At '0:00'
$task = Register-ScheduledTask -TaskName 'メモ帳の起動' -Trigger $trigger -Action $action
Start-ScheduledTask $task.TaskName

削除

PowerShell
Unregister-ScheduledTask 'メモ帳の起動'

無事に動くといいですね。おわり。





没アイデア

これを投稿に使おうと温めていたのですがなんか前後と話が噛み合わなくなったのでやめました。

PowerShell
$action = New-ScheduledTaskAction -Execute 'powershell' -Argument "-WindowStyle Hidden -command `"(New-Object -ComObject sapi.spvoice).Speak('私リカちゃん')`""
$trigger = New-ScheduledTaskTrigger -Once -At '0:00'
$task = Register-ScheduledTask -TaskName 'rika' -Trigger $trigger -Action $action
Start-ScheduledTask $task.TaskName

リモートで他人のPCに入って勝手にしゃべらそうぜみたいな悪行に活用したく。
せっかくのPSRemotingなんで同時にたくさんの端末に喋らせたら楽しいかもしれませんね。