Criando um script WMI

Você pode exibir ou manipular todas as informações disponibilizadas por meio do WMI usando scripts. Os scripts podem ser escritos em qualquer linguagem de script que dê suporte à hospedagem de script do Microsoft ActiveX, incluindo Visual Basic Edição de Script (VBScript), PowerShell e Perl. Windows WSH (Host de Script), Páginas do Servidor Ativo e Internet Explorer podem hospedar scripts WMI.

Observação

A linguagem de script principal com suporte no momento pelo WMI é o PowerShell. No entanto, o WMI também contém um corpo robusto de suporte de script para VBScript e outras linguagens que acessam a API de Script para WMI.

 

Idiomas de script WMI

Os dois idiomas principais compatíveis com o WMI são o PowerShell e o VBScript (por meio do host de script Windows ou WSH).

  • O PowerShell foi projetado com uma integração apertada com o WMI em mente. Assim, grande parte dos elementos subjacentes do WMI são incorporados aos cmdlets WMI: Get-WmiObject, Set-WmiInstance, Invoke-WmiMethod e Remove-WmiObject. A tabela a seguir descreve os processos gerais usados para acessar informações do WMI. Observe que, embora a maioria desses exemplos use Get-WMIObject, muitos dos cmdlets WMI do PowerShell têm os mesmos parâmetros, como -Class ou -Credentials. Portanto, muitos desses processos também funcionam para outros objetos. Para obter uma discussão mais aprofundada sobre o PowerShell e o WMI, consulte Usando o cmdlet e o Windows PowerShell de Get-WMiObject – a conexão WMI.

  • O VBScript, por outro lado, faz chamadas explicitamente para a API de Script para WMI, conforme mencionado acima. Outras linguagens, como Perl, também podem usar a API de script para WMI. No entanto, para fins dessa documentação, a maioria dos exemplos que demonstram a API de script para WMI usará o VBScript. No entanto, quando uma técnica de programação é específica do VBScript, ela será chamada.

    O VBScript tem essencialmente duas maneiras separadas de acessar o WMI. O primeiro é usar um objeto SWbemLocator para se conectar ao WMI. Como alternativa, você pode usar GetObject e um moniker. Um moniker é uma cadeia de caracteres que pode descrever vários elementos: suas credenciais, configurações de representação, o computador ao qual você deseja se conectar, o namespace WMI (ou seja, o local geral em que o WMI armazena grupos de objetos) e o objeto WMI que você deseja recuperar. Muitos dos exemplos abaixo descrevem ambas as técnicas. Para obter mais informações, consulte Como construir uma cadeia de caracteres moniker e descrever a localização de um objeto WMI.

    Independentemente da técnica usada para se conectar ao WMI, você provavelmente recuperará um ou mais objetos da API de Script. O mais comum é SWbemObject, que o WMI usa para descrever um objeto WMI. Como alternativa, você pode usar um objeto SWbemServices para descrever o próprio serviço WMI ou um objeto SWbemObjectPath para descrever o local de um objeto WMI. Para obter mais informações, consulte Scripts com objetos auxiliares de script e SWbemObject.

Usando wmi e uma linguagem de script, como fazer...

... conectar-se ao WMI?

Para o VBScript e a API de Script para WMI, recupere um objeto SWbemServices com um moniker e uma chamada para GetObject. Como alternativa, você pode se conectar ao servidor com uma chamada para SWbemLocator.ConnectServer. Em seguida, você pode usar o objeto para acessar um namespace WMI específico ou uma instância de classe WMI.

Para o PowerShell, a conexão com o WMI geralmente é feita diretamente na chamada de cmdlet; dessa forma, nenhuma etapa adicional é necessária.

Para obter mais informações, consulte Descrevendo a localização de um objeto WMI, construindo uma cadeia de caracteres moniker e conectando-se ao WMI com 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

... recuperar informações do WMI?

Para o VBScript e a API de Script para WMI, use uma função de recuperação, como WbemServices.Get ou WbemServices.InstancesOf. Você também pode colocar o nome da classe do objeto a ser recuperado em um moniker, o que pode ser mais eficiente.

Para o PowerShell, use o parâmetro -Class . Observe que -Class é o parâmetro padrão; como tal, você não precisa declarar explicitamente.

Para obter mais informações, consulte Recuperando dados da classe WMI ou da instância.

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

... criar uma consulta WMI?

Para o VBScript e a API de Script para WMI, use o método SWbemServices.ExecQuery .

Para o PowerShell, use o parâmetro -Query . Você também pode filtrar usando o parâmetro -Filter .

Para obter mais informações, consulte Consulta do 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:'"

... enumerar por meio de uma lista de objetos WMI?

Para VBScript e a API de Script para WMI, use o objeto de contêiner SWbemObjectSet , que é tratado no script como uma coleção que pode ser enumerada. Você pode recuperar um SWbemObjectSet de uma chamada de SWbemServices.InstancesOf ou SWbemServices.ExecQuery.

