ASAHI Accounting Robot Research Institute ASAHI Accounting Robot Research Institute

「PsExec を使ってリモート接続先のアプリケーションを起動してみる」T2 Labs

※ 今回は実験的な内容です。実際に業務でご利用される場合は、十分に検証してから行ってください。 ※

 

リモートデスクトップ先の操作

Power Automate Desktop を使って、リモートデスクトップ(RDS)を操作する場合、画像認識で操作するケースがほとんどかと思います。
数か月前のアップデートで、デスクトップレコーダーでリモートデスクトップのウィンドウにマウスを持っていくと、自動的に画像認識モードになるようになったため、操作の記録は非常に楽になりましたね。

 

では、リモート先のアプリケーションの起動はどうしていますか?
画面操作と同じように画像認識で起動する、ログイン時に自動起動するようにしておく、アプリケーションを立ち上げたままにしておく、Remote App を設定しておくなどが考えられるでしょうか。
Remote App であれば、PADでウィンドウのUI要素を取得できるため、ローカルで読み込んだデータを、リモート先のアプリに書き込むといった画面の切り替えなども容易に行うことができますね。

 

今回は PsExec という仕組みを使用して「リモート先の任意のアプリケーションを起動する」ということを行ってみたいと思います。
PsExec は、リモート先に対して、ipconfigなどのコマンドを直接送ることができる優れものです。
これが上手く動けば「リモート先のアプリケーション起動」アクションとして、利用できる可能性があります。
PsExec は指定されたポートを開放する必要があるため、ご注意ください。

 

PsExecの準備

PsExec はインストール不要で、ここからダウンロードしたファイルをクライアント(PADがインストールされたPC)にフォルダごとコピーするだけです。
今回は C:\PsTools にコピーした場合の操作を説明します。

 

PsExecを使ったフローの構築

PsExec を実行する場合は「アプリケーションの実行」アクションを使用します。
PsExec でリモート先のプログラムを起動した場合、起動したプログラムを閉じるまで、PsExec は終了しないため、「DOSコマンドの実行」アクションで実行すると、アクションが待機したままになってしまうので注意してください。

 

System.RunApplicationAndWaitToLoad ApplicationPath: $'''c:\\PsTools\\psexec''' CommandLineArguments: $''' \\\\サーバー名 -i セッションID -u ドメイン\\ユーザー名 -p パスワード \"アプリケーションパス\"''' WindowStyle: System.ProcessWindowStyle.Normal Timeout: 0 ProcessId=> AppProcessId WindowHandle=> WindowHandle

 

対象のリモートセッションを操作する為には、セッションIDが必要となります。
単純なリモート接続であれば、セッションIDは「2」を設定すれば、問題ないと思いますが、取得方法は下記を参照してください。
これを使うと、以下のようにアプリケーションを起動することが可能です。

けっこう遅いですね。
ただ、アプリケーションの起動は問題なく行えるようでした。
もしこんな方法もあるよ!という場合は、是非ご連絡ください。

 

今回の動画のコードは下記に保存していますので、宜しければ参考にしてください。(画像もそのままにしています。)

https://asahi-robo.jp/wp/wp-content/uploads/2021/08/PsExec.txt

 

セッションIDの取得方法

セッションIDを取得するためには、リモート接続を行った状態で、リモート先に対して「session query」コマンドを実行します。
PAD から PsExec でコマンドを実行すると、PsExecの結果は取得できますが、実行されたコマンドの結果は取得できないため、一度ファイルに保存する必要があります。
ただし、これにも罠があり、「DOSコマンドの実行」「CMDセッション」「Powershellの実行」では、ヘッダ行しか保存されません。
そこで、バッチファイルを作って下記コマンドを実行する必要があります。(Powershellの外部ライブラリを使えば、より簡単に行えるようです)

 

psexec \\サーバー名 -i -u ドメイン\アカウント名 -p パスワード query session > ログの保存先
例
psexec \\RemoteServer -i -u Domain\administrator -p 1234 query session > C:\ASAHI\log.txt

 

今回のフローでは「テキストの書き込み」アクションと「アプリケーションの実行」アクションで、このバッチファイルを作成、実行しています。

 

