Поделиться через


Создание скрипта WMI

Вы можете просматривать или управлять любой информацией, доступной с помощью WMI, с помощью скриптов. Скрипты можно написать на любом языке сценариев, который поддерживает размещение скриптов Microsoft ActiveX, включая Visual Basic Scripting Edition (VBScript), PowerShell и Perl. Сценарийный хост Windows (WSH), Active Server Pages и Internet Explorer могут размещать скрипты WMI.

Заметка

Основной язык скриптов, поддерживаемый WMI в настоящее время, — PowerShell. Однако WMI также содержит надежный текст поддержки сценариев для VBScript и других языков, которые получают доступ к API скриптов для WMI.

 

Языки сценариев WMI

Двумя основными языками, поддерживаемыми WMI, являются PowerShell и VBScript (через хост сценариев Windows или WSH).

  • PowerShell был разработан с учетом тесной интеграции с WMI. Таким образом, большинство базовых элементов WMI встроены в командлеты WMI: Get-WmiObject, Set-WmiInstance, Invoke-WmiMethodи Remove-WmiObject. В следующей таблице описаны общие процессы, используемые для доступа к данным WMI. Обратите внимание, что в большинстве этих примеров используется Get-WMIObject, многие из командлетов WMI PowerShell имеют одинаковые параметры, такие как -Class или -Credentials. Поэтому многие из этих процессов также работают для других объектов. Для более детального обсуждения PowerShell и WMI см. в статье Использование командлета Get-WMiObject и Windows PowerShell — WMI соединение.

  • VBScript, в отличие от этого, явно выполняет вызовы API скриптов для WMI, как упоминалось выше. Другие языки, такие как Perl, также могут использовать API сценариев для WMI. Однако в целях этой документации большинство примеров, демонстрирующих API скриптов для WMI, будут использовать VBScript. Если же техника программирования специфична для VBScript, на это будет обращено внимание.

    VBScript имеет по сути два отдельных способа доступа к WMI. Сначала используется объект SWbemLocator для подключения к WMI. В качестве альтернативы, можно использовать GetObject и моникер. Моникер — это строка, которая может описать ряд элементов: учетные данные, параметры олицетворения, компьютер, к которому требуется подключиться, пространство имен WMI (т. е. общее расположение, в котором WMI хранит группы объектов) и какой объект WMI требуется получить. Многие из приведенных ниже примеров описывают оба метода. Дополнительные сведения см. в статье Создание строки Моникера и описание расположения объекта WMI.

    Независимо от того, какой метод используется для подключения к WMI, скорее всего, вы получите один или несколько объектов из API скриптов. Чаще всего используется SWbemObject, который WMI использует для описания объекта WMI. Кроме того, можно использовать объект SWbemServices для описания самой службы WMI или объекта SWbemObjectPath для описания расположения объекта WMI. Для получения дополнительной информации см. в разделе Работа со сценарием с использованием SWbemObject и Объекты-помощники для скриптов.

Как с помощью WMI и скриптового языка сделать...

... подключиться к WMI?

Для VBScript и API скриптов для WMI извлеките объект SWbemServices с моникером и вызовом GetObject. Кроме того, можно подключиться к серверу с помощью вызова SWbemLocator.ConnectServer. Затем можно использовать объект для доступа к определенному пространству имен WMI или экземпляру класса WMI.

Для PowerShell подключение к WMI обычно выполняется непосредственно в вызове командлета; Таким образом, никаких дополнительных шагов не требуется.

Дополнительные сведения см. в статье Описание расположения объекта WMI, Конструирование строки моникера, и Подключение к WMI с помощью VBScript.

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer(".", "root\cimv2")

' Second example: implicitly uses the local compuer (.) and default namespace ("root\cimv2")
Set objWMIService = GetObject("winmgmts:")

#Already has all the defaults set
get-WmiObject Win32_LogicalDisk

