Microsoft IntuneでWin32アプリを配布した際、「端末にはアプリが入っているのに失敗と表示される」「同じインストーラーが繰り返し実行される」という問題が起きることがあります。
この症状で最初に確認すべきなのは、インストールコマンドではなく**検出規則(Detection rules)**です。Intuneは、画面上のアプリ名やスタートメニューへの登録状況ではなく、設定された検出規則を使ってアプリの存在を判断します。
特に注意したいのが、手動の検出規則を複数設定した場合です。複数の規則は「いずれかを満たせばよい」のではなく、すべての規則を満たす必要があります。1つでも不成立なら、アプリが実際に利用できる状態でも未検出になる可能性があります。([Microsoft Learn][1])
この記事では、MSI、ファイル、レジストリ、カスタムスクリプトの順に、確認すべき項目と安全な再テスト方法を解説します。
Intuneでインストール済みアプリが未検出になる仕組み
Win32アプリの配布では、次の処理を分けて考える必要があります。
- インストールコマンドを実行する
- インストーラーがファイルやレジストリを書き込む
- Intuneが検出規則を評価する
- 規則が成立すれば「インストール済み」と判断する
つまり、インストーラーが正常終了しても、検出規則が実際の導入状態と一致していなければ、Intuneはアプリが存在すると判断できません。
必須として割り当てたアプリが端末上に存在しないと判定された場合、Intuneはおおむね24時間以内にアプリを再度提供します。これは必須割り当てのアプリに対する動作であり、すべての配布失敗が無期限に再実行されるという意味ではありません。([Microsoft Learn][1])
インストール結果と検出結果は別々に確認する
トラブル対応では、「インストーラーが成功したか」と「検出規則が成立したか」を同じ結果として扱わないことが重要です。
| 確認項目 | 確認する内容 |
|---|---|
| インストール実行結果 | インストールコマンドが実行されたか、終了コードは何か |
| 実際の導入状態 | アプリ本体、ファイル、レジストリ、バージョンが存在するか |
| 検出結果 | 設定した検出規則がすべて成立しているか |
| Intune上の状態 | 成功、失敗、保留、未検出のどれになっているか |
「アプリが起動できるからインストールは成功している」という確認だけでは不十分です。Intuneが確認している条件を、同じパス、同じ値、同じ32ビット・64ビット条件で照合する必要があります。
最初にDetection rulesの種類を確認する
対象のWin32アプリを開き、プロパティに設定されている検出規則を確認します。
検出方法は、大きく次の2つです。
- 手動で検出規則を構成する
- カスタム検出スクリプトを使用する
手動規則では、MSI、ファイル、レジストリを利用できます。検出規則は少なくとも1つ必要です。また、手動規則を複数追加している場合は、すべての条件が成立しなければアプリは検出されません。([Microsoft Learn][1])
たとえば、次の3つを登録しているとします。
- MSIの製品コードが一致する
- 指定した実行ファイルが存在する
- 指定したレジストリ値が存在する
この場合、MSIとファイルの条件が成立していても、レジストリ値が削除されていれば未検出です。複数規則はOR条件ではなく、実質的にAND条件として確認します。
MSI検出規則を確認する
MSI規則では、主に次の項目を確認します。
- MSI製品コード
- MSI製品バージョンの確認を有効にしているか
- 実際にインストールされた製品コードと一致しているか
- 更新後のバージョンが設定条件を満たしているか
IntuneのMSI検出規則は、MSI製品コードを基準にアプリを確認します。製品バージョンの確認を有効にした場合は、製品コードに加えてバージョンも照合対象になります。MSI規則は1つだけ追加できます。([Microsoft Learn][1])
MSI規則で起きやすい不一致
よくあるのは、登録時に取得した製品コードと、実際に配布したインストーラーの製品コードが異なるケースです。
アプリ名が同じでも、次のような変更によって識別情報が変わる可能性があります。
- 配布パッケージを新しい版へ差し替えた
- 32ビット版から64ビット版へ変更した
- ベンダーが異なるMSIパッケージを提供した
- メジャーバージョンアップを行った
確認すべきなのは、コントロールパネルなどに表示されるアプリ名ではありません。検出規則に設定した製品コードと、端末へ実際に導入されたMSIの製品コードが一致しているかを確認します。
バージョン確認を使う場合の注意点
バージョンを確認する設定は、目的の版が導入されていることを判定したい場合に有効です。ただし、アプリ自身の自動更新によってIntuneで設定した条件と一致しなくなると、導入済みでも未検出になる可能性があります。
更新方法が複数あるアプリでは、次の方針を事前に決めておくと管理しやすくなります。
- Intuneだけで更新する
- アプリ自身の自動更新を許可する
- 製品コードだけを確認する
- 製品コードとバージョンの両方を確認する
厳密な版管理が必要ならバージョンも確認し、自動更新を許可するなら、更新後も成立する検出方法になっているかを確認します。
ファイル検出規則を確認する
ファイル規則では、ファイルやフォルダーの存在だけでなく、日付、バージョン、サイズなどを使って判定できます。設定項目には、パス、ファイルまたはフォルダー名、検出方法、64ビットOS上の32ビットアプリとして扱うかどうかが含まれます。([Microsoft Learn][1])
確認する項目は次のとおりです。
| 項目 | 確認内容 |
|---|---|
| パス | 実際のインストール先と完全に一致しているか |
| ファイルまたはフォルダー | 名前、拡張子、スペルが正しいか |
| 検出方法 | 存在、日付、バージョン、サイズのどれか |
| 比較する値 | 実際のファイル情報と一致しているか |
| 32ビット設定 | 環境変数が意図した場所へ展開されるか |
端末上のファイルをPowerShellで確認する例
次のコマンドは説明用の例です。実際のパスは対象アプリに置き換えてください。
Test-Path 'C:\Program Files\Contoso\App\ContosoApp.exe'
ファイルが存在する場合は、バージョンも確認できます。
(Get-Item 'C:\Program Files\Contoso\App\ContosoApp.exe').VersionInfo |
Select-Object FileVersion, ProductVersion
Intuneでファイルバージョンを判定している場合は、エクスプローラー上でファイルが見えるかだけでなく、検出規則が比較しているバージョン情報を確認します。
「ファイルが存在する」だけでは目的の版を証明できない
ファイルの存在確認は設定しやすい一方、古い版のファイルやアンインストール後に残ったファイルでも条件が成立することがあります。
たとえば、次のような状況です。
- 旧バージョンの実行ファイルが残っている
- アンインストール後も設定ファイルだけが残っている
- 別製品が同名のフォルダーを作成している
- 更新処理で実行ファイル名や保存先が変わった
バージョンを管理する必要があるアプリでは、単純な存在確認ではなく、実行ファイルのバージョンやアプリ固有のレジストリ値を使う方法も検討します。
レジストリ検出規則を確認する
レジストリ規則では、キーや値の存在、文字列、整数、バージョンなどを使ってアプリを検出できます。値の名前を空欄にした場合はキー自体が検出対象になります。64ビットOSでは、32ビット側と64ビット側のどちらを検索するかも指定します。([Microsoft Learn][1])
確認項目は次のとおりです。
- キーパスが正しいか
- 値の名前が正しいか
- キーの存在と値の存在を取り違えていないか
- 検出方法が実際のデータ型と合っているか
- 32ビット側と64ビット側のどちらに値があるか
- アプリ更新後も同じキーや値が作成されるか
32ビット側と64ビット側を比較する例
reg.exeを使うと、32ビットと64ビットのレジストリビューを分けて確認できます。
reg query "HKLM\SOFTWARE\Contoso\App" /reg:32
reg query "HKLM\SOFTWARE\Contoso\App" /reg:64
32ビット側では値が見つかるのに、64ビット側では見つからない場合、Intuneの「64ビットクライアント上の32ビットアプリに関連付ける」設定が実態と合っていない可能性があります。
キーの存在と値の存在を区別する
次の2つは別の条件です。
HKLM\SOFTWARE\Contoso\Appというキーが存在する- そのキー内に
Versionという値が存在する
値の名前を指定している場合、キーだけが存在しても条件は成立しません。逆に、キーの存在だけを確認したいのに値名を設定すると、不要な不一致を生むことがあります。
カスタム検出スクリプトを確認する
標準のMSI、ファイル、レジストリ規則だけでは判定できない場合は、PowerShellによるカスタム検出スクリプトを使用できます。
カスタム検出スクリプトでアプリを「インストール済み」と判定させるには、次の両方が必要です。
- 終了コードが
0 - 標準出力のSTDOUTに文字列データが出力される
終了コードが0でもSTDOUTにデータがなければ、インストール済みとは判定されません。また、STDERRにデータが書き込まれた場合は、終了コードが0でSTDOUTにデータがあっても未インストールとして評価されます。MicrosoftはスクリプトをUTF-8 BOMで保存することも推奨しています。([Microsoft Learn][1])
正常に検出するスクリプト例
$appPath = 'C:\Program Files\Contoso\App\ContosoApp.exe'
if (Test-Path $appPath) {
Write-Output 'Detected'
exit 0
}
exit 1
この例では、ファイルが存在するときにSTDOUTへDetectedを出力し、終了コード0を返します。
検出に失敗しやすい書き方
次のスクリプトは、終了コードが0でもSTDOUTへ何も出力しないため、期待どおりに検出されない可能性があります。
if (Test-Path 'C:\Program Files\Contoso\App\ContosoApp.exe') {
exit 0
}
exit 1
また、エラー情報や診断メッセージをSTDERRへ書き込む実装にも注意が必要です。
Write-Error 'Diagnostic message'
Write-Output 'Detected'
exit 0
検出スクリプトでは、通常のログ出力、警告、エラー出力を安易に混在させず、Intuneが評価する終了コード、STDOUT、STDERRを意識して設計します。
64ビットOS上の32ビットアプリ判定を確認する
64ビットWindowsで32ビットアプリを配布している場合、検出先の違いが未検出の原因になりやすくなります。
Intuneでは、規則の種類によって32ビット設定の意味が異なります。
| 規則 | 32ビット設定の影響 |
|---|---|
| ファイル | パス内の環境変数を32ビットコンテキストで展開する |
| レジストリ | 64ビットOS上の32ビットレジストリを検索する |
| スクリプト | PowerShellスクリプトを32ビットプロセスとして実行する |
ファイル規則で「はい」を選ぶと、64ビット端末上でパスの環境変数が32ビットコンテキストとして展開されます。「いいえ」では64ビットコンテキストが使われます。レジストリ規則では、「はい」にすると32ビット側のレジストリが検索されます。カスタムスクリプトにも、64ビット端末上で32ビットプロセスとして実行する設定があります。([Microsoft Learn][1])
32ビット設定はアプリ名ではなく実際の保存先で決める
「このアプリは昔からあるので32ビットだろう」と推測して設定するのは危険です。次の3点を端末上で確認してから決めます。
- 実行ファイルが実際に保存されている場所
- レジストリ値が32ビット側と64ビット側のどちらにあるか
- 検出スクリプトが参照しているPowerShell、環境変数、レジストリビュー
同じ製品でも、インストーラーの種類やバージョンによって保存先が変わる場合があります。設定値ではなく、対象端末の実態と照合することが重要です。
検出規則を安全に修正して再テストする手順
検出規則を修正するときは、本番端末へ一括反映する前にテスト対象で評価します。
現在の設定を記録する
変更前に、少なくとも次の内容を記録します。
- 規則の形式
- MSI製品コード
- ファイルのパスとファイル名
- レジストリのキーパスと値名
- 検出方法と比較値
- 32ビット関連の設定
- カスタムスクリプトの内容
- 対象アプリの割り当て方式
設定を記録せずに複数箇所を変更すると、どの修正が有効だったのか判断できなくなります。
影響を受けている端末で実際の状態を確認する
検出規則に設定されている条件を、端末上で1つずつ確認します。
複数の手動規則がある場合は、次のように個別に記録します。
| 検出条件 | 端末上の結果 | 判定 |
|---|---|---|
| MSI製品コード | 設定値と一致 | 成立 |
| 実行ファイル | 指定パスに存在 | 成立 |
| ファイルバージョン | 設定値より古い | 不成立 |
| レジストリ値 | 64ビット側には存在しない | 不成立 |
1つでも不成立なら、複数の手動規則全体としては未検出です。
インストール結果と検出結果を分けて記録する
再テスト時には、次のような記録表を使うと原因を追いやすくなります。
| 時刻 | インストール実行 | 終了結果 | 実際の導入状態 | 検出規則 | Intune表示 |
|---|---|---|---|---|---|
| 10:00 | 実行あり | 成功 | アプリ起動可能 | ファイル版が不一致 | 失敗 |
| 11:00 | 規則修正後 | 実行なし | 導入済み | すべて成立 | 成功 |
このように記録すると、インストーラーを修正すべき問題なのか、検出規則だけを修正すべき問題なのかを切り分けられます。
変更はテスト対象へ限定する
本番で利用中のWin32アプリの検出規則を直接変更すると、既存の対象端末にも影響する可能性があります。
安全に進めるには、次の順序が適しています。
- テスト端末上で現在の規則を再現する
- 不成立になっている条件を特定する
- 修正案を1つずつ検証する
- パイロット対象でIntuneから再評価する
- 成功を確認してから対象を広げる
複数の規則、インストールコマンド、割り当て、依存関係を同時に変更しないことが重要です。
よくある失敗と修正方法
複数の検出規則をOR条件だと思っている
MSI、ファイル、レジストリをすべて登録しておけば確実だと考えがちですが、規則を増やすほど成立させる条件も増えます。
3つのうち1つが成立すればよい設計にしたい場合、手動規則を3つ並べる方法では意図どおりになりません。必要に応じて、複数条件を判断するカスタムスクリプトにまとめます。
ファイルの存在だけを確認している
ファイルが存在しても、目的のバージョンとは限りません。更新管理を目的とする場合は、実行ファイルのバージョンやレジストリ内のバージョン情報を利用します。
MSIの表示名だけを確認している
Windows上で同じアプリ名が表示されていても、Intuneが確認する製品コードと一致しているとは限りません。表示名ではなく、検出規則に登録した識別情報を確認します。
32ビット設定を推測で切り替えている
32ビット設定を変更すると、ファイル、レジストリ、スクリプトの参照先や実行環境が変わります。「はい」と「いいえ」を試行錯誤するのではなく、端末上で実際の保存先を確認してから設定します。
検出スクリプトが終了コードしか返していない
カスタム検出スクリプトでは、終了コード0だけでなくSTDOUTへの出力も必要です。正常時には、空ではない文字列を明示的に出力します。([Microsoft Learn][1])
診断メッセージをSTDERRへ出力している
エラー調査のためにWrite-Errorなどを追加すると、検出結果へ影響する可能性があります。診断用の出力と、Intuneが検出判定に使う出力を分けて設計します。
検出規則を選ぶときの実務的な判断基準
検出規則は、多ければ多いほど正確になるわけではありません。アプリの導入状態を最も安定して示す情報を選ぶことが重要です。
| アプリの特徴 | 検出方法の目安 |
|---|---|
| 安定したMSIで配布する | MSI製品コード |
| 特定バージョンを必須にする | MSI製品コードとバージョン、またはファイルバージョン |
| EXE形式で導入する | 実行ファイルの存在やバージョン |
| アプリ固有の版情報がレジストリにある | レジストリ値 |
| 複数条件のうちいずれかで判定したい | カスタム検出スクリプト |
| 導入先が端末ごとに異なる | カスタム検出スクリプト |
| 設定完了まで含めて判定したい | アプリ固有のレジストリ値やカスタムスクリプト |
複数の手動規則を追加するのは、「そのすべてが導入済みの必須条件」である場合に限定すると、意図しない未検出を減らせます。
IntuneのWin32検出規則を確認するチェックリスト
最後に、次の順番で確認します。
- 対象アプリが手動規則とカスタムスクリプトのどちらを使っているか
- 手動規則が複数設定されていないか
- MSI製品コードが実際の導入結果と一致しているか
- バージョン確認の条件が現在の版と一致しているか
- ファイルのパス、名前、検出方法が正しいか
- レジストリのキー、値名、データ型が正しいか
- 32ビットと64ビットの参照先が実態と一致しているか
- カスタムスクリプトが終了コード0とSTDOUTを返しているか
- STDERRへ不要なデータを出力していないか
- インストール結果と検出結果を分けて記録したか
- 本番へ反映する前にテスト対象で再評価したか
アプリが実際に入っているのに失敗扱いになる場合は、再インストールを繰り返す前に、現在の検出規則を保存し、影響を受けている端末で各条件を1つずつ照合してください。
特に、複数の手動規則はすべて成立する必要があること、32ビットと64ビットで参照先が変わること、検出スクリプトでは終了コードと出力の両方が必要なことが重要です。原因となる条件を特定してから、テスト対象で修正後の検出結果を確認し、問題が解消した段階で本番へ反映します。
[1]: https://learn.microsoft.com/en-us/intune/intune-service/apps/apps-win32-add “Add and Assign Win32 Apps to Microsoft Intune – Microsoft Intune | Microsoft Learn”

コメント