UiPath Documentation
uipath-cli
latest
false

UiPath CLI user guide

最終更新日時 2026年5月7日

Scripting patterns

This page collects the patterns that make uip easy to script against — in shell, PowerShell, and CI pipelines. Nothing here is specific to a single tool; every pattern builds on the contract that the exit code and JSON envelope expose consistently across commands.

Helpful defaults

Three design decisions make scripting straightforward:

  1. JSON is the default output. No --output json needed, whether you are in a terminal or a pipeline.
  2. Stdout is JSON only; everything else is stderr. Logs, progress bars, and human-readable error text go to stderr, so capturing stdout gives you clean data.
  3. Exit codes are narrow and stable. Five values (0, 1, 2, 3, 4) cover every documented failure mode, plus 130 for user cancellation. Scripts can branch without parsing strings.

Strict shell options

For bash / zsh, start scripts with:

#!/usr/bin/env bash
set -euo pipefail
#!/usr/bin/env bash
set -euo pipefail
  • -e — abort on any command that exits non-zero.
  • -u — abort on an undefined variable.
  • -o pipefail — propagate a failure from any stage of a pipeline, not just the last one.

For PowerShell:

$ErrorActionPreference = 'Stop'
$ErrorActionPreference = 'Stop'

Branching on exit codes

The Result value on the envelope maps one-to-one to the process exit code. Branch on the exit code for fast decisions; open the envelope for detail (see Exit codes for the full table).

if uip or folders list --output-filter "Data[?Name=='Shared'] | [0]" > shared.json; then
  echo "Shared folder found"
else
  case $? in
    2)  echo "re-authenticating"; uip login --client-id env.UIPATH_CLIENT_ID --client-secret env.UIPATH_CLIENT_SECRET --tenant "$UIPATH_TENANT" ;;
    3)  echo "bad flag — aborting"; exit 3 ;;
    *)  echo "unexpected failure"; exit 1 ;;
  esac
fi
if uip or folders list --output-filter "Data[?Name=='Shared'] | [0]" > shared.json; then
  echo "Shared folder found"
else
  case $? in
    2)  echo "re-authenticating"; uip login --client-id env.UIPATH_CLIENT_ID --client-secret env.UIPATH_CLIENT_SECRET --tenant "$UIPATH_TENANT" ;;
    3)  echo "bad flag — aborting"; exit 3 ;;
    *)  echo "unexpected failure"; exit 1 ;;
  esac
fi

Reading values out of the envelope

Use --output-filter (JMESPath) to extract values at the source, rather than piping through jq:

FOLDER_KEY=$(uip or folders list --all --name Shared --output-filter "Data[0].Key" --output plain)
FOLDER_KEY=$(uip or folders list --all --name Shared --output-filter "Data[0].Key" --output plain)

--output plain returns the bare value (no quotes) for a scalar filter result. For arrays and objects, --output json keeps the structure:

PROCESS_KEYS=$(uip or processes list --folder-path Shared --output-filter "Data[*].Key")
echo "$PROCESS_KEYS" | jq -r '.[]' | while read -r key; do
  uip or jobs start "$key"
done
PROCESS_KEYS=$(uip or processes list --folder-path Shared --output-filter "Data[*].Key")
echo "$PROCESS_KEYS" | jq -r '.[]' | while read -r key; do
  uip or jobs start "$key"
done

If you prefer jq end-to-end, capture raw JSON and chain:

FOLDER_KEY=$(uip or folders list --all --name Shared | jq -r '.Data[0].Key')
FOLDER_KEY=$(uip or folders list --all --name Shared | jq -r '.Data[0].Key')

Both approaches produce the same value. --output-filter is faster and validates at CLI-parse time; jq gives you the full JMESPath plus jq-specific constructs like [-1] (last element) and to_entries.

Re-authenticating on AuthenticationError (exit 2)

Access tokens expire. In a long-running script, the pattern is: run the command, fall back to uip login if the token is gone, retry once, then fail hard.

uip_retry() {
  uip "$@" && return 0
  local code=$?
  if [[ $code -eq 2 ]]; then
    uip login \
      --client-id env.UIPATH_CLIENT_ID \
      --client-secret env.UIPATH_CLIENT_SECRET \
      --tenant "$UIPATH_TENANT" >/dev/null
    uip "$@"
  else
    return $code
  fi
}

uip_retry or folders list --all
uip_retry() {
  uip "$@" && return 0
  local code=$?
  if [[ $code -eq 2 ]]; then
    uip login \
      --client-id env.UIPATH_CLIENT_ID \
      --client-secret env.UIPATH_CLIENT_SECRET \
      --tenant "$UIPATH_TENANT" >/dev/null
    uip "$@"
  else
    return $code
  fi
}

uip_retry or folders list --all

Keep retries bounded — a single auth retry handles token expiry; further retries would mask a misconfigured credential and burn rate limits.

Polling long-running operations

