共用方式為


System Center

System Center Operations Manager 中的 Windows PowerShell

Marco Shaw

 

綜覽:

  • OpsMgr 命令殼層
  • OpsMgr 監視提供者
  • 自動化一般管理工作
  • 一些 Windows PowerShell 的實例

目錄

Operations Manager 命令殼層
OpsMgr 監視提供者
自動化一般工作
真實世界
總結

System Center Operations Manager 2007 (OpsMgr) 讓系統管理員能夠存取 Windows PowerShell,這是用於自動化工作的超強新指令碼語言。它自 2006 年 11 月公開發行以來,下載次數已超過兩百萬次。

在本文中,我將討論 Windows PowerShell®,並探討如何將它應用到 Operations Manager 中。我會說明一些可透過 Windows PowerShell 幫助您以更加簡單及更自動化的方式來完成的一般工作,並介紹幾個提供實用指令碼和說明的網站。我也整理了當今許多使用 Windows PowerShell 的專家們的見解和部落格文章。

雖然 Microsoft 已相繼發行了 Windows PowerShell 2.0 的 Community Technology Preview (CTP) 版本,但這些版本既不適用於生產環境,也未經過 OpsMgr 的測試,因此不應該安裝在生產系統上。

Operations Manager 命令殼層

在 OpsMgr 中,您是透過命令殼層存取 Windows PowerShell,這跟預設的 Windows PowerShell 環境很類似,差別在於它會載入主控台檔案,另外也會載入指令碼,這個指令碼會利用 OpsMgr 指令程式、函數和預設連線將環境初始化。

您可以從 OpsMgr [開始] 功能表上的圖示,或是在 OpsMgr UI 主控台中的電腦名稱上按右鍵來啟動命令殼層 (見 [圖 1])。這會直接把您帶到 OpsMgr 監視磁碟機路徑中 (我稍後會討論到)。

fig01.gif

[圖 1] 從 OpsMgr UI 開啟命令殼層 (按一下以放大影像)

Windows PowerShell 是透過 OpsMgr SDK 與 OpsMgr 互動。幸運的是,對系統管理員來說,您一般想要從命令列自動化或完成的許多工作,都已經有提供指命程式。如果特定的工作沒有可用的指令程式,您可以使用 Windows PowerShell 與 SDK 互動。

Operations Manager 命令殼層所提供的命令都包含在嵌入式管理單元中 — 這是由 Windows PowerShell 載入的 DLL,當中包含了用於 OpsMgr 系統管理的指令程式。這個嵌入式管理單元也包含了 OperationsManagerMonitoring Windows PowerShell 提供者,亦稱為監視提供者,這項工具可讓您瀏覽連線、群組和監視物件,跟瀏覽檔案系統很像。

您可以使用 Get-OperationsManagerCommand 指令程式取得 OpsMgr 專用的完整指令程式清單,如 [圖 2] 所示 (它在第一版是個函數,因為不支援 Tab 鍵自動完成功能,所以在 SP1 變成指令程式)。Operations Manager 的原始版包含 74 個指令程式,而 OpsMgr SP1 則有 87 個。

fig02.gif

[圖 2] 取得 OpsMgr 指令程式的清單 (按一下以放大影像)

OpsMgr 監視提供者

藉著使用 Set-Location 指令程式,或是 alias cd,您可以一一瀏覽群組和電腦的配置。預設 Monitoringdrive 的基本配置看起來如下:

Monitoring:\->RMS->Groups (as defined in OpsMgr)
  ->Computers(as defined in OpsMgr)

您可以從這裡接觸到更特定的物件。請注意,我在此案例中處理的是簡單的環境,也就是只有一部管理伺服器。安裝在管理群組內的第一部管理伺服器稱為 Root Management Server (RMS)。

命令殼層啟動時會建立一個稱為 Monitoring 的磁碟機,將該磁碟機對應到 OperationsManagerMonitoring 提供者的根目錄,最後將目前的位置或路徑設定為 Monitoring 磁碟機的根目錄。命令殼層接著會搜尋登錄,尋找要連接之預設 RMS 的名稱。如果與 RMS 的連線成功,則目前的位置或路徑便會設為該連線或 RMS 的名稱,如 [圖 3] 所示。

fig03.gif

