PowerShellで特定アプリが実行中か確認する基本はGet-Processです。ただし画面に表示される製品名とプロセス名は一致しない場合があり、ブラウザーやTeamsのように一つのアプリが複数プロセスを使うこともあります。確認結果を真偽値へ変えるだけでなく、PID、実行ファイル、開始時刻、ユーザーセッションを照合し、アプリ未起動と権限不足・別セッション・プロセス名違いを区別することが大切です。
対象アプリの正しいプロセス名を特定する
タスクマネージャーの「詳細」タブやGet-Process | Sort-Object ProcessNameで、アプリ起動前後の差を確認します。Get-ProcessのNameまたはProcessNameでは、通常.exeを除いた名前を使います。たとえばnotepad.exeはGet-Process -Name notepadです。製品の表示名だけから推測せず、正規の実行ファイルと発行元を確認します。
同じ製品が複数の実行ファイルやヘルパープロセスを持つ場合、どれを「実行中」の条件にするか決めます。メイン画面が閉じても更新プロセスが残る、常駐トレイだけ動く、ブラウザーのタブごとに分かれるケースがあります。業務上必要なのがユーザー画面、バックグラウンドサービス、ジョブのどれかを明確にします。
Get-Process -Nameで存在を確認する
Get-Process -Name notepadは一致するプロセスを返し、存在しない場合はエラーを表示します。確認だけならGet-Process -Name notepad -ErrorAction SilentlyContinueとし、返されたオブジェクトの有無を見ます。ただしエラーをすべて隠すと権限や環境問題に気づきにくいため、運用ではErrorVariableやtry/catchで失敗理由を記録します。
正確な真偽値が必要なら$running = $null -ne (Get-Process -Name notepad -ErrorAction SilentlyContinue)とできます。複数件を数えるなら@(Get-Process -Name notepad -ErrorAction SilentlyContinue).Countを使います。出力を文字列へ変換して検索するより、プロセスオブジェクトのName、Idなどを直接扱う方が誤判定を減らせます。
ワイルドカードは対象を広げすぎない
Get-Process -Name "chrome*"のようなワイルドカードは関連名をまとめて探せますが、想定外の別プロセスを含む可能性があります。まず完全一致で確認し、複数の正規プロセス名がある場合は許可リスト配列を使います。ユーザー入力をそのままパターンへ渡さず、検索対象名を検証します。
Where-ObjectでDescriptionやMainWindowTitleを絞る方法もありますが、説明が空、言語で変わる、ウィンドウタイトルに文書名や機密情報を含む場合があります。自動判定の主キーにはProcessNameと必要ならPath、署名、製品情報を使い、タイトルは補助情報として扱います。
PID・Path・StartTimeを照合する
同名プロセスが複数ある場合はGet-Process -Name notepad | Select-Object Name,Id,StartTime,Pathで識別します。IdはPID、StartTimeは開始時刻、Pathは実行ファイルです。一部のシステムプロセスや別ユーザーのプロセスでは、権限不足でStartTimeやPathを取得できないことがあります。空欄を偽装や異常と断定しません。
PIDはプロセス終了後に再利用されるため、監視記録には取得時刻とStartTimeを一緒に保存します。Pathがユーザープロファイル、Program Files、Windows配下のどこかを確認し、期待する製品の正規パスと比較します。見覚えのないPathを即座に削除せず、ファイル署名とセキュリティ製品の調査へ渡します。
アプリとWindowsサービスを混同しない
バックグラウンド処理がサービスとして動く製品では、Get-Processだけでサービスの状態を判断できません。Get-Service -Name サービス名でサービス管理状態を確認し、関連PIDはCIMやサービス管理ツールで照合します。サービスがRunningでも内部処理が正常とは限らず、製品のヘルスチェックやログが必要です。
反対に、サービスが停止していてもユーザーアプリが単独で動く製品があります。「プロセスあり」「サービスRunning」「アプリが業務を提供できる」は別の判定です。監視仕様で何を成功とするかを決め、プロセス存在だけを可用性監視の代わりにしません。
別ユーザー・別セッションを確認する
共有PCやRDSでは、同じプロセス名が他ユーザーのセッションで動いていることがあります。Get-ProcessのSessionIdを出力し、現在のセッションと比較します。管理者が全ユーザーの情報へアクセスできる場合でも、個人のウィンドウタイトルやパスを不要に収集しません。対象ユーザーとセッションを明示します。
スクリプトをタスクスケジューラーやサービスアカウントで実行すると、対話ユーザーとは別セッションです。監視スクリプト自身のセッションから見えることと、利用者のデスクトップで使えることは同じではありません。自動化の実行アカウント、ログオン種別、権限を記録します。
リモート端末では接続先でGet-Processを実行する
PowerShell Remotingを使う場合、Invoke-Command -ComputerName PC01 -ScriptBlock { Get-Process -Name notepad -ErrorAction SilentlyContinue }のように接続先で評価します。資格情報をスクリプトへ平文で記載せず、許可された管理基盤と最小権限を使います。接続失敗とプロセスなしを別の結果として保存します。
多数端末を確認する場合は、端末名、接続成功、プロセス件数、PID、開始時刻、エラーを一行ずつ構造化します。一斉実行の同時数とタイムアウトを制御し、オフライン端末へ繰り返し負荷をかけません。収集結果にユーザー情報が含まれる場合はアクセス権と保管期間を定めます。
監視と自動処理へつなげるときの注意
「見つからなければ起動する」処理は、単純な存在確認よりリスクが高くなります。アプリ起動に必要なユーザーセッション、二重起動防止、引数、作業フォルダー、ライセンス、復旧回数を設計します。この記事の確認コードへStart-ProcessやStop-Processを混ぜず、変更・復旧処理は別にレビューします。
一時的に終了して自動再起動中のアプリもあるため、一回の未検出で障害通知しないよう、再確認間隔と回数を決めます。プロセスが存在しても応答停止している場合は、Responding、CPU時間、製品のヘルスエンドポイントやログを補助にします。通知には端末、時刻、PID、判定条件を含め、利用者データを出しません。
実務での確認チェックリスト
- タスクマネージャーで実際のProcessNameを確認する
- Get-Process -Nameは.exeを除く名前で指定する
- 真偽値だけでなくPID、StartTime、Pathを必要に応じて記録する
- 別ユーザーとSessionIdを区別する
- サービス状態とアプリ可用性を混同しない
- 接続失敗とプロセス未検出を別結果にする

コメント