#Or, to be explicit,
get-WmiObject -class Win32_LogicalDisk -Computer "." -Namespace "root\cimv2" -Impersonation Impersonate

... получить информацию из WMI?

Для VBScript и API скриптов для WMI используйте функцию извлечения, например WbemServices.Get или WbemServices.InstancesOf. Вы также можете поместить имя класса объекта в идентификатор, чтобы извлечь его; это может быть более эффективно.

Для PowerShell используйте параметр -Class. Обратите внимание, что -Class является параметром по умолчанию; Таким образом, вам не нужно явно указывать его.

Для получения дополнительной информации см. в разделе извлечение данных класса или экземпляра WMI.

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer(".", "root\cimv2")
Set colScheduledJobs = objService.InstancesOf("Win32_ScheduledJob")

' Second example
SSet Service = GetObject("WinMgmts:{impersonationLevel=impersonate}!Win32_Service=""ALERTER""")

#default - you don't actually need to use the -Class parameter
Get-WMIObject Win32_WmiSetting

#but you can if you want to
Get-WMIObject -Class Win32_WmiSetting

... сформируйте запрос WMI?

Для VBScript и API скриптов для WMI используйте метод SWbemServices.ExecQuery.

Для PowerShell используйте параметр -Query. Вы также можете фильтровать с помощью параметра -Filter.

Дополнительные сведения см. в разделе «Запросы WMI».

strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colScheduledJobs = objWMIService.ExecQuery("Select * from Win32_ScheduledJob")
For Each objJob in colScheduledJobs
    Wscript.Echo "Job ID: " & objJob.JobId & "Command: " & objJob.Command & VBNewLine

Get-WmiObject -query "SELECT * FROM Win32_logicalDisk WHERE DeviceID = 'C:'"

#or

get-wmiObject -Class Win32_LogicalDisk -Filter "DeviceID = 'C:'"

... перечислите список объектов WMI?

Для VBScript и API скриптов для WMI используйте объект контейнера SWbemObjectSet, который обрабатывается в скрипте как коллекция, которую можно перечислить. Вы можете получить SWbemObjectSet из вызова SWbemServices.InstancesOf или SWbemServices.ExecQuery.

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

Дополнительные сведения см. в статье Доступ к коллекции.

For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDevice")

$logicalDevices = Get-WmiObject CIM_LogicalDevice
foreach ($device in $logicalDevices)
{
    $device.name
}

#or, to be more compact

Get-WmiObject cim_logicalDevice | ForEach-Object { $_.name }

... доступ к другому пространству имен WMI?

Для VBScript и API скриптов для WMI укажите пространство имен в моникере или можно явно указать пространство имен в вызове SwbemLocator.ConnectServer.

Для PowerShell используйте параметр -Namespace. Пространство имен по умолчанию — root\cimV2; однако многие старые классы хранятся в root\default.

Чтобы найти расположение заданного класса WMI, просмотрите страницу ссылки. Кроме того, можно вручную изучить пространство имен с помощью get-WmiObject.

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer(".", "root\cimv2")

' Second example
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2")

Get-WmiObject -list * -Namespace root\default

#or, to retrieve all namespaces,
Get-WmiObject -Namespace root -Class __Namespace

... как получить все дочерние экземпляры класса?

Для языков, которые напрямую используют API скриптов для WMI и PowerShell, WMI поддерживает получение дочерних классов базового класса. Таким образом, чтобы получить дочерние экземпляры, достаточно выполнить поиск только родительского класса. В следующем примере выполняется поиск CIM_LogicalDisk— предварительно установленного класса WMI, представляющего логические диски в компьютерной системе на основе Windows. Таким образом, поиск этого родительского класса также возвращает экземпляры Win32_LogicalDisk. Это то, что Windows использует для описания жестких дисков. Для получения дополнительной информации см. Общую информационную модель. WMI предоставляет всю схему таких предварительно установленных классов, которые позволяют получать доступ к управляемым объектам и управлять ими. Для получения дополнительной информации см. классы Win32 и WMI.