Some operations complete asynchronously on the Orchestrator side:

  • Job execution — use uip or jobs start --wait-for-completion to have the CLI poll for you. Default timeout is 300 seconds, adjustable with --timeout. Poll interval is 5 seconds, adjustable with --poll-interval.
  • Solution deployment — uip solution deploy run polls internally with a default timeout of 360 seconds.
  • Test execution — uip tm testset execute launches the run, returns an ExecutionId, and exits immediately with 0. To block until the run completes, chain uip tm wait (which polls and exits 2 on timeout). To read the pass/fail verdict after waiting, inspect Data.Failed in uip tm report get. See uip tm testset, uip tm execution, and uip tm wait.

When the built-in polling is too coarse, or when the terminal state needs custom handling, poll yourself:

JOB_KEY=$(uip or jobs start "$PROCESS_KEY" --output-filter "Data.Jobs[0].Key" --output plain)

while :; do
  STATE=$(uip or jobs get --job-key "$JOB_KEY" --output-filter "Data.State" --output plain)
  case "$STATE" in
    Successful) echo "done"; break ;;
    Faulted|Stopped) echo "job $STATE"; exit 1 ;;
    *) sleep 10 ;;
  esac
done
JOB_KEY=$(uip or jobs start "$PROCESS_KEY" --output-filter "Data.Jobs[0].Key" --output plain)

while :; do
  STATE=$(uip or jobs get --job-key "$JOB_KEY" --output-filter "Data.State" --output plain)
  case "$STATE" in
    Successful) echo "done"; break ;;
    Faulted|Stopped) echo "job $STATE"; exit 1 ;;
    *) sleep 10 ;;
  esac
done

Always cap the loop on time — a Faulted job that ends up in a Pending loop will otherwise block forever:

DEADLINE=$(( SECONDS + 1800 ))
while (( SECONDS < DEADLINE )); do
  # … as above …
done
[[ $SECONDS -ge $DEADLINE ]] && { echo "timed out"; exit 1; }
DEADLINE=$(( SECONDS + 1800 ))
while (( SECONDS < DEADLINE )); do
  # … as above …
done
[[ $SECONDS -ge $DEADLINE ]] && { echo "timed out"; exit 1; }

Idempotent pipelines

Many uip commands are idempotent by design — re-running them with the same arguments either returns the existing resource or does nothing:

  • uip solution publish — re-publishing a package with the same name and version returns the existing version.
  • uip tools install — a no-op if the tool is already installed.
  • uip or processes create — will fail on duplicate name-in-folder; use uip or processes update-version or uip or processes edit in that case.
  • uip resource assets deploy --from-file — upserts by key.

Combine these with set -e to build pipelines that are safe to re-run after a partial failure without cleanup steps.

Separating data from logs

Stdout is JSON. Stderr is everything else. Redirect them independently:

uip or folders list > folders.json 2> uip.log
uip or folders list > folders.json 2> uip.log

This is especially important in CI: a job that prints progress indicators or npm output inline with the data stream will produce mangled JSON for later steps to consume.

Handling empty results

A command that succeeds with zero rows in Data exits 0 — the list query worked, but nothing matched. Detect this with --output-filter:

COUNT=$(uip or folders list --all --name DoesNotExist --output-filter "length(Data)" --output plain)
if [[ "$COUNT" -eq 0 ]]; then
  echo "no match"
  exit 1
fi
COUNT=$(uip or folders list --all --name DoesNotExist --output-filter "length(Data)" --output plain)
if [[ "$COUNT" -eq 0 ]]; then
  echo "no match"
  exit 1
fi

Do not pattern-match on the absence of a Name in the table output; it is not a parseable format.

Pinning versions in CI

Reproducible pipelines require pinning both the CLI and (optionally) the tools. Because tool versions track the CLI's MAJOR.MINOR line by default, pinning the CLI alone usually suffices:

npm install -g @uipath/cli@1.0.0
uip tools install @uipath/orchestrator-tool   # resolves to latest 1.0.x
npm install -g @uipath/cli@1.0.0
uip tools install @uipath/orchestrator-tool   # resolves to latest 1.0.x

For strict reproducibility across patch levels, also pin tools:

uip tools install @uipath/orchestrator-tool@1.0.2
uip tools install @uipath/orchestrator-tool@1.0.2

Suppressing interactive prompts

A handful of uip commands are interactive by default when stdout is a TTY:

  • uip login — prompts for tenant selection if --tenant is not passed.
  • uip skills install/update/uninstall — prompts for the target agent if --agent is not passed.
  • uip completion — prompts to confirm the install path.
  • uip tools search — prompts for a query if none is passed.

In CI these prompts can hang a job. Avoid them by always passing the relevant flags (--tenant, --agent, --print/explicit shell on completion) or by ensuring stdout is not a TTY (most CI runners already take care of this).

Disabling telemetry in CI

Anonymous telemetry is sent to UiPath's Application Insights by default. For air-gapped or strict environments:

export UIPATH_TELEMETRY_DISABLED=1
export UIPATH_TELEMETRY_DISABLED=1

…or point it at your own instance via UIPATH_AI_CONNECTION_STRING. See Installing UiPath CLI — Telemetry.

参照

このページは役に立ちましたか?

接続

ヘルプ リソース サポート

学習する UiPath アカデミー

質問する UiPath フォーラム

最新情報を取得