公用程式焦點Windows PowerShell 的 SMS Cmdlet

Don Brown

下載本文程式碼: Utility2007_11.exe (1211KB)

過去要從命令列管理 Microsoft System Management Server (SMS) 2003 用戶端是不可能的事,幸好最近陸續出現許多協助系統管理員管理複雜性、變更和設定的優秀技術,其中尤以 Windows PowerShell 最能解決問題。

為了好好運用這項技術,我寫了一個小小的「公用程式」:SMS2003PowerShellSnapinSample (您可以從本專欄隨附的程式碼下載中取得這個指令碼,網址是 technetmagazine.com/code07.aspx)。這個公用程式其實是由六個 Cmdlet 組成一個 Windows PowerShellTM 嵌入式管理單元。您可以使用這些 Cmdlet,從 Windows PowerShell 設定本機電腦或遠端電腦群組的 SMS 用戶端本機原則。

由於 SMS 用戶端本機原則越用越上手,促使我更進一步學習 SMS 的操作方式,把它當作額外的收穫。也因此瞭解,只要審慎運用 SMS 用戶端本機原則,就可以用全新的方式控制 SMS 用戶端:比方說,向同一個站台報告的電腦,不一定具有相同的設定。而您可以設定幾部特定的電腦,讓它們直接從遠端控制電腦、改變用戶端檢查新原則的頻率,或者在當天多次停用特定的元件等等 — 您會發現 SMS 用戶端本機原則在使用上是海闊天空,沒有限制的。現在就讓我們來深入探討吧。

關於 SMS 進階用戶端本機原則

程式設計資源

所有正常運作的 SMS 2003 進階用戶端都有一個設定原則,這個設定原則基本上是一份驅動各種元件的設定清單。所有的用戶端、清查彙總及軟體散發設定 (尤其是這一項) 都包含在這些設定原則中。這些原則本身是在站台伺服器上建立,然後經由 SMS 管理點傳給進階用戶端。

SMS 原則的實際本文部分很類似 Managed 物件格式 (MOF) 檔,因為它所包含的一組執行個體,會編譯到進階用戶端上的 \\.\root\CCM WMI (Windows® Management Instrumentation) 命名空間中。其他各種代理程式會讀取這些位於 \\.\root\ccm\policy\machine\requestedconfig 命名空間的設定。但是,當您透過 MOF 套用本機原則時,一部電腦只能編譯一個 MOF,而且它必須在本機執行 (否則您就必須直接登入電腦)。而 WMI 因為具備分散性質的關係,可以從本機和遠端存取它,因而有更多方式可以協助 SMS 管理員。也就是說,只要具備適當的管理權限,就可以像連接本機電腦的 WMI 一樣,連接遠端電腦的 WMI。

SMS 用戶端原則是由適用於各種用戶端元件的設定所組成,不過它也可以包含執行軟體套件內容的相關指示。就像 Active Directory® 群組原則一樣,從 SMS 管理點取得的 SMS 2003 進階用戶端原則也可以覆寫成 SMS 用戶端本機原則。雖然無法將原則全部覆寫,不過仍然可以覆寫一些相當有趣的屬性。這一點讓 SMS 管理員有更大的空間可以控制 SMS 用戶端的設定與作業,因為它容許將標準設定的例外套用在 SMS 站台上。

假設現在有一個整合的安全環境,在這個環境中,SMS 管理員把伺服器和工作站都當作一個 SMS 主要站台的用戶端來管理。在這個虛構的環境中,安全性原則可能會規定技術支援工程師必須先獲得使用者允許之後,才能在遠端控制他們的機器。如果技術支援工程師希望使用遠端控制來連接伺服器,那就做不到了:因為在一般情況下不會有使用者登入伺服器,所以也沒有人可以授予遠端控制權。雖然只要審慎套用本機原則,或許可以在某些特定用戶端上覆寫必須獲得使用者允許的規定,但是談何容易呢?您大概可以想像得出其他許多 SMS 本機原則有用處的情況,允許特定 SMS 用戶端代理程式的設定有所例外。

Windows PowerShell 嵌入式管理單元的內幕

熟悉 Windows PowerShell 的基本原理之後,您就可以加入本專欄所提供的原始程式碼範例,從命令列擴充您對 SMS 用戶端本機原則的權限。有些屬性在開放給 Windows PowerShell 之前,最好先將它們套用到類別。您必須決定 Cmdlet 的目的,以及應該採取的動作。這就是所謂的「動詞-名詞」組合。一般在 Windows PowerShell 出現的動詞有 Add、Get 和 Set。名詞部分則代表您要採取動作的物件。Cmdlet 通常附有參數,這些參數在 Cmdlet 類別中被宣告為各種型別的公用屬性。還有一點,ProcessRecord 函數是主要的工作區,您大部分的工作都是在這裡執行。[圖 1] 是您可以用在自己專屬 Cmdlet 的一般範本。