For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDisk")
  WScript.Echo "Instance:", Disk.Name
Get-WmiObject CIM_LogicalDisk | ForEach-Object { "Instance: " + $_.Name  }

... найдите объект WMI?

Для API скриптов для WMI и PowerShell WMI использует сочетание пространства имен, имени класса и ключевых свойств для уникальной идентификации заданного экземпляра WMI. Вместе это называется путь к объекту WMI. Для VBScript свойство SWbemObject.Path_ описывает путь для любого заданного объекта, возвращаемого API скриптов. Для PowerShell каждый объект WMI будет иметь свойство __PATH. Дополнительные сведения см. в разделе Описание расположения объекта WMI

Помимо пространства имен и имени класса, объект WMI также будет иметь свойство ключа, которое однозначно идентифицирует этот экземпляр по сравнению с другими экземплярами на компьютере. Например, свойство DeviceID является ключевым свойством класса Win32_LogicalDisk. Дополнительные сведения см. в формате управляемых объектов (MOF) .

Наконец, относительный путь является просто сокращенной формой пути и включает имя класса и значение ключа. В приведенных ниже примерах путь может быть "\\computerName\root\cimv2:Win32_LogicalDisk.DeviceID="D:", а относительный путь будет ""Win32LogicalDisk.DeviceID="D"".

For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDisk")
  WScript.Echo "Instance:", Disk.Path_.Relpath

'or to get the path
For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDisk")
  WScript.Echo "Instance:", Disk.Path_
#retrieving the path
Get-WmiObject CIM_LogicalDisk | ForEach-Object { "Instance: " + $_.__PATH  }

#retrieving the relative path
Get-WmiObject CIM_LogicalDisk | ForEach-Object { "Instance: " + $_.__RELPATH  }

... задайте сведения в WMI?

Для VBScript и API скриптов для WMI используйте метод SWbemObject.Put_.

Для PowerShell можно использовать либо метод Put, либо команду Set-WmiInstance.

Дополнительные сведения см. в разделе Изменение свойства экземпляра.

wbemCimtypeString = 8
Set objSWbemService = GetObject("Winmgmts:root\default")
Set objClass = objSWbemService.Get()
objClass.Path_.Class = "NewClass"

' Add a property
' String property
objClass.Properties_.add "PropertyName", wbemCimtypeString  
' Make the property a key property 
objClass.Properties_("PropertyName").Qualifiers_.add "key", true

' Write the new class to the root\default namespace in the repository
Set objClassPath = objClass.Put_
WScript.Echo objClassPath.Path

'Create an instance of the new class using SWbemObject.SpawnInstance
Set objNewInst = GetObject("Winmgmts:root\default:NewClass").Spawninstance_

objNewInst.PropertyName = "My Instance"

' Write the instance into the repository
Set objInstancePath = objNewInst.Put_
WScript.Echo objInstancePath.Path

$mySettings = get-WMIObject Win32_WmiSetting
$mySettings.LoggingLevel = 1
$mySettings.Put()

#or

Set-WMIInstance -class Win32_WMISetting -argument @{LoggingLevel=1}

... используйте разные учетные данные?

Для VBScript и API скриптов для WMI используйте параметры UserName и password в методе SWbemLocator.ConnectServer.

Для PowerShell используйте параметр -Credential.

Обратите внимание, что в удаленной системе можно использовать только альтернативные учетные данные. Для получения дополнительной информации, см. раздел Защита клиентов сценариев.

strComputer = "remoteComputerName" 
strDomain = "DOMAIN" 
Wscript.StdOut.Write "Please enter your user name:"
strUser = Wscript.StdIn.ReadLine 
Set objPassword = CreateObject("ScriptPW.Password")
Wscript.StdOut.Write "Please enter your password:"
strPassword = objPassword.GetPassword()
 
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, _
                                                     "Root\CIMv2", _
                                                     strUser, _
                                                     strPassword, _
                                                     "MS_409", _
                                                     "ntlmdomain:" + strDomain)
