System Center Configuration Manager(SCCM / ConfigMgr)で、特定のコレクションに配布されたすべてのアプリの配布状態を一括で把握したいのに、レポート画面だけではいまいち追いきれない……。そんなときに便利なのが、ConfigMgrデータベースに直接問い合わせるSQLレポートです。本記事では、公式ビューと関数だけを使って「コレクション×アプリ×状態(成功/進行中/要件不適合/不明/エラー)」を一覧化するクエリと、その考え方を詳しく解説します。
SCCMで「コレクション×アプリの配布ステータス」をSQLで取りにいく意味
SCCMコンソールには「モニタリング > 展開ステータス」や各種レポートが用意されていますが、実運用で次のようなニーズが出てくることが多いです。
- 特定のコレクション(部署・拠点・サーバグループなど)に対して配布されたすべてのアプリの状態を、1つの一覧で確認したい
- 状態を「成功 / 進行中 / 要件不適合 / 不明 / エラー」のようにざっくり区分して、Excelにエクスポートして集計・共有したい
- 既存レポートのビュー名(例:
v_AppDeploymentAssetDetails)が環境に存在せず、Invalid object nameで落ちてしまうので、公式ドキュメントに載っているビューだけを使いたい
こうした要求に対して、Microsoft公式ドキュメントに載っているビューやステータス関数(fn_GetAppState)を組み合わせることで、バージョン差に比較的強い SQL レポートを構築できます。
前提:利用する主なビューと関数の整理
最初に、このテーマでよく使うビュー・関数を整理しておきます。
| 種別 | 名前 | 役割の概要 | 主な結合キー |
|---|---|---|---|
| アプリ配布定義 | v_ApplicationAssignment | アプリの配布(Assignment)1件ごとに、アプリ名・対象コレクション・目的(必須/利用可能)などを保持するビュー。 | AssignmentID、CollectionID |
| 端末ごとの状態 | v_AppIntentAssetData | AssignmentID × アプリ(AppCI)× 端末(MachineID)ごとの ComplianceState / EnforcementState / IsApplicable などを保持。アプリ状態の生データ。 | AssignmentID、MachineID |
| コレクション情報 | v_Collection | コレクション名・CollectionID などを保持。 | CollectionID |
| コレクションメンバー | v_FullCollectionMembership | 全コレクションに属する全リソース(ResourceID)を保持。特定コレクションの端末を絞り込むのに使用。 | CollectionID、ResourceID |
| 端末マスタ | v_R_System | 端末の NetBIOS 名やドメインなど、ResourceID に紐づく情報を保持。 | ResourceID |
| 配布結果(詳細) | vAppDeploymentResultsPerClientMachine | アプリ配布の結果を端末単位でまとめたビュー。AppEnforcementState などを持つ。多くのレポートで使用されている標準ビュー。 | MachineID、AssignmentID |
| 配布結果(サマリ) | v_DeploymentSummary | サイト全体の配布サマリ。アプリ・パッケージ・SU などを FeatureType で識別し、対象数/成功/失敗などの件数を集計。 | AssignmentID、CollectionID |
| 状態変換関数 | dbo.fn_GetAppState | ComplianceState・EnforcementState・IsApplicable などから 1 つの状態コード(1000/2000/…)を返すスカラー関数。他ツールでも実行権限が要求されることが多い。 | 引数で参照(JOINではなく関数呼び出し) |
このあたりのビューは、いずれも ConfigMgr の公式 SQL ビュー一覧や技術ノートに掲載されており、バージョンが変わっても名前が変わりにくいのが特徴です。
コレクション単位で「アプリごとの成功/失敗件数」を集計するSQL
まずは「特定コレクションに対して配布されたアプリごとに、成功 / 進行中 / 要件不適合 / 不明 / エラーの件数を知りたい」というサマリレポートのサンプルからです。
サマリ取得用SQLサンプル
以下のクエリは、コレクション名をパラメータに取り、アプリごとのステータス件数を返します。
DECLARE @CollectionName NVARCHAR(256) = N'<コレクション名>';
WITH TargetRes AS (
SELECT f.ResourceID
FROM v_FullCollectionMembership AS f
INNER JOIN v_Collection AS c
ON c.CollectionID = f.CollectionID
WHERE c.Name = @CollectionName
),
States AS (
SELECT
aa.AssignmentID,
aa.ApplicationName,
-- ※環境によって MachineID / ResourceID など列名が異なる場合あり
dbo.fn_GetAppState(
ad.ComplianceState,
ad.EnforcementState,
aa.OfferTypeID,
1, -- 固定値(ドキュメントどおり)
ad.DesiredState,
ad.IsApplicable
) AS AppState
FROM v_ApplicationAssignment AS aa
INNER JOIN v_AppIntentAssetData AS ad
ON ad.AssignmentID = aa.AssignmentID
INNER JOIN TargetRes AS t
ON t.ResourceID = ad.MachineID -- うまくいかない場合は ad.ResourceID に変更
WHERE aa.CollectionName = @CollectionName
)
SELECT
ApplicationName AS [アプリ名],
SUM(CASE WHEN AppState BETWEEN 1000 AND 1999 THEN 1 ELSE 0 END) AS [成功],
SUM(CASE WHEN AppState BETWEEN 2000 AND 2999 THEN 1 ELSE 0 END) AS [進行中],
SUM(CASE WHEN AppState BETWEEN 3000 AND 3999 THEN 1 ELSE 0 END) AS [要件不適合],
SUM(CASE WHEN AppState BETWEEN 4000 AND 4999 THEN 1 ELSE 0 END) AS [不明],
SUM(CASE WHEN AppState BETWEEN 5000 AND 5999 THEN 1 ELSE 0 END) AS [エラー],
COUNT(*) AS [合計]
FROM States
GROUP BY ApplicationName
ORDER BY [アプリ名];
v_AppIntentAssetData は AssignmentID・AppCI・MachineID ごとにコンプライアンス状態を保持しており、これを fn_GetAppState に渡すことで、「人間が読める 5 区分(成功 / 進行中 / 要件不適合 / 不明 / エラー)」へマッピングできます。
AppState の 1000/2000 番台と意味
fn_GetAppState の返すステータスコードは、一般的に以下のような千番台で区分できます。
| コード範囲 | 意味(日本語) | 代表例 |
|---|---|---|
| 1000–1999 | 成功 | 1000 = Succeeded / Already compliant 系 |
| 2000–2999 | 進行中 | インストール中、再起動待ち、メンテナンスウィンドウ待ちなど |
| 3000–3999 | 要件不適合 | 要件ルールに未達、プラットフォーム非対象など |
| 4000–4999 | 不明 | 状態が判断できないとき |
| 5000–5999 | エラー | 配布失敗・評価失敗・コンテンツ取得失敗など |
細かな意味は AppEnforcementState の定義に依存しますが、多くの技術ノートでも上記 5 区分で集約しており、運用レポートではこのレベルの粒度が扱いやすいことが多いです。
サマリクエリのポイント解説
コレクションメンバーの絞り込み
v_FullCollectionMembership と v_Collection を CTE TargetRes で事前に絞ることで、指定コレクションに所属する ResourceID だけに対象端末を限定しています。これにより、汎用的なビュー(v_AppIntentAssetData)から、特定のコレクションに対する配布結果だけを取り出せます。
MachineID と ResourceID の違いに注意
ConfigMgr のビューによっては、端末キーを MachineID と書いたり ResourceID と書いたりします。
v_FullCollectionMembershipやv_R_SystemはResourceIDv_AppIntentAssetDataやいくつかの App 関連ビューはMachineID
クエリがうまく動かない場合は、以下のようにビューの列を確認し、結合に使っている列名を読み替えてください。
SELECT TOP (10) *
FROM v_AppIntentAssetData;
fn_GetAppState の権限エラー(EXECUTE denied)対策
レポート実行ユーザーに fn_GetAppState の EXECUTE 権限が付与されていないと、EXECUTE permission was denied on object 'fn_GetAppState' のようなエラーになることがあります。この関数はサードパーティ製ツールでも明示的に EXECUTE 権限が必要とされており、ConfigMgr DB 上でも同様に扱われます。
DBA に依頼して、対象データベースに対して次のような権限を付与してもらうとよいでしょう(例)。
GRANT EXECUTE ON dbo.fn_GetAppState TO <レポート実行アカウント>;
コレクション × アプリ × 端末の「生の配布結果」を取得するSQL
次に、「どの端末でどのアプリがどういう状態になっているのか」を 1 行ずつ表示する詳細レポートの例です。ここでは、vAppDeploymentResultsPerClientMachine を使います。
詳細用SQLサンプル(端末単位)
DECLARE @CollectionName NVARCHAR(256) = N'<コレクション名>';
WITH TargetRes AS (
SELECT f.ResourceID
FROM v_FullCollectionMembership AS f
INNER JOIN v_Collection AS c
ON c.CollectionID = f.CollectionID
WHERE c.Name = @CollectionName
)
SELECT
aa.ApplicationName AS [アプリ名],
s.Netbios_Name0 AS [端末名],
vAD.Descript AS [デプロイ種別名],
vAD.AppEnforcementState AS [状態コード],
CASE
WHEN vAD.AppEnforcementState BETWEEN 1000 AND 1999 THEN N'成功'
WHEN vAD.AppEnforcementState BETWEEN 2000 AND 2999 THEN N'進行中'
WHEN vAD.AppEnforcementState BETWEEN 3000 AND 3999 THEN N'要件不適合'
WHEN vAD.AppEnforcementState BETWEEN 4000 AND 4999 THEN N'不明'
WHEN vAD.AppEnforcementState BETWEEN 5000 AND 5999 THEN N'エラー'
ELSE N'未定義'
END AS [状態],
ccs.LastComplianceMessageTime AS [最終状態日時]
FROM vAppDeploymentResultsPerClientMachine AS vAD
INNER JOIN v_R_System AS s
ON s.ResourceID = vAD.MachineID -- 環境により vAD.ResourceID の場合もあり
INNER JOIN v_ApplicationAssignment AS aa
ON aa.AssignmentID = vAD.AssignmentID
LEFT JOIN v_CICurrentComplianceStatus AS ccs
ON ccs.CI_ID = vAD.CI_ID
AND ccs.ResourceID = vAD.MachineID
WHERE vAD.MachineID IN (SELECT ResourceID FROM TargetRes)
ORDER BY [アプリ名], [端末名];
vAppDeploymentResultsPerClientMachine および関連ビューは、公式の SQL ビュー一覧にも掲載されており、多くのブログやサンプルレポートで配布結果抽出のベースとして使われています。
AppEnforcementState のざっくりとした読み方
AppEnforcementState は個別の数値ごとに細かな意味がありますが、レポートでは先ほどの 5 区分にまとめてしまうのが現実的です。細かい意味を知りたいときは、代表的な技術ブログの一覧が参考になります。
| 代表コード | 意味 | 区分 |
|---|---|---|
| 1000 | 成功(インストール済み / 要件を満たしている) | 成功 |
| 2000 | In Progress(実行中) | 進行中 |
| 3000 | Requirements not met(要件不適合) | 要件不適合 |
| 4000 | Unknown(状態不明) | 不明 |
| 5000 | Deployment failed(配布失敗) | エラー |
詳細レベルで見ると「2001 = Waiting for Content」「2004 = Waiting for maintenance window」など多数ありますが、運用報告ではまず 5 区分で全体感をつかみ、必要に応じて個別端末の AppEnforcementState を掘る、という運用がおすすめです。
ユーザーコレクション配布を出したい場合
ユーザーコレクションに対する配布は、端末ではなくユーザーリソースに紐づくため、次のようにビューを差し替えます。
v_R_System→v_R_UservAppDeploymentResultsPerClientMachine→vAppDeploymentResultsPerClientUser
JOIN のキーは同様に ResourceID(ユーザーの ResourceID)になります。
v_AppDeploymentAssetDetails が「Invalid object name」になる理由と対処
Microsoft Q&A などのサンプルで、次のようなクエリを見かけた方も多いと思います。
v_AppDeploymentAssetDetailsを JOIN している- 自分の環境で実行すると
Invalid object name 'v_AppDeploymentAssetDetails'と怒られる
これは、ConfigMgr のバージョンやスキーマにより、ビュー名が次のように揺れていることが主な原因です。
v_AppDeploymentAssetDetails(先頭がv_)と書かれた記事- 実際のビュー名は
vAppDeploymentAssetDetails(アンダースコアなし)である環境が多い
実際、ConfigMgr のセットアップログには「vAppDeploymentAssetDetails が見つからなければ作成する」という記録が残っており、ビューの正式名は vAppDeploymentAssetDetails であることが分かります。
手元の環境でビュー名を確認する手順
既存のサンプルをそのまま使うのではなく、まずは次のようなクエリで該当ビューが存在するかを確認しましょう。
-- AppDeployment 関連ビューをざっと確認
SELECT name
FROM sys.views
WHERE name LIKE 'v%AppDeployment%AssetDetails%'
ORDER BY name;
ここで vAppDeploymentAssetDetails が見つかる場合は、サンプルクエリ中の v_AppDeploymentAssetDetails を置き換えれば動く可能性が高いです。
一方、vAppDeploymentAssetDetails 自体が存在しない場合もあります。その場合は、本記事で紹介したように、より汎用的なビュー(v_AppIntentAssetData / vAppDeploymentResultsPerClientMachine / v_DeploymentSummary など)を組み合わせるパターンに切り替えた方が安定します。
サマリだけでよい場合のシンプルなクエリ(v_DeploymentSummary)
「端末ごとの詳細は不要で、とにかく配布全体の成功率やエラー件数だけ知りたい」というケースでは、v_DeploymentSummary を使うと手早く集計できます。
特定コレクションに対するアプリ配布サマリ
DECLARE @CollectionName NVARCHAR(256) = N'<コレクション名>';
SELECT
Ds.SoftwareName AS [アプリ名],
Ds.CollectionName AS [コレクション名],
Ds.NumberTotal AS [対象台数],
Ds.NumberSuccess AS [成功],
Ds.NumberInProgress AS [進行中],
Ds.NumberErrors AS [エラー],
Ds.NumberOther AS [要件不適合など],
Ds.NumberUnknown AS [不明],
CASE
WHEN Ds.NumberTotal IS NULL OR Ds.NumberTotal = 0 THEN 0
ELSE CAST(Ds.NumberSuccess AS FLOAT) / Ds.NumberTotal * 100
END AS [成功率%]
FROM v_DeploymentSummary AS Ds
WHERE Ds.FeatureType = 1 -- 1 = Application
AND Ds.CollectionName = @CollectionName
ORDER BY Ds.SoftwareName;
ここではアプリ配布を示す FeatureType = 1 を指定しています。他の値(2 = Program, 5 = Software Update など)は、ConfigMgr の WMI クラス SMS_DeploymentSummary の仕様に準拠しています。
このクエリは、端末ごとの詳細には踏み込みませんが、コレクション単位で「成功率が 90% を切っている配布はどれか」といった俯瞰に向いています。
クエリを環境に合わせてチューニングするポイント
実際に自分の環境へ持ち込む際にチェックしておきたいポイントをまとめます。
1. 列名・キー名の差異を確認する
- MachineID / ResourceID / DeviceID など、端末キーの列名がビューによって異なる場合があります。
- 特に、
v_AppIntentAssetDataやvAppDeploymentResultsPerClientMachineはMachineIDを持ち、v_R_SystemはResourceIDなので、JOIN 時に対応付けを意識してください。
最初は SELECT TOP 1 * で列名を確認してからクエリを書き換えると、エラーを減らせます。
2. コレクションの指定方法(Name vs ID)
サンプルでは分かりやすさを優先し、@CollectionName でコレクション名を指定しましたが、本番環境では CollectionID(例:SMS00001)で絞る方が安全な場合があります。
DECLARE @CollectionID NVARCHAR(16) = N'SMS00001';
WITH TargetRes AS (
SELECT ResourceID
FROM v_FullCollectionMembership
WHERE CollectionID = @CollectionID
)
...
コレクション名は運用中に変更されることがあるのに対し、CollectionID は基本的に変わらないためです。
3. パフォーマンス対策
- 大規模環境で全コレクション・全アプリを対象にすると、数百万行単位で走査が発生します。
- 必ず WHERE 句でコレクションやアプリを絞る、期間を限定する(最終状態日時が最近 N 日以内、など)といった制限をかけましょう。
- 必要に応じて、一時テーブルやインデックス付きビューを使うことで、SSRS レポートの応答時間を短縮できます。
実運用での活用アイデア
定期レポート(週報・月報)としての利用
v_DeploymentSummaryベースのサマリクエリを SSRS レポートにし、週次でメール配信すると「アプリ配布の健全性」を定点観測できます。- コレクションを部署・拠点単位に分けておけば、「今週はどの拠点でエラーが多いか」といった管理がしやすくなります。
トラブルシューティングの初動としての利用
- あるアプリが「インストールされていない気がする」と言われたら、まずコレクションを絞って詳細クエリ(
vAppDeploymentResultsPerClientMachine)を実行し、「エラーが多いのか、要件不適合が多いのか」を切り分けます。 - 要件不適合が多いなら、要件ルール(OS バージョンやメモリ条件など)の見直し、エラーが多いなら AppEnforcementState を確認し、コンテンツ配布や権限問題などを疑う、といった流れが作れます。
PS / PowerBI との組み合わせ
- SQL クエリをそのまま PowerBI のデータソースにすると、GUI ベースでフィルタ・可視化を簡単に追加できます。
- PowerShell から SQL を叩いて CSV に吐き出し、チーム内共有フォルダに定期保存する、といった自動化も実務ではよく行われます。
まとめ:公式ビュー+fn_GetAppStateで「壊れにくい」レポートを
本記事では、SCCM / ConfigMgr のコレクションに対するアプリ配布ステータスを SQL で一覧取得する方法として、次の 3 パターンを紹介しました。
- コレクション × アプリのサマリ:
v_AppIntentAssetData+v_ApplicationAssignment+v_FullCollectionMembership+fn_GetAppState - コレクション × アプリ × 端末の詳細:
vAppDeploymentResultsPerClientMachine+v_R_System+v_ApplicationAssignment - ざっくりサマリだけ欲しい場合:
v_DeploymentSummary(FeatureType = 1)
v_AppDeploymentAssetDetails を前提にしたサンプルが環境に合わず悩んでいる場合でも、ここで紹介したように公式ビューと関数を素直に組み合わせることで、バージョン差に強く、メンテナンスしやすいレポートを作成できます。
まずは紹介したサンプルクエリをテスト環境で実行し、自社環境の列名やビュー構成に合わせて微調整してみてください。それだけで、日々のアプリ配布状況の可視性が大きく向上するはずです。

コメント