次の方法で共有


.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.ShellWScript.NetworkScripting.DictionaryScripting.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 オブジェクトではないことを示す警告が表示されます。