Set colSwbemObjectSet = objSWbemServices.ExecQuery("Select * From Win32_Process")
For Each objProcess in colSWbemObjectSet
    Wscript.Echo "Process Name: " & objProcess.Name 
Next

$Computer = "atl-dc-01"

Get-WmiObject -Namespace "root\cimv2" -Class Win32_Process -Credential FABRIKAM\administrator  `
-ComputerName $Computer

... доступ к удаленному компьютеру?

Для VBScript и API скриптов для WMI явно укажите имя компьютера в моникере или в вызове SWbemLocator.ConnectServer. Дополнительные сведения см. в статье Удаленное подключение к WMI с помощьюVBScript.

Для PowerShell используйте параметр -ComputerName. Дополнительные сведения см. в статье Удаленное подключение к WMI с помощью PowerShell.

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer("myRemoteServerName", "root\cimv2")
Set colScheduledJobs = objService.ExecQuery("SELECT * FROM Win32_ScheduledJob")
For Each objJob in colScheduledJobs
    Wscript.Echo "Job ID: " & objJob.JobId & "Command: " & objJob.Command & VBNewLine

'example 2

strComputer = "myRemoteServerName"
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colScheduledJobs = objWMIService.ExecQuery("Select * from Win32_ScheduledJob")
For Each objJob in colScheduledJobs
    Wscript.Echo "Job ID: " & objJob.JobId & "Command: " & objJob.Command & VBNewLine

$Computer = "atl-dc-01"

Get-WmiObject -Namespace "root\cimv2" -Class Win32_logicalDisk -ComputerName $Computer

... задайте уровни проверки подлинности и олицетворения?

Для VBScript и API скриптов для WMI используйте свойство SWbemServices.Security_ для возвращаемого объекта сервера или задайте соответствующие значения в моникере.

Для PowerShell используйте параметры — -Authentication и -Impersonation, соответственно. Для получения дополнительной информации см. Защита клиентов сценариев.

Дополнительные сведения см. в разделе Защита клиентов сценариев.

' First example
Set Service = GetObject("WinMgmts:{impersonationLevel=impersonate}!Win32_Service=""ALERTER""")

' Second example
Set Locator = CreateObject("WbemScripting.SWbemLocator")
Set Service = Locator.ConnectServer       
service.Security_.ImpersonationLevel = wbemImpersonationLevelImpersonate  
Set objinstance = Service.Get("Win32_Service=""ALERTER""")

$Computer = "atl-dc-01"

Get-WmiObject -Namespace "root\cimv2" -Class Win32_Process -Impersonation Impersonate `
 -Authentication PacketIntegrity -Credential FABRIKAM\administrator -ComputerName $Computer

... как обрабатывать ошибки в WMI?

Для API скриптов для WMI поставщик может предоставить объект SWbemLastError, чтобы получить дополнительные сведения об ошибке.

В VBScript, в частности, обработка ошибок также поддерживается с помощью собственного объекта Err. Вы также можете получить доступ к объекту SWbemLastError, как описано выше. Для получения дополнительной информации см. в получение кода ошибки.

Для PowerShell можно использовать стандартные методы обработки ошибок PowerShell. Дополнительные сведения см. в статье Введение в обработку ошибок в PowerShell.

'using Err
On Error Resume Next
Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process.Handle='one'")
Wscript.Echo Err.Number

'using SWbemLastError

On Error Resume Next
Set obj = GetObject("winmgmts:root\cimv2:Win32_Process.Handle='one'")
Set LastError = createobject("wbemscripting.swbemlasterror")
Wscript.Echo "Operation = " & LastError.operation & VBCRLF & "ParameterInfo = " _
            & LastError.ParameterInfo & VBCRLF & "ProviderName = " & LastError.ProviderName