管理ツールによる一括セットアップ
管理ツールを使って組織内の開発者端末に一括でセットアップするために利用できる、配信用スクリプトを提供しています。ご利用の管理ツールに応じて、カスタマイズしてご利用ください。
この機能を利用するには、Guard を有効化した基本サブスクリプションが必要です。詳しくは料金と請求を参照してください。
概要
一括セットアップは、管理者が管理ツール(Jamf、Intune、Ansible など)を使って、組織内の開発者端末に Takumi Guard のレジストリプロキシ設定を一括で配信する仕組みです。開発者自身がコマンドを実行したり、設定ファイルを編集する必要はありません。
以下の図は、一括セットアップの全体構成を示しています。
管理者がコンソールで Bot と管理用 API キーを作成し、セットアップスクリプトとともに管理ツール経由で各端末に配信します。各端末ではスクリプトが自動的に Guard API にトークン発行をリクエストし、npm・pip・uv・Poetry・Bundler・Go modules の設定ファイルを更新します。以降、各端末からのパッケージインストールは Guard レジストリプロキシを経由するようになります。
セットアップスクリプトによって発行されたトークンは、コンソールの Guard > トークン で一覧・管理できます。

セットアップは大きく 2 つのフェーズに分かれます。
- 準備:Takumi / Shisho Cloud コンソールで Bot を作成し、セットアップスクリプトをダウンロードします
- 配信:管理ツール用のラッパースクリプトを作成し、セットアップスクリプトと合わせて対象端末に配信します
前提条件
配信の前に、Takumi / Shisho Cloud コンソールで以下の設定を完了してください。
-
Bot を作成する:設定 > Bot ページの「ボットの追加」ボタンから作成してください

-
ロールを付与する:Bot に「Takumi Guard トークン発行者」ロールを付与してください

-
API キーを取得する:作成した Bot の詳細ページで「API キーの作成」ボタンから静的 API キーを作成し、安全に保管してください

