建立 .NET 和 COM 物件

此範例只會在 Windows 平台上執行。

具有 .NET Framework 和 COM 介面的軟體元件可讓您執行許多系統管理工作。 PowerShell 可讓您使用這些元件,因此您不限於可以使用 Cmdlet 執行的工作。 PowerShell 初始版本中的許多 Cmdlet 無法對遠端電腦運作。 我們將示範如何在直接從PowerShell使用 .NET Framework System.Diagnostics.EventLog 類別來管理事件記錄檔時,解決此問題。

使用 New-Object 進行事件記錄檔存取

.NET Framework 類別庫包含名為 System.Diagnostics.EventLog 的類別,可用來管理事件記錄檔。 您可以使用 Cmdlet 搭配 TypeName 參數,來建立 .NET Framework 類別New-Object的新實例。 例如,下列命令會建立事件記錄檔參考:

New-Object -TypeName System.Diagnostics.EventLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----

雖然命令已建立 EventLog 類別的實例,但 實例不包含任何數據。 這是因為我們沒有指定特定的事件記錄檔。 如何取得真正的事件記錄檔?

搭配 New-Object 使用建構函式

若要參考特定的事件記錄檔,您必須指定記錄檔的名稱。 New-Object具有 ArgumentList 參數。 您當做值傳遞至此參數的自變數會由 物件的特殊啟動方法使用。 方法稱為建 構函式,因為它用來建構 物件。 例如,若要取得應用程式記錄檔的參考,您可以將字串 '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 找不到您指定之 typename 的相符專案,則 PowerShell 會自動嘗試尋找您在 System 命名空間中指定的類別。 這表示您可以指定 Diagnostics.EventLog 而非 System.Diagnostics.EventLog

將物件儲存在變數中

您可能想要儲存對象的參考,因此您可以在目前的殼層中使用它。 雖然 PowerShell 可讓您對管線執行許多工作,但減少對變數的需求,但有時候將對象的參考儲存在變數中,可讓您更方便操作這些物件。

任何有效 PowerShell 命令的輸出都可以儲存在變數中。 變數名稱一律以 $開頭。 如果您想要將應用程式記錄參考儲存在名為 $AppLog的變數中,請輸入變數的名稱,後面接著等號,然後輸入用來建立 Application 記錄物件的命令:

$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application

如果您接著輸入 $AppLog,您會看到它包含應用程式記錄檔:

$AppLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
  16,384      7 OverwriteOlder          2,160 Application

使用 New-Object 存取遠端事件記錄檔

上一節中使用的命令會以本機計算機為目標; Get-EventLog Cmdlet 可以執行此動作。 若要存取遠端電腦上的應用程式記錄檔,您必須同時提供記錄名稱和計算機名稱(或 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

請注意,事件記錄檔已清除,現在有 0 個專案,而不是 262 個專案。

使用 New-Object 建立 COM 物件

您可以使用 New-Object 來使用元件物件模型 (COM) 元件。 元件範圍從 Windows 腳本主機 (WSH) 隨附的各種連結庫,到大部分系統上安裝的 ActiveX 應用程式,例如 Internet Explorer。

New-Object 會使用 .NET Framework 運行時間可呼叫包裝函式來建立 COM 物件,因此在呼叫 COM 物件時,.NET Framework 有相同的限制。 若要建立 COM 物件,您必須使用所要使用的 COM 類別之程式設計標識碼或 ProgId 來指定 ComObject 參數。 完整討論 COM 使用的限制,並判斷系統上有哪些 ProgId 已超出此使用者指南的範圍,但 WSH 等環境中最知名的物件可以在 PowerShell 中使用。

您可以指定下列程式來建立 WSH 物件:WScript.Shell、WScript.NetworkScripting.DictionaryScripting.FileSystemObject。 下列命令會建立這些物件:

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 物件快速執行的工作之一,就是建立快捷方式。 假設您想要在桌面上建立快捷方式,以連結至 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,它會將其自變數視為單一專案。 這表示如果您在變數中有數個物件, Get-Member 請將它們視為 對象的陣列。 例如:

$a = 1,2,"three"
Get-Member -InputObject $a
TypeName: System.Object[]
Name               MemberType    Definition
----               ----------    ----------
Count              AliasProperty Count = Length
...

WScript.Shell CreateShortcut 方法會接受單一自變數,這是要建立之快捷方式檔案的路徑。 我們可以輸入桌面的完整路徑,但有一個更簡單的方式。 桌面通常會以目前用戶主資料夾內的名為 Desktop 的資料夾來表示。 Windows PowerShell 有一個變數 $HOME ,其中包含此資料夾的路徑。 我們可以使用這個變數來指定主資料夾的路徑,然後新增Desktop資料夾的名稱,以及輸入來建立之快捷方式的名稱:

$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 ProgId、 InternetExplorer.Application 來建立 Internet Explorer 實例:

$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

$ie.Navigate("https://devblogs.microsoft.com/scripting/")

使用 Internet Explorer 物件模型的其他成員,可以從網頁擷取文字內容。 下列命令會顯示目前網頁本文中的 HTML 文字:

$ie.Document.Body.InnerText

若要從 PowerShell 內關閉 Internet Explorer,請呼叫其 Quit() 方法:

$ie.Quit()

變數 $ie 已不再包含有效的參考,即使它仍顯示為 COM 物件也一樣。 如果您嘗試使用它,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 因此具有 Strict 參數來警告您 RCW 存取。 如果您指定 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 物件。