
TechNet コラムへようこそ。このコラムでは、よく寄せられるシステム管理スクリプトに関する質問に Scripting Guys がお答えします。システム管理スクリプトについて質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。
詳細情報
| • | |
| • | |
| • |
![]()
Scripting Guy さん、よろしくお願いします。Windows PowerShell を使用してコンピュータ上で開いているすべてのウィンドウの一覧を取得する方法があると聞きました。その方法を教えていただけますか。
-- JD

JD さん、こんにちは。もちろん、お教えしますよ。ただし、その前に少しお時間をいただいて Peter Costantini に敬意を表したいと思います。彼は最年長の Scripting Guy です。Peter は、「Doctor Scripto のスクリプト ショップ」の著者として、また Webcast で歌う変わり者として最もよく知られていますが、最近 Microsoft Management Practices グループの Program Manager に就任しました。Peter は今後も Scripting Guy であり続けますが、スクリプトの作成とスクリプト センターの記事の執筆にあまり時間を充てることができなくなります。
つまり、総合的に考えると、彼は他の Scripting Guy と同じ立場になります。しかし少なくとも、彼が何もしないのには理由があります。
他の Scripting Guy と言えば皆 Peter の幸運を祈り、特別な感謝のしるしとして彼の Scripting Guy としての最高の瞬間をいくつかまとめてみようと思いました。
| • | たとえば、ほんの数週間前に彼が、ええと、実際は Dean があれをやりました。 |
| • | でも、1 年ほど前に Peter が、いや、何でもありません。Jean があれを書きましたよね。 |
| • | まだありました。ああ、そうでしたね。しかし、ビルが放火されなかったら、あれはとてもすばらしいコンパクトなスクリプトになっていたはずです。 |
もちろん、すばらしい瞬間は他にもたくさんありますが、あまりにも多すぎて挙げきれません。
注 : ご想像のとおり、スクリプトやスクリプト センターに Peter がもたらした本当の功労は、彼がこなした仕事の量では判断できません。少なくとも、彼は私たちにいつもこう言っています。 でも、いいように考えれば、Peter は役立つことや重要なことを何もしないで数年間のんびり過ごしてきたので、マイクロソフトの管理職にうってつけです。 |
実を言うと、Peter から辞めることを聞かされたとき、私たちは最初ただぼんやりと座って落ち込みました (もちろん、この私たちの最初の反応は何に対してもたいてい同じですが)。しかし、これは Peter が期待した反応ではなかったでしょう。むしろ、くよくよせずに前向きに生きていってほしいと思ったはずです。では、どうぞ、Peter。次のコードをあなたにささげます。
Get-Process | Where-Object {$_.MainWindowTitle -ne ""} | Select-Object MainWindowTitle
ご覧のとおり、これは非常に単純な短いコマンドです。最初に Get-Process Cmdlet を呼び出します。Get-Process Cmdlet は、その名のとおり、コンピュータで実行されているすべてのプロセスのコレクションを取得します。もちろん、実際には、コンピュータで実行されている "すべて" のプロセスのコレクションは必要ありません。この Cmdlet で取得したコレクションには、ウィンドウを表示した状態で実行されないサービスや他のプロセスが含まれます。そのため、Where-Object Cmdlet に取得したコレクションを "パイプ" し、MainWindowTitle プロパティに空の文字列が設定されているプロセスをフィルタで除くように Where-Object に指示します。
注 : もちろん、わかっています。Windows PowerShell では、<> ではなく –ne 演算子を使用します。–ne を使いたいかどうかは関係ありません。–ne を使うしかないのですから。 |
このように処理するとどうなるでしょうか。ウィンドウを表示した状態で実行されないサービスや他のプロセスが除外されます (ウィンドウがない場合、MainWindowTitle は空の文字列になります)。次に、このフィルタ処理したコレクションを Select-Object Cmdlet に渡し、MainWindowTitle プロパティだけを表示するように Select-Object に指示します。
MainWindowTitle --------------- open_windows.ps1 - Notepad Inbox - Microsoft Outlook Windows PowerShell more_hey_scripting_guy.doc - Microsoft Word
よく気付きましたね。WMI の Win32_Process クラスに MainWindowTitle プロパティはありません。それは、Get-Process Cmdlet では WMI を使用してプロセス情報を取得せず、代わりに .NET Frameowork クラスの System.Diagnostics.Process が使用されるからです。
残念なことに、このコマンドには小さな欠点があります。このコマンドでは Windows エクスプローラ ウィンドウ (たとえば、C:\Scripts を開いているウィンドウ) が返されません。でも、問題ありません。次のような Windows エクスプローラ ウィンドウを返す別のワンライナーがあります。
$a = New-Object -com "Shell.Application"; $b = $a.windows() | select-object LocationName; $b
ここでは、New-Object Cmdlet を使用して、Shell.Application オブジェクトのインスタンスを作成します。Windows() メソッドを呼び出して Shell ウィンドウのコレクションを取得し、その後 Select-Object Cmdlet を使用して LocationName プロパティの値をエコー バックします。そうすると、次のようなレポートが出力されます。
LocationName ------------ Stuff Hey Scripting Guy Scripts
また、LocationURL プロパティをエコー バックして完全なパスを取得することもできます。もちろん、この場合、LocationURL から次のようなパスが返されるので、少しクリーンアップ作業をするとよいでしょう。
file:///C:/Documents%20and%20Settings/kenmyer/Desktop/Stuff/Hey%20Scripting%20Guy
返される文字列をクリーンアップするときに役立つコマンドがあります。
これでご質問の回答になっているとよいのですが、JD さん。そして気になる方のために言っておきますと、Peter が新しい職に就いたからといって、彼から Scripting Guy の地位を剥奪することなど、考えてもいませんでした。それは、彼のスクリプト界での貴重な功績を認めて、今後も、これまでどおり貢献し続けてくれると考えたからでしょうか。そうです、そのとおりです。
Peter がいなくなったら、Greg が最年長の Scripting Guy になりますが、Greg がそれを受け入れるはずがありません。ほら、言ったでしょう、Peter。私たちは、あなたをからかっていじめるのが好きですが、あなたには、このチームの中でとても重要な役割を担ってきたのです。そして、これからも、その役割を担っていくのです。そう、ずっとです。