【UiPath】Attended Robot で起動できるロボットをユーザーごとに分ける

# はじめに
UiPathを小規模に導入する場合、1台のPCに Attended Robot をインストールし、複数人で共有して実行するケースがあると思われる。その場合、みんな同じロボットを起動できるのでは、管理体制として問題がある。例えば、経理部の業務を行うロボットを他部門の人が起動できては困ってしまう。
しかし、UiPath Robot は基本的にPC1つで1つの設定値を持っているので、使うPCが同じであれば起動できるロボットの顔ぶれが同一になる。

本記事では、部門または担当者ごとにロボットを分けるため、自分が作成した環境の例を記載する。

# 概要

* RPA実行用のPCを用意する。
*	PCにログオンするWindowsのユーザーを管理単位ごとに分ける。
    *	(部門ごとにロボットを分けたいなら、部門用アカウントを作る)
*	UiPath Robot は、既定ではサービスとして起動して常駐するが、これをログオンユーザーごとに起動するようにする。
*	設定ファイルを編集し、パッケージフォルダをユーザーごとに異なる場所を設定する。
    *	ここでは`%LocalAppData%`(ユーザー固有のアプリケーションデータを保存する場所)をパッケージフォルダとしている。

# 前提条件

* UiPathのバージョン：v19.4.3
* ロボットのソースはgitで管理している。
* RPA用PCにgitをインストールしている。


# 詳しい手順

## Robotをユーザー毎に起動させる
まず、Robotインストール時にオプションを選択して、サービスとして起動しないようにする。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/7cc68b46-bbad-33f8-9253-edb42c6175b0.png)

既にサービスとして起動するようインストールした場合は、サービスを自動的に起動しないように設定する。

インストール後、ユーザーがログオンした時に UiPath Robot を起動するようにスタートアップの設定をする。
Windowsにはスタートアップ用のフォルダがあるので、そこにアプリケーションへのショートカットを貼りつければログオン時にそのアプリケーションが起動する。

エクスプローラを開き、アドレス欄に「`shell:Common Startup`」と入力してエンターを押す(すべてのユーザーのスタートアップが開く)。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/564d2922-07c0-eab5-bb35-e16ad4601d59.png)

開いたフォルダへ、UiPath Robotへのショートカットを作成する。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/00cb24bf-6c4d-f3e3-5e4e-f1f2fc706d98.png)

コピー元となる UiPath Robot のショートカットは、スタートメニューから取得するのが間違いがないと思われる。
スタートメニューのフォルダを表示するには、スタートメニュー上の「UiPath Robot」で右クリック→その他→ファイルの場所を開く を選択する。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/98709df6-b11a-b984-de3c-0cc4976cfca3.png)

するとスタートメニューのフォルダが開くので、そこにある「UiPath Robot」のショートカットをコピーすればよい。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/dc8f4585-8df2-e32c-849d-ec642636b1f7.png)

## UiPath.Settingsの編集
スタートアップの設定後、ロボット用に用意したユーザーアカウントでPCにログオンすると、UiPath Robot が起動している。
一度でもUiPath Robotが起動すると、以下のフォルダにUiPathの設定ファイル等ができている。

場所：`%LocalAppData%\UiPath`
(このパスをそのままエクスプローラのアドレス欄に入力して、エンターキーを押せば良い)

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/90c5719b-d91d-fb1c-a0bb-59f39e9cf7be.png)

`UiPath.settings`を開き、`NuGetServerUrl`の値を`%LocalAppData%\\UiPath\\Packages`へ変更する。

```
{
  "NuGetApiKey": "",
  "NuGetServerUrl": "%LocalAppData%\\UiPath\\Packages",
  "ActivitiesFeed": "",
  "UiPathServerUrl": "",
  "TracingLevel": "Information",
  "LowLevelTracing": false,
  "SecureLicenseKey": "",
  "LoginToConsole": true,
  "ResolutionWidth": 0,
  "ResolutionHeight": 0,
  "ResolutionDepth": 0,
  "FontSmoothing": false,
  "ConnectionString": ""
}
```

これで、UiPath Robot はログオンユーザーごとに分かれたフォルダからロボットを探すようになる。

# パッケージの配置
次に、各ユーザーごとの`%LocalAppData%`にどうやってロボットを配置するかについて例を記載する。

私が選択した方法は以下の通りとなっている：

1. RPA用PCに管理者アカウントでログイン。
1. Gitでソース管理しているロボットのソースをプル。
1. CLIでロボットのパッケージを作成。
1. ロボットを使用できるユーザーの`%LocalAppData%\UiPath\Packages`にパッケージを置く。
1. リリースを実施した目印として、現在のリビジョンにタグを付ける。

一連の作業は、スクリプトで自動化しておくと便利。下記にPowerShellで自動化したサンプルを記載するが、これこそRPAで自動化するのも良いと思う。