[圖 3] 命令殼層位置設為 RMS (按一下以放大影像)

自動化一般工作

讓我們來瞧瞧 Windows PowerShell 如何處理一些最常見的管理工作。

控制維護模式 無論您處理的是哪項工作,通常都要指定該工作應該發生的日期和時間。我將簡單介紹一下 Get-Date 指令程式,向您說明要這麼做有多簡單。[圖 4] 顯示了幾個範例。

fig04.gif

[圖 4] 使用 Get-Date 指令程式 (按一下以放大影像)

如您所見,我建立了一個 $date 變數,當中包含了表示目前時間的物件。我接下來使用該物件支援的一些記錄方法來說明您如何能夠輕易地在五分鐘及五小時之後,分別取得日期和時間。如果我想要取得過去的值,只要使用 (-5) (-5) 來取代 (5) 就成了。

當您需要封鎖來自某電腦的所有警示時,可啟用維護模式。OpsMgr 2007 可讓您將 Windows® 服務,甚或是特定的資料庫,而不是整部電腦或群組置於維護模式。專門處理維護模式工作的指令程式有三種:Get-MaintenanceWindow、New-MaintenanceWindow 和 Set-MaintenanceWindow。

若要從命令殼層內部將電腦置於維護模式,請使用監視提供者瀏覽至所要的電腦或監視物件,然後叫用 New-MaintenanceWindow 指令程式,如 [圖 5] 所示。如您所見,這個動作會將稱為 Denver.contoso.com 的電腦置於維護模式。我同時也定義了維護視窗的開始時間立即生效,而結束時間則在整整一個小時之後生效。請注意,使用這種方法將電腦置於維護模式並不會停止所有警示,因為這個物件的 HealthService 和 HealthServiceWatcher 執行個體仍舊處於啟用狀態。

fig05.gif

[圖 5] 使用 New-MaintenanceWindows 指令程式 (按一下以放大影像)

Microsoft OpsMgr 小組的專案經理 Boris Yanushpolsky 提供了一些非常實用的 Windows PowerShell 程式碼,這些程式碼可用來將所有參考電腦的物件設定成維護模式,他也解釋了如何在建立好指令碼之後使用這個程式碼。若要閱讀相關的詳細資訊,請參閱他的部落格,網址是 blogs.msdn.com/boris_yanushpolsky/archive/2007/07/25/putting-a-computer-into-maintenance-mode.aspx

有時候您必須判斷處於維護模式的物件是否真的應該處於該狀態。然而,一一巡視所有的物件來試著做出判斷可能是項相當艱鉅的任務。所幸,Boris Yanushpolsky 對此也有良策,那就是透過使用 OpsMgr SDK 的 Windows PowerShell 指令碼。您可以直接從他的部落格文章 (blogs.msdn.com/boris_yanushpolsky/archive/2007/08/06/so-what-is-in-maintenance-mode.aspx) 將這段程式碼貼到命令殼層視窗,來取得所有處於維護模式的物件清單。

當某物件處於維護模式時,您應該在原始指定的結束時間之前結束維護期間。如果您對 Windows PowerShell 不陌生,可能會預期這樣的指令程式應該含有 Stop 或 Remove 等動詞,但實際上您必須使用 Set-MaintenanceWindow,如 [圖 6] 所示。

fig06.gif

[圖 6] 使用 Set-MaintenanceWindows 來變更結束時間 (按一下以放大影像)

管理代理程式 系統管理員經常用到代理程式,就目前版本而言,有六個指令程式和一個函數可用來處理各種與代理程式相關的工作。您可以使用以下命令取得這份清單:

Get-Command *-agent*

自 SP1 版起,Install-AgentByName 不再是函數,而改成封裝為指令程式。因此建議您使用 Install-AgentByName 指令程式,因為它在支援和一致性方面提供較佳的基礎。

命令殼層所含的內建說明提供了一些使用 Install-Agent 和 Uninstall-Agent 指令程式的不錯範例。Microsoft OpsMgr 小組的資深軟體設計工程師 Roger Sprague,在他的部落格上也發表了一個替代方法,[圖 7] 中重現了此方法 (請參考他的原始文章,網址是 blogs.msdn.com/scshell/archive/2006/09/28/getting-started.aspx)。