O PowerShell é capaz de recuperar e manipular enumerações como qualquer outro objeto; não há nada particularmente exclusivo para o WMI.

Para obter mais informações, consulte Acessando uma coleção.

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 }

... acessar um namespace WMI diferente?

Para o VBScript e a API de Script para WMI, indique o namespace no moniker ou, caso contrário, você pode declarar explicitamente o namespace na chamada para SwbemLocator.ConnectServer.

Para o PowerShell, use o parâmetro -Namespace . O namespace padrão é "root\cimV2"; no entanto, muitas classes mais antigas são armazenadas em "raiz\padrão".

Para localizar o local de uma determinada classe WMI, examine a página de referência. Como alternativa, você pode explorar manualmente um namespace usando 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

... recuperar todas as instâncias filho de uma classe?

Para idiomas que usam diretamente a API de Script para WMI e PowerShell, o WMI dá suporte à recuperação das classes filho de uma classe base. Assim, para recuperar as instâncias filho, você precisa pesquisar apenas a classe pai. O exemplo a seguir pesquisa CIM_LogicalDisk, que é uma classe WMI pré-instalada que representa discos lógicos em um sistema de computador baseado em Windows. Assim, a pesquisa dessa classe pai também retorna instâncias de Win32_LogicalDisk, que é o que Windows usa para descrever discos rígidos. Para obter mais informações, consulte Common Information Model. O WMI fornece um esquema inteiro dessas classes pré-instaladas que permitem acessar e controlar objetos gerenciados. Para obter mais informações, consulte Classes Win32 e classes WMI..

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

... localizar um objeto WMI?

Para a API de Script para WMI e PowerShell, o WMI usa uma combinação de propriedades de namespace, nome de classe e chave para identificar exclusivamente uma determinada instância WMI. Juntos, isso é conhecido como o caminho do objeto WMI. Para VBScript, a propriedade SWbemObject.Path_ descreve o caminho para qualquer objeto retornado pela API de script. Para o PowerShell, cada objeto WMI terá uma propriedade __PATH. Para obter mais informações, consulte Descrevendo a localização de um objeto WMI

Além do namespace e do nome da classe, um objeto WMI também terá uma propriedade de chave, que identifica exclusivamente essa instância em comparação com outras instâncias em seu computador. Por exemplo, a propriedade DeviceID é a propriedade de chave da classe Win32_LogicalDisk . Para obter mais informações, consulte O MOF (Managed Object Format).

Por fim, o caminho relativo é simplesmente uma forma abreviada do caminho e inclui o nome da classe e o valor da chave. Nos exemplos abaixo, o caminho pode ser "\\computerName\root\cimv2:Win32_LogicalDisk.DeviceID="D:"", enquanto o caminho relativo seria ""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  }

... definir informações no WMI?

Para o VBScript e a API de Script para WMI, use o método SWbemObject.Put_ .

Para o PowerShell, você pode usar o método Put ou então Set-WmiInstance.

Para obter mais informações, consulte Modificar uma propriedade de instância.

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}

... usar credenciais diferentes?

Para VBScript e a API de Script para WMI, use os parâmetros UserName e Password no método SWbemLocator.ConnectServer .

Para o PowerShell, use o parâmetro -Credential .

Observe que você só pode usar credenciais alternativas em um sistema remoto. Para obter mais informações, consulte Proteção de clientes de script.

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

... acessar um computador remoto?

Para o VBScript e a API de Script para WMI, declare explicitamente o nome do computador no moniker ou na chamada para SWbemLocator.ConnectServer. Para obter mais informações, consulte Conectar-se ao WMI remotamente com o VBScript.

Para o PowerShell, use o parâmetro -ComputerName . Para obter mais informações, consulte Conectar-se ao WMI remotamente com o 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

... definir os níveis de Autenticação e Representação?

Para o VBScript e a API de Script para WMI, use a propriedade SWbemServices.Security_ no objeto de servidor retornado ou defina os valores relevantes no moniker.

Para o PowerShell, use os parâmetros -Authentication e -Impersonation , respectivamente. Para obter mais informações, consulte Proteção de clientes de script.

Para obter mais informações, consulte Proteção de clientes de script.

' 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

... manipular erros no WMI?

Para a API de Script para WMI, o provedor pode fornecer um objeto SWbemLastError para fornecer mais informações sobre um erro.

Em VBScript em particular, também há suporte para tratamento de erros usando o objeto Err nativo. Você também pode acessar o objeto SWbemLastError, conforme descrito acima. Para obter mais informações, consulte Recuperando um código de erro.

Para o PowerShell, você pode usar as técnicas padrão de tratamento de erros do PowerShell. Para obter mais informações, consulte Uma introdução ao tratamento de erros no 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