Использование инструментария управления Windows для диагностики

Windows Communication Foundation (WCF) предоставляет данные проверки службы во время выполнения с помощью поставщика инструментария управления Windows WCF (WMI).

Включение WMI

WMI — это реализация стандарта компании Microsoft Web-Based Enterprise Management (WBEM). Дополнительные сведения о пакете SDK WMI см. в разделе "Инструментирование управления Windows". WBEM является отраслевым стандартом для того, как приложения отображают инструменты управления для внешних средств управления.

Поставщик WMI — это компонент, предоставляющий инструментирование во время выполнения через интерфейс, совместимый с WBEM. Он состоит из набора объектов WMI, которые имеют пары атрибут/значение. Пары могут быть нескольких простых типов. Средства управления могут подключаться к службам через интерфейс во время выполнения. WCF предоставляет атрибуты таких служб, как адреса, привязки, поведение и прослушиватели.

Встроенный поставщик WMI может быть активирован в файле конфигурации приложения. Это делается с помощью wmiProviderEnabled атрибута <диагностики> в <разделе system.serviceModel> , как показано в следующем примере конфигурации.

<system.serviceModel>
    …
    <diagnostics wmiProviderEnabled="true" />
    …
</system.serviceModel>

Эта запись конфигурации предоставляет интерфейс WMI. Теперь приложения управления могут подключаться через этот интерфейс и получать доступ к инструментированию управления приложения.

Доступ к данным WMI

Доступ к данным WMI можно получить различными способами. Корпорация Майкрософт предоставляет API WMI для сценариев, приложений Visual Basic, приложений C++ и платформы .NET Framework. Дополнительные сведения см. в разделе ИспользованиеWMI.

Осторожность

Если вы используете методы, предоставленные .NET Framework, для программного доступа к данным WMI, следует помнить, что такие методы могут вызывать исключения при установлении подключения. Соединение устанавливается не во время сборки экземпляра ManagementObject , а при первом запросе, предполагающем фактический обмен данными. Поэтому для перехвата возможных исключений следует использовать блок.try..catch

Можно изменить уровень ведения журнала трассировки и сообщений, а также параметры ведения журнала сообщений для источника трассировки System.ServiceModel в WMI. Это можно сделать, обратившись к экземпляру AppDomainInfo , который предоставляет следующие логические свойства: LogMessagesAtServiceLevel, LogMessagesAtTransportLevel, LogMalformedMessages, и TraceLevel. Таким образом, если настроить прослушиватель трассировки для ведения журнала сообщений, но задать эти параметры false в конфигурации, их можно изменить на true позже, когда приложение работает. Это позволит эффективно включить ведение журнала сообщений во время выполнения. Аналогичным образом, если включить ведение журнала сообщений в файле конфигурации, его можно отключить во время выполнения с помощью WMI.

Следует иметь в виду, что если в файле конфигурации не указаны прослушиватели трассировки для ведения журнала сообщений или System.ServiceModel прослушиватели трассировки для трассировки, то ни одно из ваших изменений не вступит в силу, даже если они будут приняты WMI. Дополнительные сведения о правильной настройке соответствующих прослушивателей см. в разделах Настройка ведения журнала сообщений и Настройка трассировки. Уровень трассировки всех других источников трассировки, указанный в конфигурации, вступает в силу на момент запуска приложения и не может быть изменен.

WCF предоставляет GetOperationCounterInstanceName метод для создания сценариев. Этот метод возвращает имя экземпляра счетчика производительности, если вы указываете ему имя операции. Однако он не проверяет ваши данные. Таким образом, если указать неверное имя операции, возвращается неверное имя счетчика.

Свойство OutgoingChannel экземпляра Service не учитывает каналы, открытые службой для подключения к другой службе, если клиент WCF для целевой службы не создан в рамках метода Service .

Осторожность WMI поддерживает TimeSpan значение не более 3 знаков после запятой. Например, если сервис задает для одного из своих свойств значение MaxValue, его значение усекается после 3 знаков после запятой при просмотре через WMI.

Безопасность

Поскольку поставщик WMI WCF позволяет обнаруживать службы в среде, следует проявлять крайнюю осторожность при предоставлении доступа к ней. Если вы ослабите доступ только для администратора по умолчанию, вы можете разрешить менее доверенным сторонам доступ к конфиденциальным данным в вашей среде. В частности, если ослабить разрешения на удаленный доступ WMI, могут произойти flood-атаки. Если процесс перегружен чрезмерным количеством запросов WMI, его производительность может снизиться.

Кроме того, если ослабить права доступа к файлу MOF, менее доверенные стороны могут манипулировать поведением WMI и изменять объекты, загружаемые в схему WMI. Например, поля могут быть удалены таким образом, чтобы критически важные данные были скрыты от администратора или чтобы в файл были добавлены поля, которые не заполняются или вызывают исключения.