這段指令碼用在 OpsMgr RTM 沒什麼問題 (您必須位在監視提供者的根目錄 — 在本文中,即 monitoring:\oxford.contoso.com),但不能用於 OpsMgr SP1。若要讓它能夠用在 OpsMgr SP1 中,應該將 [圖 7] 中的第一個命令變更如下:

 $managementServer = Get-RootManagementServer

[圖 7] 安裝代理程式

# Get the Root Management Server.
$managementServer = Get-ManagementServer -Root: $true

# Create the discovery configuration for computer2 and computer3.
$discoConfig = New-WindowsDiscoveryConfiguration -ComputerName: computer2, computer3

# Discover the computers.
$discoResult = Start-Discovery -ManagementServer: $managementServer -WindowsDiscoveryConfiguration: $discoConfig

# Install an agent on each computer.
Install-Agent -ManagementServer: $managementServer -AgentManagedComputer: $discoResult.CustomMonitoringObjects

到目前為止,代理程式是安裝在應該要監視的遠端系統上,但最後還有一個步驟,就是管理伺服器必須實際接受新代理程式,才能完整進行監視。如果沒有採取任何後續的動作,監視伺服器會自動接受新代理程式以進行監視。不過使用 Get-AgentPendingAction 指令程式也可以快速追蹤到這個接受程序。這一行程式碼可快速追蹤代理程式接受程序:

Get-AgentPendingAction | Where Object {$_.AgentName –like 
'computer*'} | Approve-AgentPendingAction

將這一行代入 Reject-AgentPendingAction,而不是 Approve-AgentPendingAction,您就可以在動作仍處於待決狀態時,封鎖 OpsMgr 伺服器接受這個代理程式。如果動作已決,請改用 Uninstall-Agent 指令程式。

如前所述,您也可以使用 Install-AgentByName,從命令列直接在要安裝代理程式的地方指定電腦。

使用管理套件 有四個指令程式可幫助您處理各種管理套件工作。您可以使用這個命令將它們列出:

Get-Command –noun ManagementPack

這個簡單的命令會提供目前安裝的管理套件,及其版本號碼:

Get-ManagementPack | Format-Table –autosize

現在我要使用命令殼層來安裝兩個使用這些安裝程式的一般管理套件:

  • Internet Information Services System Center Operations Manager2007 Management Pack.msi
  • Windows Server® Base OS System Center Operations Manager2007 Management Pack.msi

既然此處的目標是要展示命令殼層如何能讓常規的工作更加簡單,因此我要盡可能用最少的命令來進行此動作 (如 [圖 8] 所示)。我其實可以變更這個安裝程序,將無訊息旗標傳遞給安裝程式 (.msi 檔案),但是我想要選擇可手動解壓縮的檔案位置。

fig08.gif

[圖 8] 安裝管體套件 (按一下以放大影像)

接下來,我必須安裝通用程式庫,這可以使用下面的命令來進行:

Get-ChildItem –Path C:\MPs –filter *Library.mp |
ForEach-Object
  {Install-ManagementPack –filePath $_.FullName}

然後我安裝了其他必要的管理套件:

Get-ChildItem –Path C:\MPs –filter *200?.mp | 
ForEach-Object
  {Install-ManagementPack –filePath $_.FullName}

[圖 9] 所示,內建的命令殼層說明提供了絕佳的範例,示範使用 Export-ManagementPack 指令程式來匯出未密封的管理套件。如果您想要匯出所有管理套件,請變更此行:

 $mps=Get-ManagementPack | 
Where-Object {$_.Sealed –eq $false} 
 $mps=Get-ManagementPack

fig09.gif

[圖 9] 匯出管理套件 (按一下以放大影像)

操控使用者角色 Get-UserRole 指令程式提供了一些可用來管理使用者的功能,但奇怪的是,它並沒有附隨補充的 Set 指令程式,因此您通常不會使用它來進行編輯或更新作業 (根據 Windows PowerShell SDK 說明文件)。如您在 [圖 10] 中所見,我先取得一份目前使用者角色的清單,然後新增一名使用者到「唯讀操作員」群組 (見 [圖 11])。

fig10.gif

[圖 10] 顯示使用者角色 (按一下以放大影像)

fig11.gif

[圖 11] 新增使用者 (按一下以放大影像)

