Jamf Pro の Blueprints 適用状況を確認する方法
はじめに
立神です。今回は Jamf Pro の Blueprints で展開した、個々の Blueprint の宣言状態を確認する方法について紹介します。
宣言型デバイス管理を活用するうえで、展開後の確認方法のひとつとして参考になればと思います。
今回は以下の環境で実行しています。
- Jamf Pro バージョン:11.32.0
- API 実行環境:macOS のターミナル(zsh)
- 使用するコマンド:curl、jq
宣言型デバイス管理とは
デバイス管理を行う目的のひとつに、「デバイスをあるべき状態にする」ということが挙げられます。
従来の命令型デバイス管理では、その状態にするために必要なコマンドを送っていました。
対して、宣言型デバイス管理では、あるべき状態をデバイスに伝え、デバイス自身がその状態になるように動作します。
今回は、この宣言に対して端末が報告した状態を確認します。
宣言型デバイス管理は英語で Declarative Device Management といい、以下 DDM と表します。
Blueprints とは
Jamf Pro の Blueprints は、宣言型デバイス管理を活用する機能です。
コンポーネントライブラリから適用したい設定を選択し、対象端末に展開できます。
今回は、macOS のメジャー OS アップデートの表示を、リリース日から 90 日間延期する設定を例に確認します。この設定は、メジャー OS アップデートを恒久的に禁止するものではありません。


設定の展開は、グループを用いて行います。あらかじめ設定を適用させたい端末を整理しておきましょう。
スマートグループとスタティックグループ、どちらも使用可能です。
グループについては下記で説明しているので、参考にしてみてください。
スコープから一時的に除外するなどの設定もありますが、今回は詳しい設定内容や活用方法は省きます。
最後に、展開ボタンをクリックして、スコープに設定した端末へ配布します。

対象端末では、次のように宣言の設定内容を確認できます。


適用状況の確認
Blueprint を展開すると、コンソール上のステータスが更新されます。
今回確認した環境では、この画面からどの端末に適用されたのかまで確認することはできませんでした。

