.NET オブジェクトと COM オブジェクトの作成
このサンプルは、Windows プラットフォーム上でのみ動作します。
ソフトウェア コンポーネントの中には、さまざまなシステム管理タスクを実行できるようにする .NET Framework や COM インターフェイスを備えているものがあります。 これらのコンポーネントは PowerShell から使用することもでき、コマンドレットだけではできないタスクも実行できます。 PowerShell の初回リリースでは、コマンドレットの多くがリモート コンピューターに対応していません。 ここでは、イベント ログを管理する場合に、.NET Framework の System.Diagnostics.EventLog クラスを PowerShell から直接使用して、この制限を回避する方法を紹介します。
New-Object によるイベント ログへのアクセス
.NET Framework のクラス ライブラリには、イベント ログの管理に使用する System.Diagnostics.EventLog というクラスが含まれています。 .NET Framework クラスの新しいインスタンスを作成するには、New-Object
コマンドレットと TypeName パラメーターを使用します。 たとえば、次のコマンドを実行すると、イベント ログの参照が作成されます。
New-Object -TypeName System.Diagnostics.EventLog
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
このコマンドによって EventLog クラスのインスタンスは作成されましたが、このインスタンスにはデータがまったく含まれていません。 これは、特定のイベント ログを指定しなかったためです。 実際のイベント ログを取得するにはどうすればよいのでしょうか。
New-Object でのコンストラクターの使用
特定のイベント ログを参照するには、ログの名前を指定する必要があります。 New-Object
には、ArgumentList というパラメーターがあります。 このパラメーターの値として渡した引数は、オブジェクトの特殊な初期化メソッドで使用されます。 オブジェクトを構築 (construct) する目的で使用されることから、このメソッドはコンストラクターと呼ばれています。 たとえば、Application ログの参照を取得するには、"Application" という文字列を引数として指定します。
New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
16,384 7 OverwriteOlder 2,160 Application
注意
.NET クラスの大半は System 名前空間に存在するため、指定された型名が見つからなかった場合、PowerShell は、そのクラスを自動的に System 名前空間から検索しようと試みます。 つまり、System.Diagnostics.EventLog
ではなく Diagnostics.EventLog
を指定できます。
オブジェクトの変数への保存
オブジェクトの参照を保存し、それを現在のシェルで使用できます。 PowerShell では多くの作業をパイプラインを使って実行できるため、変数を使用する機会はあまり多くありません。しかし、場合によっては、オブジェクトの参照を変数に格納した方が、オブジェクトを効率よく操作できることがあります。
正しい PowerShell コマンドであれば、その出力を変数に格納できます。 変数名は、常に $
で始まります。 Application ログの参照を変数 $AppLog
に格納するには、この変数名の後に等号を入力し、続けて、Application ログ オブジェクトの作成に使用するコマンドを入力します。
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
その後、「$AppLog
」と入力すると、Application ログが格納されていることを確認できます。
$AppLog
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
16,384 7 OverwriteOlder 2,160 Application
New-Object によるリモートのイベント ログへのアクセス
前のセクションで使用したコマンドは、アクセス先としてローカル コンピューターを想定していました。ローカル コンピューターのイベント ログを取得するのであれば、Get-EventLog
コマンドレットを使って行うこともできます。 リモート コンピューターの Application ログにアクセスするには、引数として、ログの名前とコンピューター名 (または IP アドレス) の両方を指定する必要があります。
$RemoteAppLog = New-Object -TypeName System.Diagnostics.EventLog Application, 192.168.1.81
$RemoteAppLog
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
512 7 OverwriteOlder 262 Application
これで、イベント ログの参照が $RemoteAppLog
変数に格納されたので、それで実行できるタスクについて説明します。
オブジェクトのメソッドを使用したイベント ログのクリア
多くの場合、オブジェクトには、特定のタスクを実行するときに呼び出すことのできるメソッドが存在します。 Get-Member
を使用すると、オブジェクトに関連付けられているメソッドを表示できます。 次の例は、EventLog クラスのメソッドを表示するコマンドと、その出力の抜粋です。
$RemoteAppLog | Get-Member -MemberType Method
TypeName: System.Diagnostics.EventLog
Name MemberType Definition
---- ---------- ----------
...
Clear Method System.Void Clear()
Close Method System.Void Close()
...
GetType Method System.Type GetType()
...
ModifyOverflowPolicy Method System.Void ModifyOverflowPolicy(Overfl...
RegisterDisplayName Method System.Void RegisterDisplayName(String ...
...
ToString Method System.String ToString()
WriteEntry Method System.Void WriteEntry(String message),...
WriteEvent Method System.Void WriteEvent(EventInstance in...
Clear()
メソッドを使用すると、イベント ログをクリアできます。 メソッドを呼び出すときは、引数が不要な場合でも、メソッド名の後に丸かっこを必ず入力する必要があります。 PowerShell は、丸かっこの有無により、それがメソッド名なのか、同名のプロパティ名なのかを判断します。 Clear メソッドを呼び出すには、次のように入力します。
$RemoteAppLog.Clear()
$RemoteAppLog
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
512 7 OverwriteOlder 0 Application
イベント ログがクリアされ、エントリ数が 262 から 0 に変わっていることに注目してください。
New-Object による COM オブジェクトの作成
コンポーネント オブジェクト モデル (COM) のコンポーネントを操作するには、New-Object
を使用します。 一口にコンポーネントと言っても、その種類は Windows Script Host (WSH) に含まれている各種ライブラリから、Internet Explorer のようなほとんどのシステムにインストールされている ActiveX アプリケーションまで多岐にわたります。
New-Object
では、.NET Framework ランタイム呼び出し可能ラッパーを使って COM オブジェクトを作成します。したがって、COM オブジェクトを呼び出す際には .NET Framework の場合と同じ制限が適用されます。 COM オブジェクトを作成するには、使用する COM クラスのプログラム識別子 (ProgId) を ComObject パラメーターで指定する必要があります。 COM の使用上の制限や、システム上で利用できる ProgId の調査方法については、このユーザーズ ガイドの範囲を超えているので詳しく説明しません。しかし、WSH などの環境に存在する、一般によく知られているようなオブジェクトについては、PowerShell 内で使用できます。
WSH オブジェクトは、WScript.Shell、WScript.Network、Scripting.Dictionary、Scripting.FileSystemObject などを ProgId として指定すれば作成できます。 これらのオブジェクトを作成するコマンドの例を次に示します。
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject
これらのクラスの機能は、その多くが、Windows PowerShell から他の方法を使ってアクセスすることもできます。ただし、ショートカットの作成など、一部のタスクについては、WSH のクラスを使用した方が簡単です。
WScript.Shell によるデスクトップ ショートカットの作成
COM オブジェクトの使用が適しているタスクの 1 つに、ショートカットの作成があります。 PowerShell のホーム フォルダーに対するショートカットをデスクトップ上に作成するとします。 まず必要なことは、WScript.Shell の参照を作成することです。ここでは、この参照を $WshShell
という変数に格納することにします。
$WshShell = New-Object -ComObject WScript.Shell
Get-Member
は COM オブジェクトで動作するので、次のように入力して、オブジェクトのメンバーを調べることができます。
$WshShell | Get-Member
TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}
Name MemberType Definition
---- ---------- ----------
AppActivate Method bool AppActivate (Variant, Va...
CreateShortcut Method IDispatch CreateShortcut (str...
...
Get-Member
には、省略可能なパラメーター InputObject があります。Get-Member
に対する入力をパイプで渡す代わりに、このパラメーターを使用することもできます。 Get-Member -InputObject $WshShell コマンドを使用しても表示される出力結果は同じです。 InputObject を使用した場合、その引数は単一の項目として扱われます。 つまり、1 つの変数に複数のオブジェクトが格納されている場合、Get-Member
では、それらはオブジェクトの配列として扱われます。 次に例を示します。
$a = 1,2,"three"
Get-Member -InputObject $a
TypeName: System.Object[]
Name MemberType Definition
---- ---------- ----------
Count AliasProperty Count = Length
...
WScript.Shell CreateShortcut メソッドは、作成するショートカット ファイルのパスのみを引数として受け取ります。 デスクトップへのフル パスを入力することもできますが、より簡単な方法があります。 通常、デスクトップは、現在のユーザーのホーム フォルダーにある "デスクトップ" というフォルダー名で表されます。 Windows PowerShell には、このフォルダーへのパスを保持する $HOME
という変数が用意されています。 この変数を使ってホーム フォルダーのパスを指定し、続けて、デスクトップ フォルダーの名前と、作成するショートカットの名前を追加します。次にその例を示します。
$lnk = $WshShell.CreateShortcut("$HOME\Desktop\PSHome.lnk")
変数名と思われる情報が二重引用符内に存在した場合、PowerShell は、それを対応する値に置き換えようと試みます。 一重引用符を使用した場合、PowerShell によって変数値の置き換えは行われません。 たとえば、次のコマンドを入力してみてください。
"$HOME\Desktop\PSHome.lnk"
C:\Documents and Settings\aka\Desktop\PSHome.lnk
'$HOME\Desktop\PSHome.lnk'
$HOME\Desktop\PSHome.lnk
$lnk
という変数には、現在、新しいショートカットの参照が格納されています。 メンバーを表示するには、この変数をパイプを使って Get-Member
に渡します。 次のように、ショートカットを完成するために必要なメンバーが出力結果として表示されます。
$lnk | Get-Member
TypeName: System.__ComObject#{f935dc23-1cf0-11d0-adb9-00c04fd58a0b}
Name MemberType Definition
---- ---------- ----------
...
Save Method void Save ()
...
TargetPath Property string TargetPath () {get} {set}
TargetPath (PowerShell のアプリケーション フォルダー) を指定した後、Save
メソッドを呼び出してショートカットを保存する必要があります。 PowerShell のアプリケーション フォルダーのパスは変数 $PSHome
に保存されているため、次のように入力します。
$lnk.TargetPath = $PSHome
$lnk.Save()
PowerShell からの Internet Explorer の使用
Microsoft Office ファミリのアプリケーションや Internet Explorer など、多くのアプリケーションは COM を使用して自動化できます。 COM ベースのアプリケーション操作に関係する一般的なテクニックと問題点の例を次に示します。
Internet Explorer のインスタンスを作成するには、次のように、Internet Explorer の ProgId として InternetExplorer.Application を指定します。
$ie = New-Object -ComObject InternetExplorer.Application
このコマンドでは、Internet Explorer は起動しますが、表示はされません。 「Get-Process
」と入力すると、iexplore
というプロセスが実行中であることがわかります。 実際、PowerShell を終了しても、このプロセスは実行されたままです。 iexplore
プロセスを終了するには、コンピューターを再起動するか、またはタスク マネージャーなどのツールを使用する必要があります。
注意
独立したプロセスとして起動する COM オブジェクトは、一般に ActiveX 実行可能ファイルと呼ばれ、起動時にユーザー インターフェイス ウィンドウを表示するものと、表示しないものが存在します。 Internet Explorer のように、ウィンドウを作成してもそれを表示しない場合、通常、フォーカスは Windows デスクトップに移動します。 ウィンドウを操作するには、表示する必要があります。
$ie | Get-Member
と入力すると、Internet Explorer のプロパティおよびメソッドを表示できます。 Internet Explorer ウィンドウを表示するには、次のように入力して、Visible プロパティを $true
に設定します。
$ie.Visible = $true
次に、Navigate
メソッドを使用すると、特定の Web アドレスに移動できます。
$ie.Navigate("https://devblogs.microsoft.com/scripting/")
Internet Explorer オブジェクト モデルの他のメンバーを使用すると、この Web ページからテキストの内容を取得できます。 次のコマンドを実行すると、現在の Web ページの本文に含まれる HTML テキストが表示されます。
$ie.Document.Body.InnerText
Internet Explorer を PowerShell 内から終了するには、Quit()
メソッドを呼び出します。
$ie.Quit()
まだ COM オブジェクトであるように見えますが、$ie
変数には有効な参照が含まれなくなっています。 これを使おうとすると、PowerShell はオートメーション エラーを返します。
$ie | Get-Member
Get-Member : Exception retrieving the string representation for property "Appli
cation" : "The object invoked has disconnected from its clients. (Exception fro
m HRESULT: 0x80010108 (RPC_E_DISCONNECTED))"
At line:1 char:16
+ $ie | Get-Member <<<<
$ie = $null
などのコマンドを使って残っている参照を削除するか、次のように入力して変数を完全に削除することができます。
Remove-Variable ie
注意
参照を削除したときに、ActiveX 実行可能ファイルを終了するか、実行を継続するかに関して、共通の標準は存在しません。 アプリケーションが終了するかどうかは、アプリケーションが可視状態であるか、編集中のドキュメントが存在するか、PowerShell がまだ実行されているかなど、さまざまな条件に依存します。 そのため、PowerShell で使用する ActiveX 実行可能ファイルごとに、終了時の動作をテストしておく必要があります。
.NET Framework によってラップされた COM オブジェクトの警告の取得
場合によっては、COM オブジェクトに、.NET Framework ランタイム呼び出し可能ラッパー (RCW) が関連付けられ、New-Object
から使われていることがあります。 RCW の動作は通常の COM オブジェクトの動作とは異なる場合があるため、New-Object
には、RCW アクセスに関する警告を取得する Strict パラメーターが用意されています。 Strict パラメーターを指定し、RCW を使用する COM オブジェクトを作成した場合、次のような警告メッセージが表示されます。
$xl = New-Object -ComObject Excel.Application -Strict
New-Object : The object written to the pipeline is an instance of the type "Mic
rosoft.Office.Interop.Excel.ApplicationClass" from the component's primary interop assembly. If
this type exposes different members than the IDispatch members , scripts written to work with this
object might not work if the primary interop assembly isn't installed. At line:1 char:17 + $xl =
New-Object <<<< -ComObject Excel.Application -Strict
オブジェクトは作成されますが、標準の COM オブジェクトではないことを示す警告が表示されます。
PowerShell