啟用稽核收集服務 (ACS) ACS 是 Operations Manager 2007 中全新的選用功能,簡單的說,它提供了一種集中化方法來處理安全性稽核資訊。ACS 根據預設並不會啟用,一般來說,之後可以在未來的 OpsMgr 部署階段中設定。

需要針對 ACS 啟用大量代理程式時,Windows PowerShell 就派上用場了,它可以幫助自動化安裝程序。在 OpsMgr 的 Beta 測試期間,Microsoft 提供了一個指令碼來啟用所有代理程式上的 ACS。SystemCenterForum.org 的撰文者和部落格作者 Neale Browne 則進一步發揚光大,加入了對其他參數的支援。

SystemCenterForum.org 網站 (提供 Microsoft® System Center 解決方案的社群網站) 提供了兩種不同的 Windows PowerShell 指令碼,用於自動化 ACS 的安裝程序。若要設定特定群組內的所有代理程式,請使用 systemcenterforum.org/wp-content/uploads/ACSBulkEnableGroupDisplayName.zip。若要設定所有監視的代理程式,請下載 systemcenterforum.org/wp-content/uploads/ACSBulkEnableAllAgents.zip

啟用代理程式 Proxy 處理 您的 OpsMgr 環境可能包括無代理程式監視的裝置。這些裝置必須指派給管理伺服器,或是指派給由代理程式管理且提供遠端監視的裝置。您可以在 systemcenterforum.org/enable-agent-act-as-a-proxy-in-bulk-via-powershell 找到關於使用 Windows PowerShell 指令碼設定大量代理程式的詳細說明。指令碼的更新版本可自 systemcenterforum.org/wp-content/uploads/SetAgentProxyBulk_FQDN.zip 取得。

還有其他條件,就是特定管理套件要求必須將代理程式設成 Proxy。如需詳細資料,請查閱管理套件說明文件。

真實世界

以下是進一步示範 Windows PowerShell 如何促進自動化的一些實例。

解析警示 您曾碰過必須刪除特定電腦上好幾個警示的情況嗎?或許是因為應用程式出錯,或是警示未經積極解析。以下這行命令將解析所有解析狀態為零的警示:

Get-Alert –criteria 'ResolutionState = ''0''' |
Resolve-Alert | Out-Null

下一個範例的作用與前者一樣,但是它在擁有較多待決警示的較大規模環境內執行起來要快速許多:

Get-Alert | Where-Object {$_.ResolutionState -eq 0} |
Resolve-Alert | Out-Null

效能方面之所以會有此差別,背後的原因是,當使用條件參數時,傳遞的值是直接提供給 SQL Server® 資料庫,而且只會傳回相關的資料。這減少了必須一路傳回 Windows PowerShell 主控台的物件數量。

現在您有一個快速的方法可以移除單一電腦所有待決的警示。您可以根據您的需求將此設為自動執行。

最後,下面這個快速命令可讓您檢視特定一天內的所有警示:

Get-Alert -criteria 'TimeRaised >= ''4/25/2008'''

您可以輕易變更日期值,並將輸出代入 Resolve-Alert 指令程式。

測試警示 您有時候會希望能夠監視 Windows 事件檢視器裡面的特定事件,然後進行測試。這兩行可快速建立事件日誌項目:

 $api=New-Object -comObject MOM.ScriptAPI
$api.logscriptevent("API test",100,0,
  "Test using PowerShell")

不過,這預設會寫入 Operations Manager 事件日誌,您平常可能不會到這裡查看特定的事件記錄。所幸,Microsoft 的專案領域工程師 Stefan Stranger 寫了一個指令碼,可在 Windows 事件檢視器內建立事件,而且它還提供較高的彈性讓您寫入特定記錄檔。您可以在 go.microsoft.com/fwlink/?LinkId=120308 找到此指令碼 (Stefan 已將此指令碼封裝成 .cab 檔案。您必須下載該檔案,然後以滑鼠右鍵按一下此檔案來解壓縮他的指令碼)。

對於 Stefan 的指令碼,唯一要特別注意的是,為事件來源輸入的值會決定要將項目寫入哪個記錄檔。若要確保警示確實導向適當的記錄檔,最簡單的方法可能是開啟 Windows 事件檢視器,然後尋找最新項目的來源。