ここからは API を使って、対象の端末が報告した状態を確認していきます。
API ロールとクライアントの設定
今回の検証で使用した権限は次のとおりです。
- Read Computers
- Read Smart Computer Groups
API の使い方やアクセストークンの取得方法は、こちらで説明しています。
以降は、Jamf Pro の URL を $JAMF_URL、アクセストークンを $T に入れた状態で進めます。
$JAMF_URL には、末尾の / を含めずに URL を設定してください。
また、取得した JSON の整形や、必要な項目の抽出には jq を使用します。
実行環境には、あらかじめ jq を用意してください。
Blueprint ID を確認する
対象の Blueprint を開き、ページの URL から Blueprint ID を確認します。
例えば、URL が次のようになっている場合です。
https://<Jamf Pro のホスト名>/view/mfe/blueprints/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
末尾の xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx が Blueprint ID です。
この後、取得した情報から対象の Blueprint の宣言を取り出す際に使用するので、控えておきます。
今回確認する内容
今回は、端末が報告した DDM のステータスから、対象の Blueprint に関係する宣言を確認します。
確認するのは、宣言の識別子である identifier と、状態を表す active、valid です。
対象の Blueprint ID を含む宣言を探し、宣言が有効になっているか、端末が正しく解釈できているかを確認します。
まずは 1 台分の情報を取得して、出力の見方を確認します。
その後、同じ処理をスコープに設定したスマートコンピュータグループの各端末に対して行います。
なお、ここで確認するのは宣言の状態です。設定の実際の動作まで確認するものではありません。
端末が報告した情報を取得する
DDM のステータスを取得するには、端末の managementId が必要です。
まず、端末の ID を指定して、インベントリ情報から取得します。
端末の ID は、端末詳細画面の URL 末尾の数字から確認できます。
curl -fsS "$JAMF_URL/api/v1/computers-inventory/<端末 ID>" \
-H "Authorization: Bearer $T" \
| jq -r '.general.managementId'
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
返ってきた値が、この端末の managementId です。
続いて、この値を指定して DDM のステータスを取得します。
curl -fsS "$JAMF_URL/api/v1/ddm/<managementId>/status-items" \
-H "Authorization: Bearer $T" \
| jq .
statusItems に、端末が報告した状態が返ってきます。
今回の環境では、43 項目ありました。
{
"statusItems": [
{
"key": "device.model.family",
"value": "Mac",
"lastUpdateTime": "2026-10-07T23:51:21.059"
}
]
}
※ 出力の一部を抜粋しています。以降の ID などの値はダミーです。
この中で確認するのは、management.declarations. で始まる項目です。
今回の環境では、次の 2 つの項目に対象の Blueprint の宣言が含まれていました。
| キー | 内容 |
|---|---|
management.declarations.activations |
構成を有効にするためのアクティベーションの宣言 |
management.declarations.configurations |
端末に適用する設定内容を定義した構成の宣言 |
実際の出力を抜粋すると、次のようになっています。
{
"key": "management.declarations.configurations",
"value": "{active=true, identifier=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, valid=valid, server-token=},{active=true, identifier=Blueprint_<Blueprint ID>_s1_c1_sys_cfg1, valid=valid, server-token=}",
"lastUpdateTime": "2026-10-07T23:51:21.066"
}
今回の検証環境では、対象の Blueprint に関係する宣言の identifier が、Blueprint_<Blueprint ID>_ で始まっていました。
また、複数の宣言が },{ で連結された文字列として返されたため、この区切りで分割して抽出しています。識別子の形式や value の表現が異なる場合は、抽出処理の調整が必要です。
ただ、このままではほかの宣言も並んでいるため、対象の Blueprint だけに絞って表示します。
対象の Blueprint の宣言を取り出す
今回の出力では、value は JSON ではなく文字列として返ってきています。
そのため、},{ の区切りで分割し、対象の Blueprint ID を含む宣言を取り出します。
ここでは、先ほど確認したアクティベーションと構成の 2 項目を対象にします。
curl -fsS "$JAMF_URL/api/v1/ddm/<managementId>/status-items" \
-H "Authorization: Bearer $T" \
| jq -r --arg bp "identifier=Blueprint_<Blueprint ID>_" '
.statusItems[]
| select(
.key == "management.declarations.activations"
or .key == "management.declarations.configurations"
)
| .key as $key
| .lastUpdateTime as $time
| (.value | split("},{")[])
| select(contains($bp))
| "\($key)\t\($time)\t\(.)"'
management.declarations.activations 2026-10-07T23:51:21.066 active=true, identifier=Blueprint_<Blueprint ID>_s1_c1_sys_act1, valid=valid, server-token=}
management.declarations.configurations 2026-10-07T23:51:21.066 active=true, identifier=Blueprint_<Blueprint ID>_s1_c1_sys_cfg1, valid=valid, server-token=}
項目名、更新日時、対象の Blueprint の宣言が順に表示されます。
今回の出力では、アクティベーションと構成の両方で active=true、valid=valid となっていました。
| 値 | 読み取れる状態 |
|---|---|
active=true |
宣言が端末上で有効になっている |
valid=valid |
端末が宣言を正しく解釈できている |
この結果から、対象の宣言が端末上で有効になっていることを確認できます。
設定の実際の動作を確認する場合は、端末側での確認も必要です。
グループ内の端末をまとめて確認する
ここまでで、1 台分の確認ができました。
次に、スコープに設定したスマートコンピュータグループ内の端末をまとめて確認します。
コンソールでグループの詳細画面を開き、URL の id= に続く数字をグループ ID として控えておきます。
この ID を指定して、グループに属する端末の ID を取得します。
curl -fsS "$JAMF_URL/api/v2/computer-groups/smart-group-membership/<グループ ID>" \
-H "Authorization: Bearer $T" \
| jq .
{
"members": [
101,
102,
103
]
}
※ 出力例の ID と台数は省略・置き換えています。
members に、グループに属する端末の ID が入っています。
この ID を順に取り出して、先ほどの処理を繰り返します。
各端末の managementId を取得し、その端末のステータスから対象の Blueprint の宣言を取り出す流れです。
まず、確認する Blueprint ID とグループ ID を変数に入れます。
BP_ID='<Blueprint ID>'
GROUP_ID='<グループ ID>'
続いて、グループ内の端末を順に処理します。
以下のコードは、macOS のターミナル(zsh)に貼り付けて実行します。
端末ごとに、端末 ID と対象の Blueprint の宣言を表示します。
if group_response=$(curl -fsS \
"$JAMF_URL/api/v2/computer-groups/smart-group-membership/$GROUP_ID" \
-H "Authorization: Bearer $T") \
&& ids=$(printf '%s' "$group_response" | jq -er '
.members
| if type == "array" then map(tostring) | join("\n")
else error("members が配列ではありません")
end'); then
while IFS= read -r id; do
[ -z "$id" ] && continue
printf '\n端末 ID: %s\n' "$id"
if ! inv=$(curl -fsS \
"$JAMF_URL/api/v1/computers-inventory/$id" \
-H "Authorization: Bearer $T"); then
printf 'インベントリ情報の取得に失敗しました。\n'
continue
fi
if ! mid=$(printf '%s' "$inv" | jq -er '
.general.managementId
| select(type == "string" and length > 0)'); then
printf 'managementId を取得できませんでした。\n'
continue
fi
if ! ddm_response=$(curl -fsS \
"$JAMF_URL/api/v1/ddm/$mid/status-items" \
-H "Authorization: Bearer $T"); then
printf 'DDM ステータスの取得に失敗しました。\n'
continue
fi
if ! declarations=$(printf '%s' "$ddm_response" \
| jq -r --arg bp "identifier=Blueprint_${BP_ID}_" '
.statusItems[]
| select(
.key == "management.declarations.activations"
or .key == "management.declarations.configurations"
)
| .key as $key
| .lastUpdateTime as $time
| (.value | split("},{")[])
| select(contains($bp))
| "\($key)\t\($time)\t\(.)"'); then
printf '宣言の抽出に失敗しました。\n'
continue
fi
if [ -n "$declarations" ]; then
printf '%s\n' "$declarations"
else
printf '対象の Blueprint の宣言は見つかりませんでした。\n'
fi
done <<< "$ids"
else
printf 'グループ情報の取得、または端末 ID の抽出に失敗しました。\n'
fi
処理の内容は、1 台分の確認と同じです。
端末 ID を 1 件ずつ読み取り、managementId の取得、DDM ステータスの取得、対象の宣言の抽出を繰り返しています。
途中で情報を取得できなかった端末は、その旨を表示して次の端末へ進みます。
出力は、次のような形になります。
端末 ID: 101
management.declarations.activations 2026-10-07T23:51:21.066 active=true, identifier=Blueprint_<Blueprint ID>_s1_c1_sys_act1, valid=valid, server-token=}
management.declarations.configurations 2026-10-07T23:51:21.066 active=true, identifier=Blueprint_<Blueprint ID>_s1_c1_sys_cfg1, valid=valid, server-token=}
端末 ID: 102
management.declarations.activations 2026-10-07T23:51:21.066 active=true, identifier=Blueprint_<Blueprint ID>_s1_c1_sys_act1, valid=valid, server-token=}
management.declarations.configurations 2026-10-07T23:51:21.066 active=true, identifier=Blueprint_<Blueprint ID>_s1_c1_sys_cfg1, valid=valid, server-token=}
端末 ID: 103
対象の Blueprint の宣言は見つかりませんでした。
※ 出力形式の例です。ID などの値はダミーです。
端末 ID ごとに、対象の Blueprint の宣言と、その宣言を含むステータス項目の lastUpdateTime が表示されます。これは、宣言ごとの適用完了日時を示すものではありません。
先ほどと同じように、アクティベーションと構成の active、valid を確認します。
これで、指定したグループの各端末について、対象の Blueprint に関係する宣言の状態をまとめて確認できます。
確認するときの注意点
今回取得しているのは、端末が報告した状態です。
Jamf Pro が配布を指示した内容そのものではありません。
また、lastUpdateTime もあわせて確認するとより効果的です。
Blueprint を更新・再展開する前の日時であれば、以前の状態が残っている可能性があります。
対象の宣言が見つからない場合も、その結果だけで未適用とは断定せず、端末の通信状況や報告のタイミングを含めて確認する必要があります。
今回の処理対象は、指定したスマートコンピュータグループに現在所属している端末です。
Blueprint 側の除外設定や、ほかのグループを含むスコープ全体を取得しているわけではありません。
まとめ
今回は、API を使って Blueprint に関係する宣言を取得してみました。
グループから端末の ID を取得し、各端末の DDM ステータスを確認することで、対象の Blueprint に対して端末が報告した状態をまとめて確認できます。
Blueprint を展開した後の確認方法のひとつとして、参考になればと思います。
参考資料
宣言型デバイス管理とAppleデバイスの概要 - Apple サポート (日本)
StatusManagementDeclarationsDeclarationObject - Apple Developer Documentation






