【RPA例題】WinActorロボットをAutomation Anywhere A2019 Control Roomを使って管理する

# 概要
WinActorは現場が最も気軽に導入できるRPAのひとつです。ただし、管理機能はなく (そのため[RDA, Robotic Desktop Automation](https://ja.wikipedia.org/wiki/RDA)ともいわれています)、組織から見るとどこでどう使われているのかわからず、管理ができない、成果がわかりにくい、との声もよく聞きます。管理機能を持った純正ツールのWinDirectorを入れる手もありますが、追加で年間約300万円 (サーバー費用別)かかってしまうため、ハードルがかなり高くあまり普及しているとは言えません( ;∀;)

しかし、サーバー機能の大半を実現できる別の方法があります。安価な別のサーバー型RPAを活用してWinActorのロボットを管理する方法です。たとえば、**Automation Anywhere (AA) Enterprise A2019**を使ってWinActorを管理すると、主な管理機能を実現するだけでなくWinActorにない機能も手に入ってしまいます！AA A2019はクラウド版とオンプレミス版があり、クラウド版を使うと年間約100万円でサーバー不要で実現可能です(^^♪

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/49385012-c465-09d2-73e4-78f90276c0bd.png)

この記事ではどのようにこれを実現するのか見てみたいと思います(^_-)-☆

# サーバー機能をAAで代用してみる

どのような機能が実現できるかというと、以下の通りです。

**WinDirectorの主な機能⇒これをAAで実現しちゃいましょう！**

* ユーザー管理
* ロボットの一覧の管理
* ジョブの一覧の管理、スケジューリング
* ロボット実行状態管理
* 端末の一覧の管理

これだけでなく、WinActorにない以下の機能もセットでついてきます。

**AAの機能で追加で使える機能**

* ログイン情報集中管理
* ログの管理と閲覧
* ROI算出/高度な可視化、分析
* ロボットの組織内共有
* ロボットのバージョン管理
* トリガー実行
* 自動ログイン
* 無期限繰り返しジョブ
* WinActorで操作できないオブジェクト、アプリケーションのAAロボットでの操作


# 実装
どこまで管理機能を要求するかによって、いろいろな実装のしかたがありますが、ひとつの例としてやってみたいと思います(^_-)-☆

## #1. AA Bot Runnerが同じマシンのWinActorを管理する場合

WinActorがインストールされているPCにもれなくAA Bot Runnerを入れられるのであれば、この#1の方法のみでAAからWinActorの管理が可能です。ただし、WinActorのロボットの台数によっては、AA Bot Runner (Attended or Unattended)を買い足す必要があるので、追加のライセンス費用がかかってくる場合があります。

ひとつ目のやり方では、WinActorを実行する各PCで以下のような動作をするように実装します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/e59135e7-cea6-95ce-537f-abc4da37c96e.png)


### ローカルPCのWinActorの起動と監視
AAからWinActorを起動するにはいくつか方法がありますが、**「アプリケーション: プログラム/ファイルを開く」アクション**でWinActor.exeを起動するのが簡単です。ただし、こちらは非同期処理 (プログラムを呼び出した後、次のアクションに進んでしまう)のため、WinActor終了後のログ処理は別途行う必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/e7d7ec51-8a44-2570-ee8e-dc691c7aa445.png)

>WinActorの起動オプション:

>* -f: シナリオファイルを開く
>* -r: -fで開いたシナリオファイルを実行
>* -e: シナリオ実行後WinActorを終了する

WinActor.exeが終了するまで待つには、直後に**「ループ」アクション**を入れて(中は空でOK)、WinActor.exeが「アプリケーションは実行中です」の間、待つようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/d7325326-17c9-d2e0-85a4-f7a9ceb9b91b.png)


### ローカルPCのログ出力を取得する
WinActorでは、右下の**「ログ出力」ウィンドウ**に表示されるログをファイルに出力するオプションがあるので、これを使ってWinActorの実行状況をモニターしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/2840be16-f91c-7ad9-e5e0-707c15edcbb6.png)

WinActorのメインウィンドウのメニュー「設定」-「オプション」をクリックして、表示されるダイアログボックスの「実行」タブの下の方に注目しましょう(^^)/
**「実行ログを常に出力する」**チェックボックスをONにします。その下に出力先のファイルを記載します。これは横の`…`ボタンをクリックしてファイルを開くダイアログボックスで指定しましょう。「CSVファイルエンコーディング」は「MS932」(つまりANSI出力)にしておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/24d401b0-6b9b-16e3-c494-02568d278eaf.png)
これで、WinActorのシナリオを実行すると、ログが指定された先に出力されます。

```:正常終了
2020-03-22 21:14:57  【実行開始】シナリオ「test.ums6」の実行を開始しました。
2020-03-22 21:14:57  【アクション】「待機ボックス」を実行。ノードID：4
2020-03-22 21:14:59  【実行終了】シナリオ「test.ums6」の実行を終了しました。経過時間：00:00:02.033
```