下記サンプルでは、ロボットを実行できる単位を部門で分けている。

```powershell
# UiRobot.exeがあるフォルダ
$UIPATH_DIR = "${env:ProgramFiles(x86)}\UiPath\Studio"

# UiPathのリポジトリ群があるフォルダ
# (このフォルダ直下に各部門のリポジトリがあること)
$REPOS_DIR = "$env:USERPROFILE\Documents\UiPath"

# ログファイル
$LOG_FILE = Get-Location
$LOG_OUT_FILE = "${LOG_FILE}\log_out.txt"
$LOG_ERR_FILE = "${LOG_FILE}\log_err.txt"

# パッケージ化対象の情報を入力させる
$BUMON_CD = Read-Host "部門コード"
$PROJECT_NAME = Read-Host "プロジェクト名"

$REPOS_NAME = "RPA_$BUMON_CD"

$REPOS_URL = "https://reposerver/${REPOS_NAME}.git"

<#
  主処理
#>
function main() {
    
    # Gitからソースをpull
    $rc = GitPull

    if (-not $rc) {
        return
    }

    # パッケージ作成
    $rc = CreatePackage

    if (-not $rc) {
        return
    }
    
    # パッケージバージョンが上がるので、それをコミット＆プッシュ
    $rc = GitCommit
}

<#
  ロボットのソースをpull
#>
function GitPull() {
    
    $reposDir = "$REPOS_DIR\$REPOS_NAME"

    if ((Test-Path $reposDir)) {
        # pull
        Set-Location -Path $reposDir
    
        $arglist = @("pull", "--progress", "-v", "--no-rebase", "origin")
        $rc = Start-Process git.exe -PassThru -ArgumentList $arglist -Wait -RedirectStandardOutput $LOG_OUT_FILE -RedirectStandardError $LOG_ERR_FILE

        if ($rc.ExitCode -ne 0) {
            Write-Output "pull失敗"
            return $false
        }

    } else {
        # clone

        $arglist = @("clone", "--progress", "-v", $REPOS_URL, $reposDir)
        $rc = Start-Process git.exe -PassThru -ArgumentList $arglist -Wait -RedirectStandardOutput $LOG_OUT_FILE -RedirectStandardError $LOG_ERR_FILE

        if ($rc.ExitCode -ne 0) {
            Write-Output "clone失敗"
            return $false
        }

    }

    return $true
}

<#
  パッケージ作成
#>
function CreatePackage() {
    # 対象プロジェクト
    $jsonPath = "$REPOS_DIR\$REPOS_NAME\$PROJECT_NAME\project.json"
    # パッケージ作成場所
    $outputDir = "C:\Users\RPA_${BUMON_CD}\AppData\Local\UiPath\Packages"

    # パッケージ作成
    $arglist = @("-pack", $jsonPath, "-output", $outputDir)
    $rc = Start-Process "${UIPATH_DIR}\UiRobot.exe" -PassThru -ArgumentList $arglist -Wait -RedirectStandardOutput $LOG_OUT_FILE -RedirectStandardError $LOG_ERR_FILE

    if ($rc.ExitCode -ne 0) {
        Write-Output "パッケージ作成失敗"
        return $false
    }

    return $true
}

<#
  Gitコミット＆タグ作成＆プッシュ
#>
function GitCommit() {
    $reposDir = "$REPOS_DIR\$REPOS_NAME"
    $currentYmd = (Get-Date -Format "yyyyMMdd_HHmm")

    Set-Location -Path $reposDir

    $arglist = @("commit", "-a", "-m", "パッケージ化によるコミット")
    $rc = Start-Process git.exe -PassThru -ArgumentList $arglist -Wait -RedirectStandardOutput $LOG_OUT_FILE -RedirectStandardError $LOG_ERR_FILE

    if ($rc.ExitCode -ne 0) {
        Write-Output "Gitコミット失敗"
        return $false
    }

    $arglist = @("tag", "${currentYmd}_release")
    $rc = Start-Process git.exe -PassThru -ArgumentList $arglist -Wait -RedirectStandardOutput $LOG_OUT_FILE -RedirectStandardError $LOG_ERR_FILE

    if ($rc.ExitCode -ne 0) {
        Write-Output "Gitタグ作成失敗"
        return $false
    }

    $arglist = @("push", "--tags", "origin", "master:master")
    $rc = Start-Process git.exe -PassThru -ArgumentList $arglist -Wait -RedirectStandardOutput $LOG_OUT_FILE -RedirectStandardError $LOG_ERR_FILE

    if ($rc.ExitCode -ne 0) {
        Write-Output "Gitプッシュ失敗"
        return $false
    }

    return $true
}

main
```

RPA用PCへの接続にはSSHなどを使う方が、リモート接続の手間が簡略化され、さらにシンプルになる。
(私の場合は、環境セットアップに手間取って採用できなかった)