Bot の作成と API キーの発行手順の詳細はこちらも参照してください。
セットアップスクリプト
トークンの発行とパッケージマネージャーの設定を行うセットアップスクリプトを提供しています。お使いのプラットフォームに合わせてダウンロードしてください。
- macOS / Linux: https://shisho.dev/releases/takumi-guard-setup-0.8.1.sh
- Windows: https://shisho.dev/releases/takumi-guard-setup-0.8.1.ps1
対象端末には curl がインストールされている必要があります(macOS および Linux の場合)。
使い方
セットアップスクリプトは、実行したユーザーの設定ファイルのみを変更します。組織内の全ユーザーに一括展開する場合は、後述の配信例のラッパースクリプトを使用してください。
セットアップスクリプトを以下のように実行してください。API キーは環境変数 TG_BOT_API_KEY で渡してください。
TG_BOT_API_KEY="shisho_apikey_..." ./setup.sh <BOT_ID> <USER_IDENTIFIER>
各パラメータの意味は以下の通りです。
| パラメータ | 説明 |
|---|---|
TG_BOT_API_KEY | (環境変数)Bot の API キー |
BOT_ID | Takumi / Shisho Cloud コンソールの Bot ID |
USER_IDENTIFIER | デバイスやユーザーを識別するユニークな値 |
TG_DIRECT_WRITE | (任意の環境変数)パッケージマネージャーの事前検証をせず、設定ファイルへ直接書 き込みます。詳しくはこちらを参照してください |
対象を限定したい場合は、第 3 引数でスコープを指定してください。
TG_BOT_API_KEY="..." ./setup.sh BOT_ID USER_IDENTIFIER npm,rubygems
| スコープ | 設定されるパッケージマネージャー |
|---|---|
npm | npm, pnpm, yarn(v2+), bun |
pypi | pip, uv, poetry |
rubygems | Bundler |
golang | Go modules |
Poetry は、スクリプトによるユーザー単位の設定だけでは保護が有効になりません。別途、リポジトリごとの設定が必要です。詳しくは、Python パッケージマネージャー Poetry を利用する場合を参照してください。
参考:USER_IDENTIFIER の決め方
USER_IDENTIFIER は、デバイスやユーザーを識別する文字列です。組織内で一貫した命名規則を決めておくことを推奨します。
文字種の制約は以下の通りです。
- 使用可能な文字:
a-z,A-Z,0-9,-,_,.,@,+ - 文字数: 4〜255 文字
以下の例を参考に、組織に合った識別子を選んでください。
| 例 | 値 | 説明 |
|---|---|---|
| デバイスのシリアルナンバー + OS ユーザー名 | C02X1234_jdoe | デバイス BIOS のハードウェアシリアルナンバーを使用 |
| 資産管理 ID + 社員 ID | ASSET0042_EMP12345 | 組織で管理している ID を使用 |
| MDM のデバイス ID + OS ユーザー名 | a401c7d0_jdoe | MDM ツールが割り 当てるデバイス ID を使用 |
選択した識別子が組織内でユニークであることを確認してください。一部の識別子(シリアルナンバーなど)は、自作 PC や仮想マシンなどの環境では空になったり、デバイス間でユニークでない場合があります。各デバイスとユーザーを確実に区別できる値を使用してください。
参考:詳細な挙動
初回実行時
セットアップスクリプトがトークンを発行し、既存の設定ファイルのタイムスタンプ付きバックアップ(例:~/.npmrc-backup-20260408-162351)を作成してから、Guard の設定を追記します。既存の Guard 以外の設定は変更されません。
トークンが上書きされるケース
セットアップスクリプトは、Guard が管理対象とするすべての設定ファイルを確認し、既存のトークンを検出した場合はそのトークンを検証します。また、設定ファイルごとに異なる複数のトークンが存在する場合は、それらすべてのトークンを検証します。
検出されたすべてのトークンが、以下のいずれかの条件に該当する場合、新しい組織ユーザートークンを発行し、既存のトークンをその新しいトークンで上書きします。一方で、有効かつ指定された組織に紐づく組織ユーザートークンが 1 つでも存在する場合は、そのトークンを再利用します。
- メール認証トークンである場合
- 存在しないトークンである場合
- 無効化(失効)されたトークンである場合
- 別の組織で発行されたトークンである場合
上書き前には、各設定ファイルのタイムスタンプ付きバックアップが作成されます。
再実行時
有効な組織ユーザートークンを検出して再利用するため、上記のケースを除き、新しいトークンは発行されません。また、既に Guard が設定済みのツールはスキップされます(変更もバックアップも行われません)。スコープの増分追加にも対応しています。たとえば、先に npm スコープで実行し、後から pypi スコープを追加できます。
パッケージマネージャーの事前検証
セットアッ プスクリプトは、Guard の設定を行う前に、対象となるすべてのパッケージマネージャーを一つずつ確認します。以下のいずれかに該当する場合、そのパッケージマネージャーに対して Guard の設定を行います。
- パッケージマネージャーの設定ファイルが存在する
- 利用可能な CLI が存在する
また、設定対象となるパッケージマネージャーが一つでも見つかった場合にのみ、必要に応じて組織ユーザートークンを発行します。一方で、設定対象が一つも見つからない場合は、トークンの発行や設定の変更を行わずにセットアップを終了します。
これにより、Guard の保護対象となるパッケージマネージャーを利用していない端末に対するトークン発行を防ぎ、不要な課金の発生を抑制します。
事前検証を行わずに Guard を設定する方法も用意しています。詳しくは「事前検証をせずに設定する」を参照してください。
手動ロールバック
セットアップスクリプトは、設定ファイルを変更する前にタイムスタンプ付きの永続バックアップを作成します(例:~/.npmrc-backup-20260408-162351)。Guard の設定を元に戻したい場合は、このバックアップファイルを元のファイル名にコピーしてください(例:cp ~/.npmrc-backup-20260408-162351 ~/.npmrc)。
端末の入れ替えや従業員の退職などで不要になったトークンは、Takumi / Shisho Cloud コンソールから失効させてください。詳しくは組織ユーザートークンの失効を参照してください。
パッケージマネージャーに別のレジストリ(プライベート npm レジストリなど)が既に設定され ている場合、セットアップスクリプトは既存のレジストリ設定を Guard のレジストリで上書きします。上書き前にタイムスタンプ付きのバックアップファイルが作成されますが、念のため、配信前に対象端末で使用中のレジストリ設定を確認してください。
配信例
セットアップスクリプトの配信方法は、利用する管理ツールや OS によって異なります。ここでは、代表的な OS やトークン発行方針に応じた配信例を紹介します。なお、以下のラッパースクリプトはあくまでサンプルです。利用する環境や運用に合わせて適宜修正してください。
- 端末あたり1トークン発行: 端末ごとにトークンを発行します。端末上のいずれかのアカウントに有効なトークンが存在しないかを確認したうえで、存在する場合は再利用し、存在しない場合だけ新しくトークンを 1 つ発行したうえで、端末上の各開発者アカウントに対して同じトークンで設定します。
- 端末のユーザー毎に個別トークン発行: (端末, ユーザー)の組ごとにトークンを発行します。1 台の端末に複数の開発者アカウントが存在する環境(共用ワークステーション、MDM が作成する管理者アカウントと利用者アカウントが併存する端末、IdP が発行するアカウントとビルトインローカルアカウントが併存する端末など)では、同じ端末でアカウント数分のライセンスを消費することになります。
いずれのラッパースクリプトも、有効なトークンを検出した場合は再利用するため、定期実行はどちらのモデルでも安全です。
実際の環境では、管理用のサービスアカウントや、Takumi Guard の設定対象としたくないユーザーを除外したい場合があります。そのような場合は、ラッパースクリプト側で対象ユーザーを絞り込むことで対応できます。
macOS / Linux の例:
# 特定のユーザー名をスキップ
case "$USER_NAME" in
corp-admin|service-account|Guest) continue ;;
esac
Windows の例:
# 特定のユーザー名をスキップ
$Skip = @('corp-admin', 'Guest', 'defaultuser0')
if ($Skip -contains $UserName) { continue }
同様の方法で、対象ディレクトリや所属グループによる絞り込みも実装できます。たとえば、macOS / Linux では /Users/dev-* や /home/dev-* 配下のユーザーのみを対象にしたり、id -Gn "$USER_NAME" | grep -q developers を利用して特定のグループに所属するユーザーのみを対象にしたりできます。Windows でも、Get-CimInstance Win32_GroupUser などを利用して同様の制御が可能です。
macOS
管理ツールによるスクリプト実行は通常 root 権限で行われるため、以下のラッパースクリプトがユーザーごとに切り替えながら、各開発者の環境へセットアップを行います。配信方法については、Jamf Pro のスクリプト実行機能など、利用する管理ツールの手順に従ってください。
- 端末あたり1トークン発行
- 端末のユーザー毎に個別トークン発行
#!/bin/bash
# Admin deployment wrapper (one token per device)
# TODO: Replace with your Bot ID and API key from Shisho Cloud console
BOT_ID="BTXXXXXXXXXXXXXXXXXXXXXXXXXX"
export TG_BOT_API_KEY="shisho_apikey_XXXXX"
# TODO: Update VERSION when a newer setup script becomes available
VERSION="0.8.1"
# Set to true to pre-provision package managers that are not installed yet
# (writes config directly and skips the pre-check).
TG_DIRECT_WRITE=false
# Download the setup script
SCRIPT_PATH=$(mktemp /tmp/takumi-guard-setup.XXXXXX)
curl -sL -o "$SCRIPT_PATH" "https://shisho.dev/releases/takumi-guard-setup-${VERSION}.sh"
chmod 755 "$SCRIPT_PATH"
trap 'rm -f "$SCRIPT_PATH"' EXIT
# Device-level USER_IDENTIFIER: serial number only -- the token is shared
# across every user on this device, so the identifier does not embed a user.
# Fall back to the hostname if empty or a placeholder, and strip disallowed characters.
SERIAL=$(ioreg -l | grep IOPlatformSerialNumber | awk -F'"' '{print $4}')
SERIAL=$(printf '%s' "$SERIAL" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
case "$SERIAL" in ''|None|0|'System Serial Number'|'To Be Filled By O.E.M.'|'Default string'|'Default System Serial Number'|'Not Specified'|'Not Applicable'|'Not Available') SERIAL=$(hostname) ;; esac
SERIAL=$(printf '%s' "$SERIAL" | LC_ALL=C tr -cs '0-9A-Za-z._@+-' '-' | sed 's/^-*//; s/-*$//')
[ "${#SERIAL}" -ge 4 ] || SERIAL="unknown-device"
USER_IDENTIFIER="$SERIAL"
# Phase 1 -- discover an existing active token on this device.
DEVICE_TOKEN=""
for USER_HOME in /Users/*; do
USER_NAME=$(basename "$USER_HOME")
[ "$USER_NAME" = "Shared" ] && continue
[ ! -d "$USER_HOME" ] && continue
id "$USER_NAME" >/dev/null 2>&1 || continue
CANDIDATES=$(sudo -u "$USER_NAME" -H "$SCRIPT_PATH" discover 2>/dev/null) || continue
while IFS= read -r CAND; do
[ -n "$CAND" ] || continue
STATUS=$(HOME="$USER_HOME" USER_HOME="$USER_HOME" TG_BOT_ID="$BOT_ID" "$SCRIPT_PATH" verify "$CAND" 2>/dev/null)
case "$STATUS" in
active)
DEVICE_TOKEN="$CAND"
break 2
;;
unknown)
# Network down / API unreachable: abort instead of burning a
# fresh license under uncertainty.
echo "[Error] Could not verify token status against the Shisho Cloud API. Re-run after the API is reachable." >&2
exit 1
;;
esac
done <<EOF
$CANDIDATES
EOF
done
# Phase 2 -- if no active token exists yet, mint exactly one for the device.
if [ -z "$DEVICE_TOKEN" ]; then
# If no profile on this device has anything to configure, skip the
# mint -- otherwise every no-op deploy would still consume a license.
HAS_ANY_TARGET=false
for USER_HOME in /Users/*; do
USER_NAME=$(basename "$USER_HOME")
[ "$USER_NAME" = "Shared" ] && continue
[ ! -d "$USER_HOME" ] && continue
id "$USER_NAME" >/dev/null 2>&1 || continue
if sudo -u "$USER_NAME" -H TG_DIRECT_WRITE="${TG_DIRECT_WRITE:-}" "$SCRIPT_PATH" precheck 2>/dev/null; then
HAS_ANY_TARGET=true
break
fi
done
if [ "$HAS_ANY_TARGET" = false ]; then
echo "[Done] No configurable tools found on this device. Skipping token mint."
exit 0
fi
DEVICE_TOKEN=$(HOME=/var/root USER_HOME=/var/root TG_BOT_ID="$BOT_ID" "$SCRIPT_PATH" issue "$USER_IDENTIFIER")
if [ -z "$DEVICE_TOKEN" ]; then
echo "[Error] Failed to obtain device token" >&2
exit 1
fi
fi
# Phase 3 -- install the same token for every developer account.
for USER_HOME in /Users/*; do
USER_NAME=$(basename "$USER_HOME")
[ "$USER_NAME" = "Shared" ] && continue
[ ! -d "$USER_HOME" ] && continue
id "$USER_NAME" >/dev/null 2>&1 || continue
sudo -u "$USER_NAME" -H zsh -lic "
TG_DIRECT_WRITE='${TG_DIRECT_WRITE:-}' $SCRIPT_PATH install '$DEVICE_TOKEN'
"
echo "[Done] $USER_NAME"
done
# Clean up credentials
unset TG_BOT_API_KEY
#!/bin/bash
# Admin deployment wrapper
# TODO: Replace with your Bot ID and API key from Shisho Cloud console
BOT_ID="BTXXXXXXXXXXXXXXXXXXXXXXXXXX"
export TG_BOT_API_KEY="shisho_apikey_XXXXX"
# TODO: Update VERSION when a newer setup script becomes available
VERSION="0.8.1"
# Set to true to pre-provision package managers that are not installed yet
# (writes config directly and skips the pre-check).
TG_DIRECT_WRITE=false
# Download the setup script
SCRIPT_PATH=$(mktemp /tmp/takumi-guard-setup.XXXXXX)
curl -sL -o "$SCRIPT_PATH" https://shisho.dev/releases/takumi-guard-setup-${VERSION}.sh
chmod 755 "$SCRIPT_PATH"
trap 'rm -f "$SCRIPT_PATH"' EXIT
# Get the device serial number for USER_IDENTIFIER generation, falling back to
# the hostname and stripping characters the identifier does not allow.
SERIAL=$(ioreg -l | grep IOPlatformSerialNumber | awk -F'"' '{print $4}')
SERIAL=$(printf '%s' "$SERIAL" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
case "$SERIAL" in ''|None|0|'System Serial Number'|'To Be Filled By O.E.M.'|'Default string'|'Default System Serial Number'|'Not Specified'|'Not Applicable'|'Not Available') SERIAL=$(hostname) ;; esac
SERIAL=$(printf '%s' "$SERIAL" | LC_ALL=C tr -cs '0-9A-Za-z._@+-' '-' | sed 's/^-*//; s/-*$//')
[ "${#SERIAL}" -ge 4 ] || SERIAL="unknown-device"
# Run the setup script for each user on this machine
for USER_HOME in /Users/*; do
USER_NAME=$(basename "$USER_HOME")
# Skip system directories and non-existent paths
[ "$USER_NAME" = "Shared" ] && continue
[ ! -d "$USER_HOME" ] && continue
# Skip if the user account does not exist
id "$USER_NAME" >/dev/null 2>&1 || continue
# Build a unique identifier for this device + user combination
SAFE_USER_NAME=$(printf '%s' "$USER_NAME" | LC_ALL=C tr -cs '0-9A-Za-z._@+-' '-' | sed 's/^-*//; s/-*$//')
[ -n "$SAFE_USER_NAME" ] || SAFE_USER_NAME="uid-$(id -u "$USER_NAME" 2>/dev/null)"
USER_IDENTIFIER="${SERIAL}_${SAFE_USER_NAME}"
# Run the setup script as this user.
# Use zsh -lic (login + interactive) so that ~/.zshrc is loaded and
# package managers installed outside the default PATH are found.
sudo -u "$USER_NAME" -H zsh -lic '
TG_BOT_API_KEY="'"$TG_BOT_API_KEY"'" TG_DIRECT_WRITE="'"${TG_DIRECT_WRITE:-}"'" \
"'"$SCRIPT_PATH"'" "'"$BOT_ID"'" "'"$USER_IDENTIFIER"'"
'
echo "[Done] $USER_NAME (USER_IDENTIFIER: $USER_IDENTIFIER)"
done
# Clean up credentials
unset TG_BOT_API_KEY
Linux
管理ツールによるスクリプト実行は通常 root 権限で行われるため、以下のラッパースクリプトがユーザーごとに切り替えながら、各開発者の環境へセットアップを行います。
- 端末あたり1トークン発行
- 端末のユーザー毎に個別トークン発行
#!/bin/bash
# Admin deployment wrapper (one token per device)
# TODO: Replace with your Bot ID and API key from Shisho Cloud console
BOT_ID="BTXXXXXXXXXXXXXXXXXXXXXXXXXX"
export TG_BOT_API_KEY="shisho_apikey_XXXXX"
# TODO: Update VERSION when a newer setup script becomes available
VERSION="0.8.1"
# Set to true to pre-provision package managers that are not installed yet
# (writes config directly and skips the pre-check).
TG_DIRECT_WRITE=false
# Download the setup script
SCRIPT_PATH=$(mktemp /tmp/takumi-guard-setup.XXXXXX)
curl -sL -o "$SCRIPT_PATH" "https://shisho.dev/releases/takumi-guard-setup-${VERSION}.sh"
chmod 755 "$SCRIPT_PATH"
trap 'rm -f "$SCRIPT_PATH"' EXIT
# Device-level USER_IDENTIFIER: serial number only, falling back to the hostname
# and stripping characters the identifier does not allow.
SERIAL=$(dmidecode -s system-serial-number 2>/dev/null)
SERIAL=$(printf '%s' "$SERIAL" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
case "$SERIAL" in ''|None|0|'System Serial Number'|'To Be Filled By O.E.M.'|'Default string'|'Default System Serial Number'|'Not Specified'|'Not Applicable'|'Not Available') SERIAL=$(hostname) ;; esac
SERIAL=$(printf '%s' "$SERIAL" | LC_ALL=C tr -cs '0-9A-Za-z._@+-' '-' | sed 's/^-*//; s/-*$//')
[ "${#SERIAL}" -ge 4 ] || SERIAL="unknown-device"
USER_IDENTIFIER="$SERIAL"
# Phase 1 -- discover an existing active token on this device.
DEVICE_TOKEN=""
for USER_HOME in /home/*; do
USER_NAME=$(basename "$USER_HOME")
[ ! -d "$USER_HOME" ] && continue
id "$USER_NAME" >/dev/null 2>&1 || continue
CANDIDATES=$(sudo -u "$USER_NAME" -H "$SCRIPT_PATH" discover 2>/dev/null) || continue
while IFS= read -r CAND; do
[ -n "$CAND" ] || continue
STATUS=$(HOME="$USER_HOME" USER_HOME="$USER_HOME" TG_BOT_ID="$BOT_ID" "$SCRIPT_PATH" verify "$CAND" 2>/dev/null)
case "$STATUS" in
active)
DEVICE_TOKEN="$CAND"
break 2
;;
unknown)
echo "[Error] Could not verify token status against the Shisho Cloud API. Re-run after the API is reachable." >&2
exit 1
;;
esac
done <<EOF
$CANDIDATES
EOF
done
# Phase 2 -- if no active token exists yet, mint exactly one for the device.
if [ -z "$DEVICE_TOKEN" ]; then
# If no profile on this device has anything to configure, skip the
# mint -- otherwise every no-op deploy would still consume a license.
HAS_ANY_TARGET=false
for USER_HOME in /home/*; do
USER_NAME=$(basename "$USER_HOME")
[ ! -d "$USER_HOME" ] && continue
id "$USER_NAME" >/dev/null 2>&1 || continue
if sudo -u "$USER_NAME" -H TG_DIRECT_WRITE="${TG_DIRECT_WRITE:-}" "$SCRIPT_PATH" precheck 2>/dev/null; then
HAS_ANY_TARGET=true
break
fi
done
if [ "$HAS_ANY_TARGET" = false ]; then
echo "[Done] No configurable tools found on this device. Skipping token mint."
exit 0
fi
DEVICE_TOKEN=$(HOME=/root USER_HOME=/root TG_BOT_ID="$BOT_ID" "$SCRIPT_PATH" issue "$USER_IDENTIFIER")
if [ -z "$DEVICE_TOKEN" ]; then
echo "[Error] Failed to obtain device token" >&2
exit 1
fi
fi
# Phase 3 -- install the same token for every developer account.
for USER_HOME in /home/*; do
USER_NAME=$(basename "$USER_HOME")
[ ! -d "$USER_HOME" ] && continue
id "$USER_NAME" >/dev/null 2>&1 || continue
USER_SHELL=$(getent passwd "$USER_NAME" | cut -d: -f7)
sudo -u "$USER_NAME" -H "$USER_SHELL" -lic "
[ -f \"\$HOME/.bashrc\" ] && . \"\$HOME/.bashrc\" 2>/dev/null
TG_DIRECT_WRITE='${TG_DIRECT_WRITE:-}' $SCRIPT_PATH install '$DEVICE_TOKEN'
"
echo "[Done] $USER_NAME"
done
# Clean up credentials
unset TG_BOT_API_KEY
#!/bin/bash
# Admin deployment wrapper
# TODO: Replace with your Bot ID and API key from Shisho Cloud console
BOT_ID="BTXXXXXXXXXXXXXXXXXXXXXXXXXX"
export TG_BOT_API_KEY="shisho_apikey_XXXXX"
# TODO: Update VERSION when a newer setup script becomes available
VERSION="0.8.1"
# Set to true to pre-provision package managers that are not installed yet
# (writes config directly and skips the pre-check).
TG_DIRECT_WRITE=false
# Download the setup script
SCRIPT_PATH=$(mktemp /tmp/takumi-guard-setup.XXXXXX)
curl -sL -o "$SCRIPT_PATH" https://shisho.dev/releases/takumi-guard-setup-${VERSION}.sh
chmod 755 "$SCRIPT_PATH"
trap 'rm -f "$SCRIPT_PATH"' EXIT
# Get the device serial number for USER_IDENTIFIER generation, falling back to
# the hostname and stripping characters the identifier does not allow.
SERIAL=$(dmidecode -s system-serial-number 2>/dev/null)
SERIAL=$(printf '%s' "$SERIAL" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
case "$SERIAL" in ''|None|0|'System Serial Number'|'To Be Filled By O.E.M.'|'Default string'|'Default System Serial Number'|'Not Specified'|'Not Applicable'|'Not Available') SERIAL=$(hostname) ;; esac
SERIAL=$(printf '%s' "$SERIAL" | LC_ALL=C tr -cs '0-9A-Za-z._@+-' '-' | sed 's/^-*//; s/-*$//')
[ "${#SERIAL}" -ge 4 ] || SERIAL="unknown-device"
# Run the setup script for each user on this machine
for USER_HOME in /home/*; do
USER_NAME=$(basename "$USER_HOME")
# Skip non-existent paths
[ ! -d "$USER_HOME" ] && continue
# Skip if the user account does not exist
id "$USER_NAME" >/dev/null 2>&1 || continue
# Build a unique identifier for this device + user combination
SAFE_USER_NAME=$(printf '%s' "$USER_NAME" | LC_ALL=C tr -cs '0-9A-Za-z._@+-' '-' | sed 's/^-*//; s/-*$//')
[ -n "$SAFE_USER_NAME" ] || SAFE_USER_NAME="uid-$(id -u "$USER_NAME" 2>/dev/null)"
USER_IDENTIFIER="${SERIAL}_${SAFE_USER_NAME}"
# Run the setup script as this user.
# Detect the user's login shell and run it in login + interactive mode
# so that ~/.bashrc (or ~/.zshrc) is loaded and package managers
# installed outside the default PATH are found.
# Explicitly source .bashrc as a fallback for environments where
# .bash_profile does not source it (e.g. CentOS).
USER_SHELL=$(getent passwd "$USER_NAME" | cut -d: -f7)
sudo -u "$USER_NAME" -H "$USER_SHELL" -lic '
[ -f "$HOME/.bashrc" ] && . "$HOME/.bashrc" 2>/dev/null
TG_BOT_API_KEY="'"$TG_BOT_API_KEY"'" TG_DIRECT_WRITE="'"${TG_DIRECT_WRITE:-}"'" \
"'"$SCRIPT_PATH"'" "'"$BOT_ID"'" "'"$USER_IDENTIFIER"'"
'
echo "[Done] $USER_NAME (USER_IDENTIFIER: $USER_IDENTIFIER)"
done
# Clean up credentials
unset TG_BOT_API_KEY
macOS / Linux で root ユーザーにも Guard を設定したい場合は、ラッパースクリプト内でユーザー切り替えをせずにセットアップスクリプトを一度実行してください。
Windows
Windows では、管理ツールがスクリプトを実行する方式に応じて、複数の配信パターンがあります。ここでは、ログオン中のユーザーのみに Guard を設定する方法と、端末上のすべてのユーザーに一括で設定する方法を紹介します。
- ログオン中のユーザーのみに設定する: 管理ツールがそのユーザーの資格情報でスクリプトを実行する形となります。Microsoft Intune の「ログオンした資格情報を使用してこのスクリプトを実行する」オプションや、グループポリシーのログオンスクリプトがこの形にあたります。そのユーザーの WSL(Windows Subsystem for Linux) ディストリビューションへの設定も可能です。
- 端末上のすべてのユーザーに一括で設定する: 管理ツールがスクリプトを
SYSTEM権限で実行する形となります。Microsoft Configuration Manager(旧 SCCM)、グループポリシーのスタートアップスクリプト、PDQ Deploy など、多くの MDM ツールが既定でこの動作です。SYSTEM権限で動かす必要があるため、配信経路は基本的に管理ツール経由となります。
Windows の既定の実行ポリシーでは、署名されていない PowerShell スクリプト(.ps1)の実行が制限されています。そのため、本節で紹介しているラッパースクリプトは、ExecutionPolicy Bypass を指定して実行する必要があります。
Microsoft Intune、Microsoft Configuration Manager、グループポリシーのスタートアップスクリプトなどの主要な管理ツールでは、PowerShell スクリプトを自動的にこの設定で実行するため、追加の設定は不要です。
一方、PsExec などを利用して手動で実行する場合は、次のように起動してください。
powershell.exe -ExecutionPolicy Bypass -File <ラッパースクリプト>.ps1
ログオン中のユーザーのみに設定する
このラッパースクリプトはログオン中 のユーザー自身のセッションで動作し、ユーザーごとの個別トークンを発行したうえで設定します。以下のスクリプトを保存し、管理ツールから各端末へ配信するか、共有ストレージなど別経路で配布のうえ、各端末での実行を依頼してください。
また、Windows ホストに加えて、そのユーザーに登録されている WSL ディストリビューションにも同じトークンで Guard を設定します。ラッパースクリプトは開発用途の WSL を検出し、Docker Desktop などの内部用途のディストリビューションを除いて設定します。
なお、WSL への Guard 設定は、スクリプト冒頭の $ConfigureWsl で有効・無効を切り替えられます。既定値は $true で、$false に設定した場合は Windows ホストにのみ Guard を設定します。WSL への設定の詳細については、こちらも参照してください。
このラッパースクリプトは、Windows ホストおよび各 WSL 環境に対して、それぞれ独立して Guard を設定します。いずれかで設定に失敗しても処理は停止せず、残りの環境への設定を継続します。失敗した環境で行われた変更は自動的にロールバックされ、実行前の状態に戻ります。また、設定済みの他の環境には影響しません。