Figure 1 Cmdlet 範本

[Cmdlet( "Verb", "Noun", SupportsShouldProcess = true )]
public class Verb_Noun : PSCmdlet
{
    [Parameter( ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, 
        HelpMessage = "Parameter" )]
    [ValidateNotNullOrEmpty]
    [Alias( "param" )]
    public string Parameter
    {
        get { return MyParameter; }
        set { MyParameter = value; }
    }
    private string MyParameter;

    protected override void ProcessRecord( )
    {
        //Do your stuff here!
    }
}

當嵌入式管理單元編譯完成之後,您就可以在定義 RunInstaller 屬性集和一些特定屬性的專案中加入一個類別,將它登錄到 Windows PowerShell。如需相關細節,請參閱本文所附的原始程式碼。若要登錄您的嵌入式管理單元,必須使用 Microsoft® .NET Framework 附隨的 InstallUtil.exe 工具。[圖 2] 是登錄嵌入式管理單元所用的語法。請注意,如果您是使用 Windows Vista®,則必須提高權限才能執行這項作業,您可以選擇「以系統管理員的身分開啟」,或者使用 Script Elevation PowerToys for Windows Vista (可在 technetmagazine.com/issues/2007/06/UtilitySpotlight 下載),來開啟 Windows PowerShell。

Figure 2 從 Windows PowerShell 安裝嵌入式管理單元

PS> set-alias installutil $env:windir\Microsoft.NET\Framework\v2.0.50727\installutil 
PS> installutil C:\MySMSTools\SMS2003PowerShellSnapinSample.dll 
Microsoft (R) .NET Framework Installation utility Version 2.0.50727.42 
Copyright (C) Microsoft Corporation. All rights reserved. 
Running a transacted installation. 
... 
The transacted install has completed.

接著就是判斷 Windows PowerShell 是否認可您的嵌入式管理單元。只要使用附有已登錄參數的 Get-PSsnapin cmdlet,Windows PowerShell 就會總結列出目前載入的嵌入式管理單元,後面附加一份即將加入的已登錄嵌入式管理單元清單。您的嵌入式管理單元應該就列在這份清單當中:

PS> Get-PSsnapin -registered

現在您就可以使用 Add-PSsnapin Cmdlet,將 Windows PowerShell 嵌入式管理單元加入命令介面中,如下所示:

PS> add-pssnapin SMS2003PowerShellSnapinSample

完成這項作業之後,應該就能在您的 Windows PowerShell 嵌入式管理單元中執行 Cmdlet 了。

若要查看任何 Windows PowerShell 嵌入式管理單元所能使用的 Cmdlet,只要以 Get-Command Cmdlet 指定特定的嵌入式管理單元,並且將嵌入式管理單元的名稱作為 PSsnapin 參數的值傳遞即可。本專欄所附的這個嵌入式管理單元範例,一共有六個 Cmdlet,其中包括「動詞-名詞」Cmdlet 範本在內,如 [圖 3] 所示。

[圖 3] 將 Cmdlet 顯示在嵌入式管理單元中

[圖 3]** 將 Cmdlet 顯示在嵌入式管理單元中 **(按影像可放大)

我在原始程式碼範例中,專門為 Get-SMSServerConnection Cmdlet 寫了說明來解說它的架構。如果您要擴充說明,可以參考 XML 檔中的範例。[圖 4] 所顯示的是說明輸出。

現在您已經知道如何安裝 Windows PowerShell 嵌入式管理單元、如何找出嵌入式管理單元中有哪些命令,以及如何取得標準 Cmdlet 的說明了,接著我們就開始使用 Cmdlet 吧。您可以使用下面這個命令,列出 SMS 主要站台伺服器中所有的集合:

PS > Get-SMSServerConnection -server MYSMSSERVER | Get-Collections | Format-Table Name

請注意管線。這是讓 Windows PowerShell 運作的核心部分,它是功能相當強大的工具。只要一行就足以在 Windows PowerShell 做任何事情。Get-SMSServerConnection Cmdlet 會連接 SMS 伺服器。Get-Collections Cmdlet 有一個 Get-SMSServerConnection 傳回的型別的輸入參數,因此您只要把 Get-SMSServerConnection Cmdlet 的輸出傳到 Get-Collections Cmdlet 即可。這就是管線運作的方式。此外,它也很清楚的告訴您,如何將複雜物件從一個 Cmdlet 傳到另一個 Cmdlet。您也可以將物件儲存在變數中,如果您在 Windows PowerShell 指令碼中寫了這個動作,結果將如下所示:

$SMS = Get-SMSServerConnection 
     -server MYSMSSERVER
Get-Collections -SMSServerProvider $SMS

如果不將輸出好好格式化一番,大概很難看懂,因為 Get-Collections 傳回的是 SMSCollections 型別的物件 (基本上是 SMSCollection 型別的物件陣列)。簡單的說,除非過濾掉不感興趣的集合,或者把只含有中意屬性的表格加以格式化,否則這個畫面不會太好看。而作法是將輸出透過管線,從 Get-Collections Cmdlet 傳到 Format-Table Cmdlet,這樣就只會顯示您所指定的屬性了。舉個例說,您可以附加 | Format-Table Name, Members。

其實要顯示某一個集合的所有成員,還有一個更好的方法,在本例當中這個方法就是 Get-CollectionMembers。這個 Cmdlet 會傳回一個字串陣列,代表集合中每一個成員的名稱。或許您已經猜到,這就是將管線傳給下一個 Cmdlet 的絕佳人選。

到目前為止,我們還沒有用到 SMS 進階用戶端本機原則,而只是連接到 SMS 主要站台伺服器,以及列舉集合與集合成員而已。Windows PowerShell 嵌入式管理單元範例最後出場的兩個 Cmdlet (名稱分別為 Enable-SoftwareDistribution 和 Disable-SoftwareDistribution),才是 SMS 用戶端本機原則要派上用場的地方。最後這兩個 Cmdlet 的用途,是針對 SMS 進階用戶端上的軟體散發用戶端代理程式元件,來操作 SMS 用戶端本機原則。也許您已經從 Cmdlet 的動詞部分猜到了,Disable 會佈下一個用戶端本機原則覆寫項,指定同時停用軟體散發用戶端代理程式。同樣的,動詞 Enable 則會移除所有的用戶端本機原則覆寫項,將軟體散發用戶端代理程式還原為正常狀態,這是由 SMS 管理點交付的 SMS 原則所定義。[圖 5] 顯示了 Windows PowerShell 單行指令的範例,在軟體散發用戶端代理程式上佈下一個 SMS 用戶端本機原則覆寫項,強迫 Windows Server 2003 系統自訂集合的所有成員都停用它。移除同一集合軟體散發用戶端代理程式的所有 SMS 用戶端本機原則覆寫項的單行指令,也會一併列出。如果您只想用幾部電腦來操作 SMS 用戶端本機原則,也可以單獨使用 Disable-SoftwareDistribution 和 Enable-SoftwareDistribution Cmdlet。

Figure 5 組合 cmdlet — 範例

PS >Get-SMSServerConnection -server MYSMSSERVER | Get-Collections | where-object {$_.Name -eq "Windows Server 2003 Systems"} | Get-CollectionMembers | Disable-SoftwareDistribution 
PS >
PS > Get-SMSServerConnection -server MYSMSSERVER | Get-Collections | where-object {$_.Name -eq "Windows Server 2003 Systems"} | Get-CollectionMembers | Enable-SoftwareDistribution
PS >
PS >Disable-SoftwareDistribution –hosts SMSCLIENT1, SMSCLIENT2, SMSCLIENT3
PS >
PS >Enable-SoftwareDistribution –hosts SMSCLIENT1, SMSCLIENT2, SMSCLIENT3

下一步

如果您想學習將 SMS 用戶端本機原則覆寫項套用到電腦群組,本文所附的原始程式碼範例可以提供您一個好的起點。此處提供的範例只跟 SMS 軟體散發用戶端代理程式有關,而且只用到 Enabled 屬性。其他用戶端代理程式還有許多屬性,也可以用同樣的方式套用覆寫項。有了初步瞭解之後,接下來就要看看 SMS 用戶端本機原則的其他部分了。您可以想一想哪些管理系統群組可以用在 SMS 用戶端本機原則覆寫項,以及哪些本機原則覆寫項值得使用。最後的叮嚀:無論做什麼都要先明確釐清自己的方向,因此在實驗室環境中,一定要徹底測試每一個項目。

Don Brown 在 Microsoft 擔任資深首席外勤工程師,從有印象以來便開始研究並支援 SMS (就是 SCCM),至今仍未間斷。他的連絡方式為:donbrown@microsoft.com

© 2008 Microsoft Corporation and CMP Media, LLC. 保留所有權利;未經允許,嚴禁部分或全部複製.