次に保存したログからセッション情報を展開します。
ログは以下のように固定長で成形されたデータになっています。

固定長のデータを読み込む場合は、「CSVを読み込ます」アクションを使用することで、DataTable形式で読み込みができます。
しかし、PADの固定長読み取りにはちょっとした問題があり、バイト数ではなく文字数カウントのため、「12345_____(10byte、10文字)」と「あいうえお(10byte、5文字)」では文字の長さが変わってしまう、という問題が発生します。

これだと10文字で区切るとした場合、1行目は正しく区切ることが出来ますが、2行目は「あいうえおXYZ」までが対象となってしまいます。
今回は、日本語が含まれるのはヘッダのみなので、ヘッダを削除することで回避します。(日本語のユーザー名を適用している環境では使用できません)

 

はじめに「ファイルからテキストを読み取ります」アクションを使用して、各行をリストとして取得します。

次に「リストから項目を削除」アクションを使用して、1行目のヘッダ行を削除します。

「テキストをファイルに書き込みます」アクションを使って、ファイルを上書きします。

「CSVファイルを読み取ります」アクションで固定長でテキストファイルを読み込みます。

これでDataTableとしてデータ化できます。

次に対象のセッションID(3列目)を取得します。
「for each」アクションを使用するか、一度Excelに出力し「Excelワークシート内のセルを検索して置換する」アクションを使用して、対象アカウントのセッションIDを取得します。

これでセッションIDが取得できます。
最初に行ったコマンドと組み合わせることで、対象のユーザーセッションに対して処理が出来るようになります。

 

セッションIDを取得するコードは以下を参照してください。

 

SET Host TO $'''リモート先'''
SET Domain TO $'''ドメイン'''
SET User TO $'''ユーザー名'''
SET Password TO $'''パスワード'''
SET LogFile TO $'''C:\\ASAHI\\log.txt'''
File.WriteText File: $'''C:\\ASAHI\\querysession.bat''' TextToWrite: $'''C:\\PsTools\\psexec \\\\%Host% -i -u %Domain%\\%User% -p %Password% query session > %LogFile%''' AppendNewLine: True IfFileExists: File.IfFileExists.Overwrite Encoding: File.FileEncoding.DefaultEncoding
System.RunApplicationAndWaitToComplete ApplicationPath: $'''C:\\ASAHI\\querysession.bat''' WindowStyle: System.ProcessWindowStyle.Normal Timeout: 0 ProcessId=> AppProcessId ExitCode=> AppExitCode
File.ReadTextAsList File: LogFile Encoding: File.TextFileEncoding.DefaultEncoding Contents=> FileContents
Variables.RemoveItemFromListByIndex ItemIndex: 0 List: FileContents NewList=> FileContents
File.WriteText File: LogFile TextToWrite: FileContents AppendNewLine: False IfFileExists: File.IfFileExists.Overwrite Encoding: File.FileEncoding.UTF8
File.ReadCSVWithFixedColumnWidths CSVFile: LogFile Encoding: File.CSVEncoding.UTF8 TrimFields: True FirstLineContainsColumnNames: False FixedColumnWidths: $'''19,22,7,8,12,8''' CSVTable=> CSVTable
LOOP FOREACH CurrentItem IN CSVTable
    IF CurrentItem[1] = User THEN
        SET SessionId TO CurrentItem[2]
        EXIT LOOP
    END
END




 
ロボ研では、Power Automate を利用したフローの導入・運用・開発支援、
Power AppsなどのPower Platformを活用した効率化支援、
リスキリングに関するご支援を行っております。

お客様の業務効率化・生産性向上に向け、最大限のご支援をさせていただきます。
ぜひご相談ください。

◆ Power Automate / Power Automate for desktop 向けサポートサイト ◆
Power Automate サポート ★一部無償でご覧いただけます★

◆ セミナー定期開催中◆
事務スタッフが始める!自動化・デジタル化Webセミナー(オンライン/無料)
リスキリング経験者&DXアドバイザーによる”現場のリスキリングセミナー

◆ 過去の記事 ◆
ブログ記事一覧

◆ 書籍 ◆
Power Automate for desktop(Power Automate Desktop)や RPA に関する書籍を出版、監修しております。