最後の行に「【実行終了】」の文字がある場合は、正常終了です。正常終了なら「test.ums6 正常終了」そうでない場合は「test.usm6 エラー」という値を文字列型変数`$Result$`に代入します。

### WinActor実行結果の見える化
**「Analyze」パッケージ**を使うことで、Bot Insightを使った見える化がすぐにできます。フローの最初に「Analyze:Open」アクション、最後に「Analyze:Close」アクションを挿入します。Bot Insightに出力したい変数について、「Analyze:Close」アクションの詳細でチェックをONにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/acfcfd5d-339f-c761-13c4-dd7802516fee.png)

これらを踏まえて、WinActorで指定したシナリオを実行後、待機してログファイル解析結果をBot Insightに出力するフローを作成してみましょう。

作成結果はこんなかんじです(^_-)-☆
これでローカルPCのWinActorを起動、監視できます。

Bot: "WinActor"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/85e3c4df-6cb3-b67e-dd9f-237577692276.png)

Bot Insightの出力結果も見てみましょう。ダッシュボードからBot Insightの画面に移ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/09852b81-af1f-d7e3-9b61-8c8ba8356a4f.png)

My Dashboardで「Business」タブに移動すると、いまの「WinActor」についてのダッシュボードができています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/038a722b-b6a1-4081-971c-220c307fb640.png)

すると、先ほど実行して出力した結果が表示されます。(実行に成功したら`$Result$`に"test.ums6 - Success"と代入し、これをBot Insightに出力することになっていました)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/542255e2-1f20-818a-35e7-900b9a23c643.png)

「プロフィール」を見ると、より細かい情報も記録されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/c1f1e5c5-dc70-1dba-8b16-1698bf110cad.png)

ちなみに、このダッシュボードの情報は、Bot「WinActor」を再度編集するとクリアされて消えてしまいます。同じBotの状態で繰り返し実行していると、数がたまってきます。

## #2. AA Bot Runnerが他のマシンのWinActorを管理する場合

もうひとつのやり方は、ひとつのAA Bot RunnerですべてのWinActorロボットを管理する場合です。リモートPCにリモートコントロールに必要な設定を行う必要があります。加えて、WinActorが別のリモートPC上にあるので、**「WinActorのリモート実行」**と**「リモートPCからのログの回収」**を工夫する必要があります。これらの工夫をすることで、AA Bot Runnerのライセンスを節約することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/afe590a3-3362-4df9-8a6d-dd60674c69f8.png)


### リモートPCのWinActorを起動、監視する
WinActorのリモート実行は、リモートからのアプリケーション起動と、起動後のプロセスの終了監視の2つからなります。リモート実行は使い方によってはハッカーの攻撃にも使えるので、最近のOSではセキュリティも厳しくなっており、工夫が必要です。

記事「[別端末(Windows)のプログラムを標準機能でリモート起動する方法まとめ](https://qiita.com/0829/items/5518256b348521ac358c)」も参考にさせていただきながら試しましたが、この記事の中である程度簡単に、かつインタラクティブなセッションを起動できる方法は**「schtasks (タスクスケジューラ)」**を使う方法に限られます。schtasksを使って過去の日付でタスクを登録、その後登録したタスクを実行します。

>このコマンドの実行に関連する「スケジュールされたリモートタスク管理」という項目がWindows Defenderファイアウォールの設定に存在しますが、これはOFFでもリモートから動作しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/e1ad9903-6bf5-a94c-b482-96474d13291a.png)

また、タスク起動後は非同期にボットのアクションは進んでいくので、リモートプロセスを監視して終了するまでウェイトをかけたい場合は、後述の「野良ボットの一覧を作成するには」の手法をサブタスクボットにしておき、ループ内で呼び出して監視する方法もあります。

### リモートのログ出力を取得する
ログを出力する場所を工夫します。つまり、管理用PCからも見えるネットワークドライブ上に出力するようにすれば同じようにログを読み込めます。

### WinActor実行結果の見える化
「#1」と同様に、「Analyze」パッケージを使うことで、Bot Insightを使った見える化がすぐにできます。

これらを踏まえて、WinActorで指定したシナリオをリモートから実行後、プロセスが完了するまで待機してログファイル解析結果をBot Insightに出力するフローを作成してみましょう。

Bot: "WinActor-Remote"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/cae7529b-e431-5a1b-029f-424371bb5e8c.png)

>**補足:**
>`$WinActorRunning$` - ディクショナリ/数字型変数。WatchNoraBotの返り値が入ります。`$WinActorRunning{Found}$`が1ならWinActor.exeが実行中、0なら実行なし (後述の「野良ボットの一覧を作成するには」参照)　`$WinActorRunning{Found}.Number:toString$`という形でインライン形式で数字型を文字列型に変換可能。