По умолчанию поставщик WMI WCF предоставляет администраторам разрешения на выполнение метода, запись поставщика и включение учетной записи, а также разрешение на включение учетной записи для ASP.NET, локальной службы и сетевой службы. В частности, на платформах, отличных от Windows Vista, учетная запись ASP.NET имеет доступ на чтение к пространству имен WMI ServiceModel. Если вы не хотите предоставлять эти привилегии определенной группе пользователей, вам следует либо отключить провайдер WMI (он отключен по умолчанию), либо отключить доступ для определенной группы пользователей.

Кроме того, при попытке включить WMI через конфигурацию WMI может быть не включен из-за недостаточных привилегий пользователя. Однако в журнал событий не записывается событие, которое могло бы зафиксировать этот сбой.

Чтобы изменить уровни привилегий пользователей, выполните следующие действия.

  1. Нажмите кнопку Пуск, а затем Выполнить и введите compmgmt.msc.

  2. Щелкните правой кнопкой мыши элементы управления «Службы и приложения/WMI », чтобы выбрать «Свойства».

  3. Выберите вкладку «Безопасность » и перейдите в пространство имен Root/ServiceModel . Нажмите кнопку Безопасность.

  4. Выберите конкретную группу или пользователя, доступ к которым вы хотите контролировать, и используйте флажок Разрешить или Запретить для настройки разрешений.

Предоставление разрешений на регистрацию WCF WMI дополнительным пользователям

WCF предоставляет данные управления для WMI. Это достигается за счет размещения внутрипроцессного поставщика WMI, иногда называемого «несвязанным провайдером». Чтобы данные управления были раскрыты, учетная запись, которая регистрирует этого поставщика, должна иметь соответствующие разрешения. В Windows только небольшой набор привилегированных учетных записей может регистрировать несвязанных поставщиков по умолчанию. Это проблема, поскольку пользователи обычно хотят предоставить доступ к данным WMI из службы WCF, работающей под учетной записью, которая не входит в набор по умолчанию.

Чтобы предоставить такой доступ, администратор должен предоставить дополнительной учетной записи следующие разрешения в следующем порядке:

  1. Разрешение на доступ к пространству имен WCF WMI.

  2. Разрешение на регистрацию поставщика WCF Decoupled WMI.

Предоставление разрешения на доступ к пространству имен WMI

  1. Выполните следующий скрипт 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 доступ к пространству имен WMI "root/servicemodel". В нем указываются следующие списки ACL:

    • Built-In Администратор (БА) - уже имел доступ.

    • Сетевая служба (NS) - уже имел доступ.

    • Локальная система (LS) - уже имел доступ.

    • Built-In Users — группа, к которой необходимо предоставить доступ.

Предоставление доступа к регистрации поставщика услуг

  1. Выполните следующий скрипт 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 для произвольного пользователя. Один из способов — войти в систему под именем нужного пользователя, а затем выполнить следующую команду оболочки.

Whoami /user

Дополнительные сведения см. в разделе Хорошо известные идентификаторы безопасности.

Доступ к удаленным экземплярам объектов WMI

Если необходимо получить доступ к экземплярам WCF WMI на удаленном компьютере, необходимо включить конфиденциальность пакетов в средствах, используемых для доступа. В следующем разделе описывается, как достичь этих целей с помощью WMI CIM Studio, тестера инструментария управления Windows, а также пакета SDK для .NET 2.0.

Студия WMI CIM

Если вы установили средства администрирования WMI, вы можете использовать WMI CIM Studio для доступа к экземплярам WMI. Инструменты находятся в следующей папке:

%windir%\Программные файлы\WMI Tools\

  1. В окне Connect to namespace: введите root\ServiceModel и нажмите OK.

  2. В окне входа в WMI CIM Studio нажмите кнопку «Параметры >> », чтобы развернуть окно. Выберите Packet privacy для параметра Authentication level (Конфиденциальность пакетов) для параметра Authentication level (Уровень аутентификации) и нажмите кнопку OK.

Тестер инструментария управления Windows

Этот инструмент устанавливается Windows. Чтобы запустить его, запустите командную консоль, введя cmd.exe в диалоговом окне «Пуск/Выполнить» и нажмите кнопку «ОК». Затем введите wbemtest.exe в командном окне. После этого запускается средство тестирования инструментария управления Windows.

  1. Нажмите кнопку «Подключить » в правом верхнем углу окна.

  2. В новом окне введите root\ServiceModel в поле Пространство имен и выберите Конфиденциальность пакетов для параметра Уровень аутентификации. Нажмите кнопку "Подключить".

Использование управляемого кода

Вы также можете получить доступ к удаленным экземплярам WMI программным способом с помощью классов, предоставляемых пространством System.Management имен. В следующем примере кода показано, как это сделать.

String wcfNamespace = $@"\\{this.serviceMachineName}\Root\ServiceModel");

ConnectionOptions connection = new ConnectionOptions();
connection.Authentication = AuthenticationLevel.PacketPrivacy;
ManagementScope scope = new ManagementScope(this.wcfNamespace, connection);