設定所有人 自動設定警示的所有人有時候可能蠻有用的。以下是從命令殼層進行此動作的簡單方法:

 $alert = Get-Alert 
  -id f3f73d62-37ab-45ce-a7ff-2bdda0dfaeb4
$alert.set_owner("Administrator")
$alert.update("Updated owner")

此程式碼的第一行會取得特定警示物件的識別碼,然後將它傳遞給 $alert 變數。在第二行中,會使用該變數設定所有人,最後會將更新套用到 OpsMgr 資料庫。如果您使用下列命令來檢查警示的所有人,會看到它已變更:

Get-Alert -id f3f73d62-37ab-45ce-a7ff-2bdda0dfaeb4 |
Select-Object Owner

若要設定整組警示的所有人,您可以將程式碼簡化如下:

Get-Alert | ForEach-Object {$_.Set_
  Owner("Administrator");
  $_.Update("Owner set")}

還原監視狀態 您很有可能會碰到處於「未監視」狀態的代理程式。發生這種情況時,您可能必須快速地將所有代理程式還原成完整的監視狀態,然後嘗試判斷發生了什麼情況。直接從命令殼層執行 [圖 12] 中的指令碼應該可還原任何受影響代理程式的完整監視狀態。

[圖 12] 重設健全狀況服務儲存區

 $all="Microsoft.SystemCenter.AllComputersGroup"
$agents = Get-ChildItem Microsoft.SystemCenter.AllComputersGroup | `
  Where-Object {$_.HealthState -eq 'Uninitialized'}
foreach ($agent in $agents)
{
$agent.DisplayName
Push-Location $all\$agent\Microsoft.SystemCenter.HealthService
Get-Task | Where-Object {$_.Name -eq "Microsoft.SystemCenter.ResetHealthServiceStore"} | `
    Start-Task -Asynchronous
Pop-Location
}

請看一下 [圖 12] 中的程式碼。宣告變數之後,我取得了這個 RMS 上所有代理程式的清單,然後篩選出看似有問題的代理程式。接著,我以非同步的方式呼叫了一項工作,藉此重設篩選清單中所有代理程式上的健全狀況服務儲存區。

建立警示與管理套件的關聯 [圖 13] 說明如何取得所有新警示,以及各自相關聯的管理套件清單。

這段程式碼需要一些技巧,以確定所有管理套件名稱都可以解析。所用的指令程式將視警示是來自規則或是監視器而異 (請注意在 [圖 13] 中,我需要為 Get-Monitor 指令程式實作一個小小的變通辦法。自 OpsMgr SP1 開始,這個指令程式支援新的 ID 參數,可稍微簡化此程式碼)。

[圖 13] 尋找管理套件

Get-Alert | Where-Object {($_.PrincipalName -ne $null) -and ($_.ResolutionState = '0')}| `
Format-Table –autosize PrincipalName,Severity, `
  @{Label="MP"
      Expression={If(!($_.IsMonitorAlert)){
        ForEach-Object {
          ((Get-Rule $_.MonitoringRuleId).GetManagementPack()).DisplayName}
       }  
       Else{
         ForEach-Object {
          $id=$_.ProblemId
          ((Get-Monitor -criteria "Id='$id'").GetManagementPack()).DisplayName}
         }
   }
}

簡易報告功能 將環境升級時,稽核所有安裝的代理程式版本可能蠻有用的。只要一個簡單的指令碼,就可以列印出一份不錯的報告:

