Windows 通訊基礎(WCF)透過 WCF 的 Windows 管理儀器(WMI)提供者,在執行時公開服務的檢查資料。
啟用 WMI
WMI 是Microsoft Web-Based 企業管理 (WBEM) 標準的實作。 如需 WMI SDK 的詳細資訊,請參閱 Windows Management Instrumentation。 WBEM 是應用程式如何向外部管理工具公開管理工具的業界標準。
WMI 提供者是一種元件,透過與 WBEM 相容的介面在執行時暴露儀器。 它由一組具有屬性/值對的 WMI 對象組成。 對可以是許多簡單的類型。 管理工具可在執行時透過介面連接服務。 WCF 會公開服務的屬性,例如位址、系結、行為和接聽程式。
可以在應用程式的配置檔中啟動內置的 WMI 提供程式。 這是通過 wmiProviderEnabledsystem.serviceModel< 部分中的診斷><屬性>完成的,如以下示例配置所示。
<system.serviceModel>
…
<diagnostics wmiProviderEnabled="true" />
…
</system.serviceModel>
此設定項目會暴露 WMI 介面。 管理應用程式現在能夠透過這個介面連接並存取應用程式的管理工具。
訪問 WMI 數據
您可以透過許多不同的方式存取 WMI 資料。 Microsoft提供腳本、Visual Basic 應用程式、C++應用程式和 .NET Framework 的 WMI API。 如需詳細資訊,請參閱使用 WMI 。
謹慎
如果使用 .NET Framework 提供的方法以程式設計方式訪問 WMI 數據,則應注意,在建立連接時,此類方法可能會引發異常。 連接不是在實例構建 ManagementObject 期間建立的,而是在涉及實際數據交換的第一個請求時建立的。 因此,您應該使用 try..catch 塊來捕獲可能的異常。
可以更改WMI中跟蹤 System.ServiceModel 源的跟蹤和消息記錄級別以及消息記錄選項。 這可以通過訪問 AppDomainInfo 實例來完成,該實例公開了以下布爾屬性:LogMessagesAtServiceLevel、LogMessagesAtTransportLevelLogMalformedMessages、 、 和 TraceLevel. 因此,如果您設定訊息記錄的追蹤接聽程式,但在組態中將這些選項 false 設定為 ,您稍後可以在應用程式執行時將其變更為 true 。 這將有效啟用執行時的訊息記錄。 同樣地,如果你在設定檔啟用訊息記錄,執行時可以用 WMI 來關閉它。
您應該知道,如果在配置檔中未指定用於消息日誌記錄的消息日誌記錄跟蹤偵聽器,或者未 System.ServiceModel 指定用於跟蹤的跟蹤偵聽器,則即使 WMI 接受這些更改,您的任何更改也不會生效。 有關正確設置相應偵聽器的更多資訊,請參閱 配置消息日誌記錄 和 配置跟蹤。 配置指定的所有其他跟蹤源的跟蹤級別在應用程式啟動時有效,並且無法更改。
WCF 公開了 GetOperationCounterInstanceName 一種腳本編寫方法。 如果您為性能計數器實例提供作名稱,則此方法將返回該實例名稱。 但是,它不會驗證您的輸入。 因此,如果提供的作名稱不正確,則會返回不正確的計數器名稱。
OutgoingChannel如果未在方法中創建Service到目標服務的 WCF 用戶端,則實例的屬性Service不會對服務打開的連接到其他服務的通道進行計數。
謹慎 WMI 僅支援 TimeSpan 最多 3 個小數點的值。 例如,如果您的服務將其其中一個屬性設置為 MaxValue,則在通過WMI 查看時,其值將在3個小數點後截斷。
安全性
由於 WCF WMI 提供程式允許在環境中發現服務,因此在授予對它的訪問許可權時應格外小心。 如果您放寬預設的僅限管理員訪問許可權,則可以允許不太受信任的方訪問您環境中的敏感數據。 具體而言,如果放寬對遠端 WMI 訪問的許可權,則可能會發生泛洪攻擊。 如果進程被過多的 WMI 請求淹沒,則其性能可能會降低。
此外,如果放寬對MOF檔的訪問許可權,則不太受信任的參與方可以縱 WMI 的行為並更改在WMI架構中載入的物件。 例如,可以刪除欄位,以便對管理員隱藏關鍵數據,或者將未填充或導致異常的欄位添加到檔中。
默認情況下,WCF WMI 提供程式為管理員授予“執行方法”、“提供程式寫入”和“啟用帳戶”許可權,併為 ASP.NET、本地服務和網路服務授予“啟用帳戶”許可權。 具體而言,在非 Windows Vista 平臺上,ASP.NET 帳戶具有對 WMI ServiceModel 命名空間的讀取訪問許可權。 如果不想將這些許可權授予特定使用者組,則應停用WMI提供程式(預設情況下處於禁用狀態),或禁用特定使用者組的訪問。
此外,當您嘗試通過配置啟用 WMI 時,由於用戶許可權不足,WMI 可能無法啟用。 但是,不會將任何事件寫入事件日誌來記錄此失敗。
要修改使用者許可權級別,請使用以下步驟。
按兩下「開始」,然後按兩下「運行」並鍵入 compmgmt.msc。
右鍵按下 Services and Application/WMI Controls 以選擇 Properties ( 屬性)。
選擇 Security 選項卡,然後導航到 Root/ServiceModel 命名空間。 按一下 [安全性] 按鈕。
選擇要控制訪問許可權的特定組或用戶,然後使用 Allow 或 Deny 複選框設定許可權。
向其他使用者授予 WCF WMI 註冊許可權
WCF 向 WMI 公開管理數據。 它通過託管進程內 WMI 提供程式(有時稱為“分離的提供程式”)來實現此目的。 對於要公開的管理數據,註冊此提供程式的帳戶必須具有相應的許可權。 在 Windows 中,預設情況下,只有一小部分特權帳戶可以註冊分離的提供程式。 這是一個問題,因為使用者通常希望從不在預設集中的帳戶下運行的 WCF 服務中公開 WMI 數據。
要提供此訪問許可權,管理員必須按以下順序向其他帳戶授予以下許可權:
訪問 WCF WMI 命名空間的許可權。
註冊 WCF 分離 WMI 提供程式的許可權。
授予 WMI 命名空間訪問許可權
執行下列 PowerShell 腳本。
write-host "" write-host "Granting Access to root/servicemodel WMI namespace to built in users group" write-host "" # Create the binary representation of the permissions to grant in SDDL $newPermissions = "O:BAG:BAD:P(A;CI;CCDCLCSWRPWPRCWD;;;BA)(A;CI;CC;;;NS)(A;CI;CC;;;LS)(A;CI;CC;;;BU)" $converter = new-object system.management.ManagementClass Win32_SecurityDescriptorHelper $binarySD = $converter.SDDLToBinarySD($newPermissions) $convertedPermissions = ,$binarySD.BinarySD # Get the object used to set the permissions $security = gwmi -namespace root/servicemodel -class __SystemSecurity # Get and output the current settings $binarySD = @($null) $result = $security.PsBase.InvokeMethod("GetSD",$binarySD) $outsddl = $converter.BinarySDToSDDL($binarySD[0]) write-host "Previous ACL: "$outsddl.SDDL # Change the Access Control List (ACL) using SDDL $result = $security.PsBase.InvokeMethod("SetSD",$convertedPermissions) # Get and output the current settings $binarySD = @($null) $result = $security.PsBase.InvokeMethod("GetSD",$binarySD) $outsddl = $converter.BinarySDToSDDL($binarySD[0]) write-host "New ACL: "$outsddl.SDDL write-host ""此 PowerShell 腳本使用安全描述符定義語言 (SDDL) 向 Built-In 使用者組授予對“root/servicemodel”WMI 命名空間的訪問許可權。 指定以下 ACL:
Built-In 管理員 (BA) - 已具有訪問許可權。
網路服務 (NS) - 已具有訪問許可權。
本地系統 (LS) - 已具有存取權限。
Built-In Users ( 使用者) - 要授予存取權限的組。
授予提供程式註冊訪問許可權
執行下列 PowerShell 腳本。
write-host "" write-host "Granting WCF provider registration access to built in users group" write-host "" # Set security on ServiceModel provider $provider = get-WmiObject -namespace "root\servicemodel" __Win32Provider write-host "Previous ACL: "$provider.SecurityDescriptor $result = $provider.SecurityDescriptor = "O:BUG:BUD:(A;;0x1;;;BA)(A;;0x1;;;NS)(A;;0x1;;;LS)(A;;0x1;;;BU)" # Commit the changes and display it to the console $result = $provider.Put() write-host "New ACL: "$provider.SecurityDescriptor write-host ""
向任意使用者或組授予訪問許可權
本節中的示例向所有本地使用者授予 WMI 提供程式註冊許可權。 如果要向非內置使用者或組授予訪問許可權,則必須獲取該使用者或組的安全標識碼 (SID)。 沒有簡單的方法可以獲取任意使用者的 SID。 一種方法是以所需使用者身份登錄,然後發出以下shell命令。
Whoami /user
有關詳細資訊,請參閱 已知 SID。
訪問遠端 WMI 物件實例
如果需要訪問遠端電腦上的 WCF WMI 實例,則必須在用於訪問的工具上啟用數據包隱私。 以下部分介紹如何使用 WMI CIM Studio、Windows Management Instrumentation Tester 以及 .NET SDK 2.0 實現這些目標。
WMI CIM 工作室
如果已安裝 WMI 管理工具,則可以使用 WMI CIM Studio 訪問 WMI 實例。 這些工具位於以下資料夾中:
%windir%\Program Files\WMI 工具\
在 Connect to namespace: (連接到命名空間: ) 視窗中,鍵入 root\ServiceModel 並按兩下 OK (確定)。
在 WMI CIM Studio 登錄 視窗中,按下 選項 >> 按鈕以展開視窗。 選擇 Packet privacy (資料包隱私 ) 作為 Authentication level (身份驗證級別),然後按兩下 OK (確定)。
Windows Management Instrumentation 測試器
此工具由 Windows 安裝。 要運行它,請在 Start/Run (開始/運行) 對話框中鍵入 cmd.exe 來啟動命令控制台,然後按兩下 OK(確定)。 然後,在命令視窗中鍵入 wbemtest.exe 。 然後啟動 Windows Management Instrumentation Tester 工具。
點擊 Connect 視窗右上角的按鈕。
在新視窗中,為 Namespace 字段輸入 root\ServiceModel,然後選擇 Packet privacy 作為 Authentication level。 按一下 [ 連接]。
使用託管代碼
還可以使用命名空間提供的 System.Management 類以程式設計方式訪問遠端 WMI 實例。 下列程式代碼範例示範如何執行這項作。
String wcfNamespace = $@"\\{this.serviceMachineName}\Root\ServiceModel");
ConnectionOptions connection = new ConnectionOptions();
connection.Authentication = AuthenticationLevel.PacketPrivacy;
ManagementScope scope = new ManagementScope(this.wcfNamespace, connection);