>2行目: `cmd.exe /c schtasks /Create /S $Machine$ /TN winactorsample /SC ONCE /SD 1900/01/01 /ST 00:00 /F /TR "C:\program files (x86)\WinActor\WinActor.exe -f 'c:\users\user\Documents\WinActor\test.ums6' -r -e"`というコマンドを実行するように、プログラム/ファイルの場所はcmd.exe、パラメータには/c ...以下の文字列を入れる。
>(`schtasks.exe ...`というコマンドで実行しようとすると、なぜかうまくいきませんでした( ;∀;))

>5行目: `cmd.exe /c schtasks /Run /S $Machine$ /I /TN winactorsample"`というコマンドを実行するように、プログラム/ファイルの場所はcmd.exe、パラメータには/c ...以下の文字列を入れる。
>(`schtasks.exe ...`というコマンドで実行しようとすると、なぜかうまくいきませんでした( ;∀;))

>3/6行目: ウィンドウ `$window-1$`が開くのを待つ
>`$window-1$`はウィンドウタイトル "*"、実行可能ファイル "C:\Windows\System32\cmd.exe"を指定

>4/7行目: ウィンドウ `$window-1$`が閉じるのを待つ

実行してみると、コマンドプロンプトの画面が何回も立ち上がりますが、リモートPCのWinActorが実行されている間、待機して、実行終了したらログを読みに行き、結果をBot Insightに出力していることがわかります(^^♪



### 野良ボットの一覧を作成するには
ところで、WinActorは後から管理機能を導入するケースが多いですが、単独でも動作するフル版ライセンスや実行版ライセンスを利用している限りは、完全に野良ボットを防ぐのはなかなか難しいです。しかし、管理権限が届く範囲のPCで実行されているプロセス情報を監視することで、野良ボットをかなり防ぐことは可能です。

(必要な事前設定の詳細は「[メモ: 最新のWindows10環境でリモートPC管理！ (ワークグループ環境)](https://qiita.com/Okura_/items/496cdd1b8a022c99d3f3)」等を見てください)

リモートPC「Machine01」のプロセス一覧を取得するコマンド:

```:DOS
C:\>tasklist /s Machine01

イメージ名                     PID セッション名     セッション# メモリ使用量
========================= ======== ================ =========== ============
System Idle Process              0                            0          8 K
System                           4                            0        136 K
Registry                        96                            0     26,304 K

...(中略)...

WinActor.exe                  4868                            2      7,508 K

...(中略)...

WMIADAP.exe                   9008                            0      7,888 K
WmiPrvSE.exe                  5852                            0      8,392 K
```
リストの中にWinActor.exeというプロセスが出てくる場合、WinActorが実行されています。意図しないマシンで実行されていれば、野良ボットということになります。

これをAA A2019で作ってみます。監視するマシンの一覧はデータファイル (CSV) に入れておくものとします。また、分析結果はBot Insightに出力するようにしておくと、簡単に分析を見える化できます。

Bot: "WatchNoraBot"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/9a4f3ded-f783-8155-29e6-4096b1a38d42.png)
>**補足:**

>* 入力: `$Machine$` - 文字列変数
>* 出力: `$Found$` - 数字変数 - 1ならWinActor.exeが`$Machine$`にて実行中、0なら実行なし。

>`$FilePath$` - Tasklist.exeの出力をリダイレクトで保存する一時ファイル (ex. c:\temp\tasklist.txt)

>1行目: `cmd.exe /c tasklist /s $Machine$  > $FilePath$`というコマンドを実行するように、プログラム/ファイルの場所はcmd.exe、パラメータには/c ...以下の文字列を入れる。
>(`tasklist.exe /s $Machine$  > $FilePath$`というコマンドで実行しようとすると、なぜかうまくいきませんでした( ;∀;))

>2行目: ウィンドウ `$window-1$`が開くのを待つ
>`$window-1$`はウィンドウタイトル "*"、実行可能ファイル "C:\Windows\System32\cmd.exe"を指定

>3行目: ウィンドウ `$window-1$`が閉じるのを待つ

>7行目: ループの現在位置を代入する変数 = `$Row$` 
>(値の範囲は0から`$FileTable.DataTable:rowCount$-1`まで)

>8行目: tasklist.txtをデータテーブルに読み込み (列0にのみ値が入る)、WinActor.exeというテキストを大文字小文字の区別なしで部分文字列検索し、どこかで見つかれば`$Found$=1`を代入。見つからなければ`$Found$=0`を代入。

# 管理を実行している動画
こちらでご覧いただけます。
![WinActor3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490819/6ac4d140-f828-32ea-34a0-f4119453a644.gif)


より高解像度なYouTubeによる動画は以下を見てください(^^)/
https://www.youtube.com/watch?v=-6v6b_YKdRQ

# まとめ
以上で見てきたように、Automation AnywhereでWinActorを管理していくというやり方は、わりと現実味があり、かつ低予算で比較的現場にも簡単に実行できるのではないでしょうか。

実装方法は今回紹介した方法だけではないので、他にもいろいろ工夫してみて、もっといい方法があれば教えてください(^^)/