OpenSSH経由のリモートログインでもGUIアプリケーションを起動する仕組みを作る

本連載でこれまでに説明したように、OpenSSH経由でWindowsにリモートログインした場合、そこからはGUIアプリケーションを起動できない。しかし、Windows上の仮想環境やWSL2で動作しているUbuntuから、Windows側のGUIアプリケーションを起動したいケースはある。やはり、OpenSSH経由でリモートログインしている状態でもGUIアプリケーションを起動したいのだ。

こうしたことから、本連載ではGUIアプリケーションが起動できる状態のサーバを起動しておいて、そのサーバにアプリケーションの実行を依頼するかたちでこれを実現する方法を紹介した。作成したのは、次のPowerShellスクリプト「wincmdserver.ps1」だ。

#!/usr/bin/env pwsh

#========================================================================
# 特定のファイルに書き込まれたコマンドを実行する簡易サーバ
#========================================================================

#========================================================================
# コマンドが書き込まれるファイル
#========================================================================
$commandFilePath = "${HOME}/.wincmdserver_cmd"

#========================================================================
# ファイルをチェックするインターバル時間[秒]
#========================================================================
$fileCheckInterval = 1.0

#========================================================================
# コマンドが書き込まれるファイルを初期化
#========================================================================
Write-Output $null > $commandFilePath

#========================================================================
# コマンドが書き込まれるファイルを監視して、コマンドが書き込まれた場合には
# コマンドを実行してファイルをクリアする
#========================================================================
while ($true) {
    # コマンドファイルが存在し、かつ、中身があるときに中身を実行する
    if (Test-Path "$commandFilePath") {

        if (0 -lt (Get-ChildItem "$commandFilePath").Length) {

            # ファイルに書き込まれたコマンドを実行
            Invoke-Expression (cat "$commandFilePath") 

            # ログ出力
            $timestamp = Get-Date -format "yyyy/MM/dd HH:mm:ss"
            $timestamp + " - " + (cat "$commandFilePath")

            # ファイルの中身をクリア
            Clear-Content "$commandFilePath"
        }
    }

    # 次のチェックまで指定秒間待機
    Start-Sleep $fileCheckInterval
}

このPowerShellスクリプトを実行しておけば、${HOME}/.wincmdserver_cmdに書き込まれた文字列がコマンドとして実行されるようになる。要するに特定のファイルにGUIアプリケーションを起動するコマンドを書き込めば、それが実行されるという仕組みである。

タスクスケジューラに登録する

「この機能は常に動作していてほしい」「使うときに都度起動するのは面倒だ」「常に背後で動いていてほしい」――これを実現するものとして、前回「タスクスケジューラ」を取り上げた。説明の中で、簡単なPowerShellスクリプトをタスクスケジューラに登録し、Windowsにログオンしたら自動的に実行されるところまでを確認した。この機能をwincmdserver.ps1に適用してみよう。

タスクスケジューラを起動して、新しいタスクを作成する。重要な部分のスクリーンショットだけ、以下に掲載しておく。

  • タスクスケジューラの作成:名前をつける

    タスクスケジューラの作成:名前を付ける

  • トリガーとして「任意のユーザーのログオン時」を選択

    トリガーとして「任意のユーザーのログオン時」を選択

  • 用意したwincmdserver.ps1を登録

    用意したwincmdserver.ps1を登録

操作(アクション)としてここでは次の内容を登録している。「引数の追加」や「開始」に登録するパスについては、状況に応じて書き換えていただきたい。

項目 内容
操作 プログラムの開始
プログラム/スクリプト "C:\Program Files\PowerShell\7\pwsh.exe"
引数の追加 Command "C:\Users\daichi\wincmdserver.ps1"
開始 C:\Users\daichi
  • 操作(アクション)の登録内容

    操作(アクション)の登録内容

  • タスク:条件 - デフォルトのまま

    タスク:条件 - デフォルトのまま

  • タスク:設定 - デフォルトのまま

    タスク:設定 - デフォルトのまま

  • 作成したタスクを確認

    作成したタスクを確認

この状態でシステムを再起動、または、いったんログアウトしてからログオンする。すると次のように、登録したPowerShellスクリプトが起動する。以前はこのターミナルウインドウを表示しないオプションが機能していたのだが、現在は使用できなくなっている。とりあえず動作はするので、今はこのままにしておこう。邪魔になったらウインドウを最小化すればよい。

  • ログオン時に登録したPowerShellスクリプトが起動することを確認

    ログオン時に登録したPowerShellスクリプトが起動することを確認

動作確認

では、動作を確認してみよう。WSL2で動作しているLinuxでもよいし、ほかのホストからでもよいので、WindowsへOpenSSH経由でリモートログインして、${HOME}/.wincmdserver_cmdファイルへコマンドを書き込む。次のようなイメージだ。

  • OpenSSH経由でリモートログインして指定されたファイルへコマンドを書き込む

    OpenSSH経由でリモートログインして指定されたファイルへコマンドを書き込む

ほかのホストから実行するコマンドの例

ssh ホスト 'echo "コマンド" > $HOME/.wincmdserver_cmd'

Windows側では次のように${HOME}/.wincmdserver_cmdファイルへ書き込んだコマンドが実行され、アプリケーションが起動する。

  • ${HOME}/.wincmdserver_cmdファイル書き込んだコマンドが実行されていることを確認

    ${HOME}/.wincmdserver_cmdファイル書き込んだコマンドが実行されていることを確認

このように、Windowsにログオンした状態でOpenSSH経由でのGUIアプリケーションが起動できる状態になっていることを確認できる。

これまで示してきたように、リモートログインからGUIアプリケーションを起動するために特別なことはしていない。必要なPowerShellスクリプトを作成し、それをタスクスケジューラに登録してログオン時に自動的に起動するようにしただけだ。それでも、これだけ実用的な機能を実現できる。ユーザーによっては、さまざまな操作を自動化できるとても重要な機能となるだろう。あるとないとでは、大きな違いになるはずだ。