.NET Framework 和 COM 介面隨附的軟體元件可用來執行許多系統管理工作。Windows PowerShell 能讓您使用這些元件,因此即使您不用 Cmdlet 也可以執行工作。Windows PowerShell 第一版所附的 Cmdlet 大多無法從遠端電腦執行工作。以下將示範如何直接從 Windows PowerShell 使用 .NET Framework System.Diagnostics.EventLog 類別來管理事件記錄檔以突破這項限制。

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

.NET Framework 類別庫所含的 System.Diagnostics.EventLog 類別可用來管理事件記錄檔。使用 New-Object Cmdlet 搭配 TypeName 參數即可建立 .NET Framework 類別的新執行個體。例如,下列命令會建立事件日誌參照:

PS> New-Object -TypeName System.Diagnostics.EventLog

  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----

雖然此命令已建立 EventLog 類別的執行個體,該執行個體並未包含任何資料。這是因為命令沒有明確指定事件日誌。怎樣才能取得真正的事件日誌?

使用建構函式搭配 New-Object

若要參照特定事件記錄檔,必須指定記錄檔的名稱。New-Object 具有 ArgumentList 參數。傳入此參數做為參數值的引數將交給物件的特殊啟動方法使用。該方法稱為「建構函式」(Constructor),因為其用途即為建構物件。例如,若要取得應用程式記錄檔的參照,請指定 'Application' 字串做為引數:

PS> New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application

Max(K) Retain OverflowAction        Entries Name
------ ------ --------------        ------- ----
16,384      7 OverwriteOlder          2,160 Application
附註:

由於大多數 .NET Framework 核心類別都包含在 System 命名空間中,Windows PowerShell 如果找不到與您指定的類型名稱 (TypeName) 相符的類別,便會自動嘗試在 System 命名空間中尋找該指定類別。這表示您可以指定 Diagnostics.EventLog 代替 System.Diagnostics.EventLog。

將物件儲存至變數

您或許希望儲存物件的參照,以便可在目前的殼層中使用。縱然使用 Windows PowerShell 管線既可執行很多工作又能減少變數的需要量,有時若將物件的參照儲存至變數,則反而更方便操控這些物件。

Windows PowerShell 允許您建立基本上屬於具名物件的變數。Windows PowerShell 任何有效命令的輸出皆可儲存至變數。變數名稱一律以 $ 開頭。若要將應用程式記錄檔參照儲存至 $AppLog 變數,請輸入變數的名稱再加上等號,然後輸入用於建立應用程式記錄檔物件的命令:

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

接著輸入 $AppLog,就會看到此變數中包含應用程式記錄檔:

PS> $AppLog

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

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

上一節所使用的命令是以本機電腦為對象;其實 Get-EventLog 就能辦到。若要存取遠端電腦上的應用程式記錄檔,您必須一併提供記錄檔名稱和電腦名稱 (或 IP 位址) 做為引數。

PS> $RemoteAppLog = New-Object -TypeName System.Diagnostics.EventLog Application,192.168.1.81
PS> $RemoteAppLog

  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
     512      7 OverwriteOlder            262 Application

如今 $RemoteAppLog 變數中已儲存事件日誌的參照,接下來可以執行哪些工作呢?

使用物件方法清除事件日誌

物件通常會提供可呼叫的方法讓您用來執行工作。您可以使用 Get-Member 顯示與物件關聯的方法。下列命令指定輸出選項進而顯示 EventLog 類別的若干方法:

PS> $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() 方法可用來清除事件記錄檔。無論呼叫任何方法,即使方法不需要引數,方法名稱後面都必須加上括號。這樣 Windows PowerShell 才能分辨方法和潛在的同名屬性。下列命令可呼叫 Clear 方法:

PS> $RemoteAppLog.Clear()

接著輸入下列命令以顯示日誌。您將看到事件日誌已經清除,項目數從 262 變成 0:

PS> $RemoteAppLog

  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
     512      7 OverwriteOlder              0 Application

使用 New-Object 建立 COM 物件

您可以使用 New-Object 來處理元件物件模型 (COM) 元件。元件種類包括 Windows Script Host (WSH) 所附的各種程式庫,乃至大多數系統上安裝的 ActiveX 應用程式如 Internet Explorer。

New-Object 使用 .NET Framework Runtime 可呼叫包裝函式建立 COM 物件,因而呼叫 COM 物件時所受的限制與 .NET Framework 相同。若要建立 COM 物件,必須指定 ComObject 參數並將其值設定為所要使用的 COM 類別的程式設計識別碼或 ProgId。有關 COM 的使用限制與如何得知系統上可用的 ProgId 等主題,其完整細節已超出本使用手冊討論範圍,但其他環境如 WSH 下的常用物件大致都可在 Windows PowerShell 中使用。

您可以藉由指定下列 ProgId 來建立 WSH 物件:WScript.ShellWScript.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 物件便可快速進行的工作之一是建立捷徑。假設您想建立桌面捷徑以連結到 Windows PowerShell 的主資料夾。首先必須建立 WScript.Shell 的參照,並將其儲存在 $WshShell 變數中:

$WshShell = New-Object -ComObject WScript.Shell

Get-Member 可搭配 COM 物件使用,所以輸入下列命令即可檢視物件的成員:

PS> $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 會將其視為物件陣列。例如:

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

WScript.Shell CreateShortcut 方法接受單一引數,代表即將建立的捷徑檔所在路徑。您可以輸入桌面的完整路徑,但是還有更簡單的辦法。桌面通常就是目前使用者的主資料夾內名稱為 [桌面] (Desktop) 的資料夾。Windows PowerShell 使用 $Home 變數儲存這個資料夾的路徑。您可以使用此變數指定主資料夾的路徑,然後加上 [桌面] 資料夾的名稱,以及所要建立的捷徑名稱,例如:

$lnk = $WshShell.CreateShortcut("$Home\Desktop\PSHome.lnk")

如果雙引號中的字串看似變數名稱,Windows PowerShell 將嘗試取代相符的值。但若使用單引號,Windows PowerShell 就不會嘗試取代變數值。例如,試著輸入下列命令:

PS> "$Home\Desktop\PSHome.lnk"
C:\Documents and Settings\aka\Desktop\PSHome.lnk
PS> '$Home\Desktop\PSHome.lnk'
$Home\Desktop\PSHome.lnk

如今 $lnk 變數中包含新的捷徑參照。若要查看其成員,您可以透過管線將此變數傳送給 Get-Member。下列輸出顯示了建立捷徑時需要用到的成員:

PS> $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,這是 Windows PowerShell 的應用程式資料夾,然後呼叫 Save 方法儲存 $lnk 捷徑。Windows PowerShell 應用程式資料夾路徑儲存於 $PSHome 變數,因此請輸入下列命令進行作業:

$lnk.TargetPath = $PSHome

$lnk.Save()

從 Windows PowerShell 取用 Internet Explorer

使用 COM 可以將許多應用程式 (包括 Microsoft Office 系列應用程式和 Internet Explorer) 自動化。Internet Explorer 展現了使用 COM 應用程式所涉及的一些典型技巧和議題。

您可以指定 Internet Explorer ProgId InternetExplorer.Application 來建立 Internet Explorer 執行個體:

$ie = New-Object -ComObject InternetExplorer.Application

此命令會啟動 Internet Explorer,但並未予以顯示。如果您輸入 Get-Process,就會看到 iexplore 處理序正在執行中。事實上,當您結束 Windows PowerShell 後,該處理序仍將繼續執行。您必須重新啟動電腦,或使用 [工作管理員] 等工具結束 iexplore 處理序。

附註:

啟動成個別處理序的 COM 物件通稱為「ActiveX 可執行程式」(ActiveX Executable),啟動之後未必會顯示使用者介面視窗。這些物件若建立視窗但未予以顯示,就像 Internet Explorer,則焦點通常會移到 Windows 桌面,屆時您必須使視窗成為可見方能與之互動。

輸入 $ie | Get-Member 便可檢視 Internet Explorer 的屬性和方法。若要顯示 Internet Explorer 視窗,請將 Visible 屬性設定為 $true,如下所示:

$ie.Visible = $true

接著使用 Navigate 方法瀏覽特定網址:

$ie.Navigate("http://www.microsoft.com/technet/scriptcenter/default.mspx")

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

$ie.Document.Body.InnerText

呼叫 Internet Explorer 的 Quit() 方法則可從 PowerShell 將其關閉:

$ie.Quit()

這會強制關閉程式。$ie 變數雖然仍是 COM 物件,卻已不再包含有效的參照。若您繼續嘗試使用此變數,就會出現 Automation 錯誤:

PS> $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 可執行程式的參照移除之後,並無任何通則標準可判斷其是否已結束或仍繼續執行。應用程式結束與否取決於多種狀況,例如應用程式是否可見或仍開啟編輯過的文件,甚至於 Windows PowerShell 是否還在執行中。因此,您應針對每一個要從 Windows PowerShell 取用的 ActiveX 可執行程式測試其終止情形。

取得 .NET Framework 包裝式 COM 物件的相關警告

在某些情況下,COM 物件或許與 .NET Framework「可呼叫包裝函式」(Runtime-Callable Wrapper,RCW) 有所關聯,而 New-Object 正是使用後者。由於 RCW 的行為可能與一般 COM 物件的行為不同,New-Object 提供 Strict 參數以顯示 RCW 存取方面的警告。若您指定 Strict 參數且隨後使用 RCW 建立 COM 物件,就會看到警告訊息:

PS> $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 inte
rop assembly. If this type exposes different members than the IDispatch members
, scripts written to work with this object might not work if the primary intero
p assembly is not installed.
At line:1 char:17
+ $xl = New-Object  <<<< -ComObject Excel.Application -Strict

雖然還是會建立物件,卻也警告您該物件不是標準 COM 物件。




目錄