この投稿は「UiPath Advent Calendar 2024」の5日目のエントリです。
何をするか
この件です。
2024年12月時点の「Cloud Orchestrator」では、 タイムトリガーを「次回実行時間順」で並び替え/ソートできない
ので、「次に実行されるタイムトリガーは何だろう?」と思ったときに、目で見て把握する必要があります。
ですが、目で見て把握するのは厳しい。トリガーが増えて複数ページになったら、かなり面倒で苛立ちます。なぜソートできないのか!
なぜ「次回実行時間順」にソート機能が無いのか?
(あくまで推測ですが) Orchestratorのタイムトリガーの登録内容を見ると、Cron式で1回限りの実行でない限り「次回実行時間」を持っていません。登録したデータは「繰り返し実行のルール」があるだけです。
つまり、次回実行時間は「登録内容と現在日時を加味して計算した参考値」でなので、SQL実行時には「並び替えのキーに指定しにくい(できるけど「都度計算で結果が変わる」のでキャッシュが有効活用できず、クエリ実行時のコストになってしまう)」のだと思います。
とすると、今後、ソート項目に足されるのは厳しいかもしれない。(足してほしいけれど)
どうするか?
(APIで)ある程度絞ってデータを取得して、並び替えれば出来ます。
Xamlで書いても良いし、Powerautomateでも良いですが、処理の内容が説明しやすいように「PowerShell」で作ってみます。
コードサンプル:各種設定
まずは、API実行のための「トークン」を取得です。AutomationCloud にログインし、「PrivateAccessToken」を発行します。
場所)AutomationCloud > 右上ユーザーアイコンを右クリック > 設定 > 個人用アクセストークン
今回はタイムトリガーの情報を取得するので、必要な権限は「OrchestratorAPIAccess」の「Jobs.Read」です。取得したトークンを、以下でセットします。
# トークン
$token = 'rt_・・・・・・'
次にAPIのベースURLを確認します。
Orchestratorのテナントの情報になるので、以下の例に倣ってOrchestratorのURLの前方の情報をセットします。
例)https://cloud.uipath.com/{個別のID}/{テナント名}/orchestrator_/
# URL
$baseUrl = 'https://cloud.uipath.com/{個別のID}/{テナント名}'
次は取得対象のフォルダの指定です。
OrchestratorのAPIは基本的に「フォルダ単位でしか処理ができない」ので、トリガーデータの取得もフォルダ単位で分割して行います。
PowerShellの変数にフォルダの「名前」と「ID」を以下のようにセットします。
(フォルダIDは、OrchestratorのURLで「fid=******」となっている部分から把握できます)
今回は、実行結果を分かりやすくするために「フォルダ名」も一緒にセットしています。
# フォルダ
$ary_folder = @()
$ary_folder += New-Object PSObject -Property @{Id = "6127328"; Name = "管理部"}
$ary_folder += New-Object PSObject -Property @{Id = "6127329"; Name = "マーケ部"}
最後に結果の出力先ファイルパスを指定します。
# 出力ファイルパス
$outputPath = "C:\work\nexttrigger_" + (Get-Date -Format "yyyy-MMdd-HHmmss") + ".txt"
コードサンプル:データの取得
続いて APIからデータを取得します。
以下でタイムトリガーの情報を「API:ProcessSchedules」から「有効」になっているデータに絞り込んで取得します。
# トリガー情報取得
$ary_trigger = @()
$url = $baseUrl + '/orchestrator_/odata/ProcessSchedules?$filter=Enabled%20eq%20true'# 有効のみ
foreach($folder in $ary_folder){
$headers = @{"Authorization" = "Bearer " + $token; "X-UIPATH-OrganizationUnitId" = $folder.id}
$response = Invoke-RestMethod -Uri $url -Method Get -Headers $headers -ContentType "application/json"
if ($response.StatusCode -lt 300){
foreach($dat in $response.value){
$MachineName = ""
if($dat.MachineRobots -ne $null){
$MachineName =$dat.MachineRobots.MachineName
}
$NextOccurrence = ""
$NextDate = ""
if($dat.StartProcessNextOccurrence -ne $null){
$NextOccurrence = (Get-Date -Date $dat.StartProcessNextOccurrence).ToString("yyyy/MM/dd HH:mm:00")
$NextDate = (Get-Date -Date $dat.StartProcessNextOccurrence).ToString("yyyy/MM/dd")
}
$item = New-Object PSObject -Property @{
Name = $dat.Name
MachineName = $MachineName
UnitName = $folder.Name
StartTime = $NextOccurrence
StartDate = $NextDate
}
$ary_trigger += $item
}
}else{
Write-Host $response.StatusCode
Write-Host $response.StatusDescription
throw ”API呼び出しエラー”
}
Write-Host "[Get]Sleep - 5 Seconds...(optional delay for api rate limit)"
Sleep 5
}
コードサンプル:データの絞り込み・並び替え・出力
取得後に「次回実行が本日」に絞り込み「実行開始順」で並び替えて出力します。
# 絞り込み・並び替え
$ary_trigger = $ary_trigger | Where-Object StartDate -eq (Get-Date -Format "yyyy/MM/dd")
$ary_trigger = $ary_trigger | Select-Object StartTime, MachineName, UnitName, Name
$ary_trigger = $ary_trigger | Sort-Object -Property StartTime, Name
# 結果出力:CSV
$ary_trigger | Export-Csv $outputPath -Encoding Default
説明は以上です。
全て繋げると以下のようになります。
# トークン
$token = 'rt_・・・・・・'
# URL
$baseUrl = 'https://cloud.uipath.com/{個別のID}/{テナント名}'
# フォルダ
$ary_folder = @()
$ary_folder += New-Object PSObject -Property @{Id = "6127328"; Name = "管理部"}
$ary_folder += New-Object PSObject -Property @{Id = "6127329"; Name = "マーケ部"}
# 出力ファイルパス
$outputPath = "C:\work\nexttrigger_" + (Get-Date -Format "yyyy-MMdd-HHmmss") + ".txt"
# トリガー情報取得
$ary_trigger = @()
$url = $baseUrl + '/orchestrator_/odata/ProcessSchedules?$filter=Enabled%20eq%20true'# 有効のみ
foreach($folder in $ary_folder){
$headers = @{"Authorization" = "Bearer " + $token; "X-UIPATH-OrganizationUnitId" = $folder.id}
$response = Invoke-RestMethod -Uri $url -Method Get -Headers $headers -ContentType "application/json"
if ($response.StatusCode -lt 300){
foreach($dat in $response.value){
$MachineName = ""
if($dat.MachineRobots -ne $null){
$MachineName =$dat.MachineRobots.MachineName
}
$NextOccurrence = ""
$NextDate = ""
if($dat.StartProcessNextOccurrence -ne $null){
$NextOccurrence = (Get-Date -Date $dat.StartProcessNextOccurrence).ToString("yyyy/MM/dd HH:mm:00")
$NextDate = (Get-Date -Date $dat.StartProcessNextOccurrence).ToString("yyyy/MM/dd")
}
$item = New-Object PSObject -Property @{
Name = $dat.Name
MachineName = $MachineName
UnitName = $folder.Name
StartTime = $NextOccurrence
StartDate = $NextDate
}
$ary_trigger += $item
}
}else{
Write-Host $response.StatusCode
Write-Host $response.StatusDescription
throw ”API呼び出しエラー”
}
Write-Host "[Get]Sleep - 5 Seconds...(optional delay for api rate limit)"
Sleep 5
}
# 絞り込み・並び替え
$ary_trigger = $ary_trigger | Where-Object StartDate -eq (Get-Date -Format "yyyy/MM/dd")
$ary_trigger = $ary_trigger | Select-Object StartTime, MachineName, UnitName, Name
$ary_trigger = $ary_trigger | Sort-Object -Property StartTime, Name
# 結果出力:CSV
$ary_trigger | Export-Csv $outputPath -Encoding Default
$ary_trigger | Format-Table
実行結果・出力内容
上記のコードを実行すると、画面上に結果が整形して表示され、指定の出力先にCSVファイルが出力されます。
次回実行を知りたい時に実行でも、タスクスケジューラーに登録&SlackやTeamsに投稿機能をつけて、定期実行させても良いかもしれません。
終わりに
以上、タイムトリガーをAPIで取得する 方法の紹介でした。