PowerShellを使って特定のアプリケーションがインストールされているか確認する方法

PowerShellを使って特定のアプリケーションがインストールされているか確認する方法で重要なのは、実行例を増やすことより、対象と戻し方を先に確定することです。結論は「「導入済み」はdesktop installer、Store package、portable executable、current user scopeのどれを対象にするかで判定方法が違います。product ID、publisher、実行pathなど複数条件で確認し、見つからないを即未導入としません。」。ここではapplication種別とscopeを先に決め、Win32_Productや曖昧なname substringに依存しない条件を前提に、2026年7月17日時点の公式仕様から、現場で再現できる判断順を組み立てます。

目次

applicationをname・publisher・scopeで定義する

registry exact match、Get-AppxPackage、Get-Commandの入力、出力、変更有無を一文で書き、host、user、current directory、実行時刻を添えます。registry・Appx・PATHの結果は同じhost/user scopeで集め、別端末の候補を混在させません。

  • targetの正式product名、publisher、package IDをvendor資料から確認する
  • machine/user、64/32bit、Store/portableのscopeを決める
  • Uninstall registryを副作用なく読む
  • 必要ならGet-Commandで実行pathとsignatureを確認する

registryのexact matchを三値化する

registryでexact productを探す

$roots='HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*','HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*','HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
$match=Get-ItemProperty $roots -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq 'Target Application' -and $_.Publisher -eq 'Expected Publisher' }

正式値へ置き換えます。似たviewerやlanguage packを除外します。

結果を三状態で返す

if($match.Count -eq 1){'Installed'} elseif($match.Count -gt 1){'Ambiguous'} else{'NotFoundInRegistry'}

0件を端末全体のNotInstalledとせずsourceを明記します。複数件はbitnessやversionをreviewします。

Store packageを確認

Get-AppxPackage -Name 'Expected.Package.Name' | Select-Object Name,Version,Publisher,PackageFullName

current user scopeです。package nameはvendor資料から確認します。

command pathを補足

Get-Command 'target.exe' -CommandType Application -All -ErrorAction SilentlyContinue |
  Select-Object Name,Path,Version

PATHにあることはinstaller登録と同義ではありません。複数pathやuser-writable pathを確認します。

PATH上binaryの署名を確認

$cmd=Get-Command 'target.exe' -CommandType Application -ErrorAction SilentlyContinue
if($cmd){Get-AuthenticodeSignature -LiteralPath $cmd.Path | Select-Object Status,SignerCertificate}

名前だけで正規appと判断せずpublisherを確認します。

Store package名を別経路で確認する

NotFoundInRegistryはportable、Store、別user、壊れたregistrationの可能性を残します。Installed判定には「実行可能」「licensed」「設定済み」「support対象」が含まれません。目的がdeployment complianceならproduct codeやpackage IDを管理基準にし、表示名の曖昧matchを避けます。

PATH上のexecutable候補をすべて列挙する

判定は読み取りです。Win32_Product queryはMSI repairを誘発し得るので使いません。見つからないから自動installしたり、複数matchを一括uninstallしたりしません。導入が必要ならpublisher、source、version、user data、maintenance、rollbackを確認します。疑わしい同名exeは実行せずsignatureとpathをsecurity担当へ報告します。

実行fileの署名とversionを確認する

  • DisplayNameの-likeだけで判定する
  • Win32_Productを使う
  • current userだけで全userを断定する
  • PATH上exeをinstaller済みとする
  • 0件なら自動installへ進む

portable copyを導入済みと混同しない

Settings Installed apps、official package manager、registry、executable signatureを対象種別に応じて照合します。Installed、NotFound、Ambiguous、AccessDeniedをtestし、exit codeを分けます。判定結果にsource、scope、host、取得時刻を含め、後続deploymentが誤って動かないことを確認します。

特定applicationの導入有無判定を定期化するなら、正常件数、警告境界、停止条件を数値化します。

UniqueExecutable・NotFound・Ambiguousを検収する

Target applicationをproduct ID、publisher、package family、署名済みexe pathで照合し、Installed、NotFoundInCheckedSources、Ambiguousを返します。0件だけで自動installせず、どのsource/scopeを調べたかを結果へ含めます。

registryとPATH候補を独立に確認する

$cmds=@(Get-Command 'target.exe' -CommandType Application -All -ErrorAction SilentlyContinue)
$cmds | ForEach-Object { $sig=Get-AuthenticodeSignature -LiteralPath $_.Path; [pscustomobject]@{Path=$_.Path;Version=$_.Version;Signature=$sig.Status;Signer=$sig.SignerCertificate.Subject} }

一意・未検出・曖昧を分ける

  • 正規実体を一意化:一つの信頼できるIDとpublisher/path/signatureが一致してInstalledになる
  • PATH・registry未検出:全ての宣言済みsourceが正常に調査できて0件ならNotFoundInCheckedSourcesになる
  • 複数候補・署名不備:複数match、source query error、signature不一致はAmbiguous/Errorとして処理を止める

PATH上の同名exeだけでは正規installer済みとは限りません。per-userとmachine-wide、portableとregistered、Store packageを混同せず、0件からinstall/uninstallへ直結しません。

複数pathと署名なしbinaryを試す

$state=if($cmds.Count -eq 1 -and (Get-AuthenticodeSignature $cmds[0].Path).Status -eq 'Valid'){'UniqueExecutable'}elseif($cmds.Count -eq 0){'NotFoundOnPath'}else{'AmbiguousOrUnsigned'}
[pscustomobject]@{State=$state;Candidates=$cmds.Count}

未導入、正規1件、同名複数、unsigned、per-userのみ、registryのみをtestします。checked sources、candidate数、ID、path、signature、versionを一recordへ残します。

導入状態は一つのsourceだけでは確定しません。registry、Appx、PATH候補を独立に収集し、署名・publisher・versionが一致した実体だけをUniqueとして扱います。

公式情報・参考資料

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次