PowerShell 2.0 實踐(三)操作Windows服務
上一次我們學習了文件系統的操作,能夠讀取、寫入基于文本的文件,搜索本地及遠程文件、目錄。本次我們來操作下Windows服務,首先來回顧一下Windows服務的基本概念:
本系列所有腳本均在Windows Server 2008 R2 DataCenter (PowerShell 2.0) + PowerGUI Script Editor Free Edition x64中測試通過。
1、Windows服務介紹(摘自MSDN)
Microsoft Windows 服務(即,以前的 NT 服務)使您能夠創建在它們自己的 Windows 會話中可長時間運行的可執行應用程序。這些服務可以在計算機啟動時自動啟動,可以暫停和重新啟動而且不顯示任何用戶界面。這些功能使服務非常適合在服務器上使用,每當需要使用不會影響在同一臺計算機上工作的其他用戶的功能時也適用。還可以在不同于登錄用戶的特定用戶帳戶或默認計算機帳戶的安全上下文中運行服務。有關服務和 Windows 會話的更多信息,請參見 MSDN Library 的 Platform SDK 文檔中的關于服務一節。
通過創建作為服務安裝的應用程序,可以輕松地創建服務。例如,假設要監視性能計數器數據并對閾值做出反應。可以編寫一個偵聽性能計數器數據的 Windows 服務應用程序、部署該應用程序并開始收集和分析數據。
將服務創建為 Microsoft Visual Studio 項目,并在其中定義代碼,以控制哪些命令可以發送到服務以及接收到這些命令時采取的操作。可以發送到服務的命令包括啟動、暫停、繼續和停止該服務;還可以執行自定義命令。
創建并生成了應用程序后,可以通過運行命令行實用工具 InstallUtil.exe 并將路徑傳遞給服務的可執行文件,或通過使用 Visual Studio 的部署功能來安裝該應用程序。然后可以使用"服務控制管理器"啟動、停止、暫停、繼續和配置服務。這些任務中的許多種也可以在"服務器資源管理器"的"服務"節點中或通過使用 ServiceController 類來完成。
服務應用程序與其他 Visual Studio 應用程序
服務應用程序與其他許多項目類型的功能在幾個方面有所不同:
- 必須將服務應用程序項目創建的已編譯可執行文件安裝在服務器上,此項目才能以有意義的方式運行。不能通過按 F5 或 F11 來調試或運行服務應用程序;不能立即運行服務或進入其代碼。相反,必須安裝和啟動服務,然后將一個調試器附加到服務的進程中。有關更多信息,請參見 如何:調試 Windows 服務應用程序。
- 與一些類型的項目不同,對于服務應用程序,必須為其創建安裝組件。安裝組件在服務器上安裝和注冊服務,并用 Windows"服務控制管理器"為服務創建一個項。有關更多信息,請參見如何:將安裝程序添加到服務應用程序。
- 服務應用程序的 Main 方法必須為項目包含的服務發出 Run 命令。Run 方法將服務加載到適當服務器上的"服務控制管理器"中。如果使用"Windows 服務"項目模板,系統將自動為您寫入此方法。注意,加載服務與啟動服務不同。有關更多信息,請參見下面的"服務生存期"。
- Windows 服務應用程序在不同于登錄用戶的交互區域的窗口區域中運行。窗口區域是包含剪貼板、一組全局原子和一組桌面對象的安全對象。由于 Windows 服務的區域不是交互區域,因此 Windows 服務應用程序中引發的對話框將是不可見的,并且可能導致程序停止響應。同樣,錯誤信息應記錄在 Windows 事件日志中,而不是在用戶界面中引發。
.NET Framework 支持的 Windows 服務類不支持與交互區域(即登錄用戶)進行交互。同時,.NET Framework 不包含表示區域和桌面的類。如果 Windows 服務必須與其他區域進行交互,則需要訪問非托管的 Windows API。有關更多信息,請參見 Platform SDK 文檔中的窗口區域和桌面。
設計 Windows 服務與用戶或其他區域的交互時必須非常小心,應考慮某些情況,例如沒有登錄的用戶或用戶具有一組意外的桌面對象的情況。在某些情況下,編寫一個在用戶控制下運行的 Windows 應用程序可能更為妥當。
- Windows 服務應用程序在各自的安全上下文中運行,并且在用戶登錄到安裝有該程序的 Windows 計算機之前啟動。應仔細計劃在哪些用戶帳戶內運行服務;在系統帳戶下運行的服務比在用戶帳戶下運行的服務具有更多的權限和特權。
服務生存期
服務在其生存期內要經歷幾個內部狀態。首先,將服務安裝在將要運行它的系統上。此過程執行服務項目的安裝程序,并將服務加載到該計算機的"服務控制管理器"中。"服務控制管理器"是由 Windows 提供的管理服務的核心實用工具。
Microsoft Windows 服務(即,以前的 NT 服務)使您能夠創建在它們自己的 Windows 會話中可長時間運行的可執行應用程序。這些服務可以在計算機啟動時自動啟動,可以暫停和重新啟動而且不顯示任何用戶界面。這些功能使服務非常適合在服務器上使用,每當需要使用不會影響在同一臺計算機上工作的其他用戶的功能時也適用。還可以在不同于登錄用戶的特定用戶帳戶或默認計算機帳戶的安全上下文中運行服務。有關服務和 Windows 會話的更多信息,請參見 MSDN Library 的 Platform SDK 文檔中的關于服務一節。
通過創建作為服務安裝的應用程序,可以輕松地創建服務。例如,假設要監視性能計數器數據并對閾值做出反應。可以編寫一個偵聽性能計數器數據的 Windows 服務應用程序、部署該應用程序并開始收集和分析數據。
將服務創建為 Microsoft Visual Studio 項目,并在其中定義代碼,以控制哪些命令可以發送到服務以及接收到這些命令時采取的操作。可以發送到服務的命令包括啟動、暫停、繼續和停止該服務;還可以執行自定義命令。
創建并生成了應用程序后,可以通過運行命令行實用工具 InstallUtil.exe 并將路徑傳遞給服務的可執行文件,或通過使用 Visual Studio 的部署功能來安裝該應用程序。然后可以使用"服務控制管理器"啟動、停止、暫停、繼續和配置服務。這些任務中的許多種也可以在"服務器資源管理器"的"服務"節點中或通過使用 ServiceController 類來完成。
服務應用程序與其他 Visual Studio 應用程序
服務應用程序與其他許多項目類型的功能在幾個方面有所不同:
- 必須將服務應用程序項目創建的已編譯可執行文件安裝在服務器上,此項目才能以有意義的方式運行。不能通過按 F5 或 F11 來調試或運行服務應用程序;不能立即運行服務或進入其代碼。相反,必須安裝和啟動服務,然后將一個調試器附加到服務的進程中。有關更多信息,請參見 如何:調試 Windows 服務應用程序。
- 與一些類型的項目不同,對于服務應用程序,必須為其創建安裝組件。安裝組件在服務器上安裝和注冊服務,并用 Windows"服務控制管理器"為服務創建一個項。有關更多信息,請參見如何:將安裝程序添加到服務應用程序。
- 服務應用程序的 Main 方法必須為項目包含的服務發出 Run 命令。Run 方法將服務加載到適當服務器上的"服務控制管理器"中。如果使用"Windows 服務"項目模板,系統將自動為您寫入此方法。注意,加載服務與啟動服務不同。有關更多信息,請參見下面的"服務生存期"。
- Windows 服務應用程序在不同于登錄用戶的交互區域的窗口區域中運行。窗口區域是包含剪貼板、一組全局原子和一組桌面對象的安全對象。由于 Windows 服務的區域不是交互區域,因此 Windows 服務應用程序中引發的對話框將是不可見的,并且可能導致程序停止響應。同樣,錯誤信息應記錄在 Windows 事件日志中,而不是在用戶界面中引發。
.NET Framework 支持的 Windows 服務類不支持與交互區域(即登錄用戶)進行交互。同時,.NET Framework 不包含表示區域和桌面的類。如果 Windows 服務必須與其他區域進行交互,則需要訪問非托管的 Windows API。有關更多信息,請參見 Platform SDK 文檔中的窗口區域和桌面。
設計 Windows 服務與用戶或其他區域的交互時必須非常小心,應考慮某些情況,例如沒有登錄的用戶或用戶具有一組意外的桌面對象的情況。在某些情況下,編寫一個在用戶控制下運行的 Windows 應用程序可能更為妥當。
- Windows 服務應用程序在各自的安全上下文中運行,并且在用戶登錄到安裝有該程序的 Windows 計算機之前啟動。應仔細計劃在哪些用戶帳戶內運行服務;在系統帳戶下運行的服務比在用戶帳戶下運行的服務具有更多的權限和特權。
服務生存期
服務在其生存期內要經歷幾個內部狀態。首先,將服務安裝在將要運行它的系統上。此過程執行服務項目的安裝程序,并將服務加載到該計算機的"服務控制管理器"中。"服務控制管理器"是由 Windows 提供的管理服務的核心實用工具。
服務加載后,必須啟動。啟動服務使服務開始運行。可以從"服務控制管理器"、從"服務器資源管理器"或通過調用 Start 方法從代碼啟動服務。Start 方法將處理傳遞給應用程序的 OnStart 方法并處理您在該處定義的任何代碼。
運行的服務可以以這種狀態無限期地存在下去,直到它被停止或暫停或者計算機關閉。服務可以以三種基本狀態之一存在:Running、Paused 或 Stopped。服務還可以報告掛起命令的狀態:ContinuePending、PausePending、StartPending 或 StopPending。這些狀態指示命令已經發出(如暫停正在運行的服務的命令),但尚未執行。您可以查詢 Status 以確定服務的狀態,也可以使用 WaitForStatus 在以上任一狀態出現時執行操作。
可以從"服務控制管理器"、從"服務器資源管理器"或通過從代碼調用方法來暫停、停止或繼續服務。每種操作都可以調用服務中的一個相關過程(OnStop、OnPause 或 OnContinue),在其中可以定義當服務狀態更改時所執行的其他處理。
服務類型
在 Visual Studio 中使用 .NET Framework 可以創建兩種類型的服務。進程中的唯一服務被指定為 Win32OwnProcess 類型。與其他服務共享進程的服務被指定為 Win32ShareProcess 類型。可通過查詢 ServiceType 屬性檢索服務類型。
如果查詢不是在 Visual Studio 中創建的現有服務,則偶爾還可能看到其他服務類型。有關這些內容的更多信息,請參見 ServiceType。
服務和 ServiceController 組件
ServiceController 組件用于連接到已安裝的服務并操作其狀態;使用 ServiceController 組件可以啟動和停止服務、暫停和繼續其運行以及將自定義命令發送到服務。但是,在創建服務應用程序時不需使用 ServiceController組件。實際上,多數情況下,ServiceController 組件存在于與定義服務的 Windows 服務應用程序不同的應用程序中。
部署和安裝服務
Visual Studio 隨附有安裝組件,這些組件可以安裝與服務應用程序相關的資源。安裝組件在正在安裝到的系統上注冊一項單個的服務,并使"服務控制管理器"知道該服務的存在。
在將安裝程序添加到應用程序之后,下一步是創建安裝項目,該項目將安裝已編譯的項目文件并運行安裝服務所需的安裝程序。若要創建完整的安裝項目,您必須將服務項目的輸出添加到該安裝項目,然后添加自定義操作以安裝您的服務。
2、PowerShell中關于服務的命令如下:
Get-Service | Set-Service |
Start-Service | Stop-Service |
Restart-Service | New-Service |
Suspend-Service | Resume-Service |
從字面意思就可以看出其作用,下面來測試一下。
2.1、獲取系統中的所有服務,將處于"運行" 狀態的標記為黃字黑底,并非別按照顯示名稱、服務狀態排序:
$services = Get-Service | Sort -Property DisplayName,Status
foreach($service in $services)
{
if($service.Status -eq "Running")
{
Write-Host "$($service.DisplayName) is $($service.Status)" -ForegroundColor Yellow -BackgroundColor Black
}
else
{
Write-Host "$($service.DisplayName) is $($service.Status)"
}
}
運行結果:
注意表達式$($service.DisplayName)的用法。
2.2、遇到一個新命令時,快速了解其成員的好方法是對其調用 Get-Member:
Get-Service | Get-Member
運行結果:
獲取名稱中包含"SQL"的服務:
Get-Service | Where {$_.Name -like "*SQL*"}
運行結果:
注意,服務控制臺中的"Name"是PowerShell中的"DisplayName":
在PowerShell 2.0中,新增了 –ComputerName參數,可以查看遠程計算機上的服務,虛擬機的IP和服務如下:
查看此遠程計算機上的服務:
Get-Service -ComputerName 192.168.200.132
運行結果:
-ComputerName支持IP地址、NetBios名稱和域名,為遠程管理提供了極大的便利性。
2.3、更改服務的啟動狀態:
Set-Service SQLWriter -StartupType Automatic –PassThru
運行結果:
同樣可以更改遠程計算機上的服務:
Set-Service pla -ComputerName 192.168.200.132 -StartupType Manual –PassThru
運行結果:
為了安全起見,PowerShell設計為只能使用Get-Service、Set-Service操作遠程計算機上的服務。
2.4、啟動、停止、重啟服務:
Start-Service SQLWriter -PassThru
Stop-Service SQLWriter -PassThru
Restart-Service SQLWriter –PassThru
運行結果:
暫停、恢復服務:
注意并不是每一個服務都支持暫停、恢復操作,因此我們先獲取支持暫停、恢復的服務:
Get-Service | Where {$_.CanPauseAndContinue}
運行結果:
這些是我本機所有支持暫停、恢復的服務,還是很少的。
Suspend-Service MSSQLSERVER -PassThru
Resume-Service MSSQLSERVER –PassThru
運行結果:
2.5、獲取服務的依賴服務與被依賴服務:
Get-Service "Remote Procedure Call (RPC)" –RequiredServices
Get-Service "Remote Procedure Call (RPC)" –DependentServices
運行結果:
可以看到,眾多服務依賴于RPC服務。
小結:
本次我們對Windows服務這一重要的實體進行了介紹,練習了一些簡單的命令。此外在PowerShell 2.0中,可以進行遠程服務管理,這對于管理員來說是個利好消息,但是這也或多或少帶來了一些安全隱患。下一次我們將練習操作Windows進程。

浙公網安備 33010602011771號