Get-Agent| `
Format-Table DisplayName,@{ `
  Label="Version"
  Expression={ `
    switch ($_.Version){
    "6.0.5000.0" {"RTM"}
    "6.0.6246.0" {"SP1 (RC)"}
    "6.0.6278.0" {"SP1 (RTM)"}
    }
  }
}

[圖 14] 顯示指令碼的輸出。這個指令碼是 systemcenterforum.org/checking-operations-manager-2007-agent-and-server-versions-via-powershell 中提供的範例的擴充版。

fig14.gif

[圖 14] 顯示部分代理程式版本的輸出 (按一下以放大影像)

排定工作 您可能會想要定期執行 Windows PowerShell 指令碼。假設您使用一部用戶端電腦連接並管理您的 OpsMgr 伺服器,而您將 OpsMgr 系統管理工具安裝在本機。再假設,您想要每天執行代理程式版本報告,而且將輸出儲存到檔案,並使用目前的日期作為檔名。您可以使用 Windows 內建工作排程器從本機電腦執行指令碼。

要這麼做,只要使用設定為 powershell.exe (一般是位於 C:\Windows\System32\WindowsPowerShell\v1.0) 的程式建立新工作就行了。建立工作之後,進行編輯,然後將要執行的命令設定如下:

C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe 
  –Command "& {& 'c:\agent_report2.ps1'}"

結果我必須對原始的 Windows PowerShell 程式碼多做好幾項變更,如您在 [圖 15] 中所見。我必須新增 OpsMgr PowerShell 嵌入式管理單元,建立對應到 OperationsManagerMonitoring 提供者的 Monitoring 磁碟機,以及建立與 RMS 的連線。我另外還載入了 OpsMgr 自訂 Windows PowerShell 指令碼 (Microsoft.EnterpriseManagement.OperationsManager.ClientShell.Startup.ps1) 以載入 OpsMgr 專用的函數。

[圖 15] 排定代理程式版本指令碼

Add-PSSnapin Microsoft.EnterpriseManagement.OperationsManager.Client
New-PSDrive Monitoring Microsoft.EnterpriseManagement.OperationsManager.Client\
  OperationsManagerMonitoring ""
New-ManagementGroupConnection Oxford.contoso.com

Set-Location 'C:\Program Files\System Center Operations Manager 2007'
./Microsoft.EnterpriseManagement.OperationsManager.ClientShell.NonInteractiveStartup.ps1

$file="C:\$(Get-Date -f `"MMddyyyy`").rpt"

Get-Agent -Path Monitoring:\Oxford.contoso.com | `
Format-Table DisplayName,@{ `
  Label="Version"
  Expression={ `
    switch ($_.Version){
    "6.0.5000.0" {"RTM"}
    "6.0.6246.0" {"SP1 (RC)"}
    "6.0.6278.0" {"SP1 (RTM)"}
    }
  }
} | Out-File $file

但不止於此,您可能還會注意到工作每次一執行時,如果有人登入正在執行指令碼的系統,畫面上都會出現一個黑色的主控台視窗。您可以參考由 Sapien 的 Don Jones 與 Jeffery Hicks 所提供的些小秘訣來解決這個問題,網址是 blog.sapien.com/index.php/2006/12/26/more-fun-with-scheduled-powershell

基本上,您必須將指令碼包裝在 VBScript 內。要這麼做,您使用如 [圖 16] 中的程式碼,而不是從排定工作呼叫下列命令:

C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe
  –Command "& {& 'c:\agent_report2.ps1'}"

[圖 16] 隱藏快顯畫面

Dim objShell
Set objShell=CreateObject("WScript.Shell")

'enter the PowerShell expression you need to use short filenames and paths 
strExpression="'c:\agent_report2.ps1'"

strCMD="powershell -nologo  -command " & Chr(34) & _
"&{&" & strExpression &"}" & Chr(34) 

'Uncomment next line for debugging
'WScript.Echo strCMD

'use 0 to hide window
objShell.Run strCMD,0

此工作現在會使用 wscript.exe 程式,而呼叫的內容看起來像這樣:

C:\WINDOWS\System32\wscript.exe C:\agent_report.vbs 

最後,我可以建立自動化報告,而且登入的使用者看不到整個過程。

總結

本文針對 OpsMgr 2007 的自動化新功能提供快速導覽,不過這些只是使用 Windows PowerShell 來處理 OpsMgr 系統管理的皮毛而已。

我想要藉此感謝在文中提及的所有人員,以及 Pete Zerger、MOM MVP 和 SystemCenterForum.org 的創辦人,他們為本文提供重要協助。

Marco Shaw 是加拿大電信公司的 IT 系統分析師。他在 IT 產業工作已有 10 年以上的資歷,並且最近剛榮獲 Windows PowerShell MVP 頭銜。Marco 也是新 PowerShell 社群網站的社群助理董事,網址是 powershellcommunity.org。他的部落格位於 marcoshaw.blogspot.com

© 2008 Microsoft Corporation and CMP Media, LLC.著作權所有,並保留一切權利。未經許可,不得部分或全部重製。