Creación de un script WMI

Puede ver o manipular cualquier información disponible a través de WMI mediante scripts. Los scripts se pueden escribir en cualquier lenguaje de scripting que admita el hospedaje de scripts de Microsoft ActiveX, incluidos Visual Basic Scripting Edition (VBScript), PowerShell y Perl. Windows Host de script (WSH), Páginas de servidor activo e Internet Explorer pueden hospedar scripts WMI.

Nota

El lenguaje de scripting principal admitido actualmente por WMI es PowerShell. Sin embargo, WMI también contiene un sólido cuerpo de compatibilidad de scripting para VBScript y otros lenguajes que acceden a scripting API para WMI.

 

Lenguajes de scripting de WMI

Los dos lenguajes principales admitidos por WMI son PowerShell y VBScript (a través del host de script de Windows o WSH).

  • PowerShell se diseñó con una estrecha integración con WMI en mente. Por lo tanto, gran parte de los elementos subyacentes de WMI están integrados en los cmdlets WMI: Get-WmiObject, Set-WmiInstance, Invoke-WmiMethod y Remove-WmiObject. En la tabla siguiente se describen los procesos generales que se usan para acceder a la información de WMI. Tenga en cuenta que, aunque la mayoría de estos ejemplos usan Get-WMIObject, muchos de los cmdlets WMI de PowerShell tienen los mismos parámetros, como -Class o -Credentials. Por lo tanto, muchos de estos procesos también funcionan para otros objetos. Para obtener una explicación más detallada de PowerShell y WMI, consulte Uso del cmdlet de Get-WMiObject y Windows PowerShell: la conexión WMI.

  • VBScript, en cambio, realiza explícitamente llamadas a la API de scripting para WMI, como se mencionó anteriormente. Otros lenguajes, como Perl, también pueden usar la API de scripting para WMI. Sin embargo, para los fines de esta documentación, la mayoría de los ejemplos que muestran la API de scripting para WMI usará VBScript. Sin embargo, cuando una técnica de programación es específica de VBScript, se llamará.

    VBScript tiene básicamente dos formas independientes de acceder a WMI. El primero usa un objeto SWbemLocator para conectarse a WMI. Como alternativa, puede usar GetObject y un moniker. Un moniker es una cadena que puede describir varios elementos: las credenciales, la configuración de suplantación, el equipo al que desea conectarse, el espacio de nombres WMI ( es decir, la ubicación general donde WMI almacena grupos de objetos) y el objeto WMI al que desea recuperar. Muchos de los ejemplos siguientes describen ambas técnicas. Para obtener más información, vea Construir una cadena de Moniker y Describir la ubicación de un objeto WMI.

    Independientemente de la técnica que use para conectarse a WMI, es probable que recupere uno o varios objetos de la API de scripting. El más común es SWbemObject, que WMI usa para describir un objeto WMI. Como alternativa, puede usar un objeto SWbemServices para describir el propio servicio WMI o un objeto SWbemObjectPath para describir la ubicación de un objeto WMI. Para obtener más información, vea Scripting with SWbemObject and Scripting Helper Objects.

Uso de WMI y un lenguaje de scripting, Cómo...

... conectarse a WMI?

Para VBScript y la API de scripting para WMI, recupere un objeto SWbemServices con un moniker y una llamada a GetObject. Como alternativa, puede conectarse al servidor con una llamada a SWbemLocator.ConnectServer. A continuación, puede usar el objeto para tener acceso a un espacio de nombres WMI específico o a una instancia de clase WMI.

Para PowerShell, la conexión a WMI se realiza normalmente directamente en la llamada de cmdlet; por lo tanto, no se necesitan pasos adicionales.

Para obtener más información, vea Describir la ubicación de un objeto WMI, construir una cadena de moniker y conectarse a WMI con 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 información de WMI?

Para VBScript y la API de scripting para WMI, use una función de recuperación, como WbemServices.Get o WbemServices.InstancesOf. También puede colocar el nombre de clase del objeto que se va a recuperar en un moniker, lo que puede ser más eficaz.

Para PowerShell, use el parámetro -Class . Tenga en cuenta que -Class es el parámetro predeterminado; por lo tanto, no es necesario indicarlo explícitamente.

Para obtener más información, vea Recuperar datos de instancia o clase 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

... crear una consulta WMI?

Para VBScript y la API de scripting para WMI, use el método SWbemServices.ExecQuery .

Para PowerShell, use el parámetro -Query . También puede filtrar mediante el parámetro -Filter .

Para obtener más información, consulte Consulta de 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 a través de una lista de objetos WMI?

Para VBScript y la API de scripting para WMI, use el objeto contenedor SWbemObjectSet , que se trata en el script como una colección que se puede enumerar. Puede recuperar un SWbemObjectSet desde una llamada desde SWbemServices.InstancesOf o SWbemServices.ExecQuery.

PowerShell puede recuperar y controlar las enumeraciones como lo haría con cualquier otro objeto; no hay nada particularmente único para WMI.

Para obtener más información, consulte Acceso a una colección.

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 }

... ¿tiene acceso a otro espacio de nombres WMI?

Para VBScript y la API de scripting para WMI, indique el espacio de nombres en el moniker o, de lo contrario, puede indicar explícitamente el espacio de nombres en la llamada a SwbemLocator.ConnectServer.

Para PowerShell, use el parámetro -Namespace . El espacio de nombres predeterminado es "root\cimV2"; sin embargo, muchas clases anteriores se almacenan en "root\default".

Para buscar la ubicación de una clase WMI determinada, examine la página de referencia. Como alternativa, puede explorar manualmente un espacio de nombres mediante 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

... ¿recupera todas las instancias secundarias de una clase?

Para los lenguajes que usan directamente la API de scripting para WMI y PowerShell, WMI admite la recuperación de las clases secundarias de una clase base. Por lo tanto, para recuperar las instancias secundarias, solo debe buscar la clase primaria. En el ejemplo siguiente se busca CIM_LogicalDisk, que es una clase WMI preinstalada que representa discos lógicos en un sistema de equipo basado en Windows. Por lo tanto, la búsqueda de esta clase primaria también devuelve instancias de Win32_LogicalDisk, que es lo que Windows usa para describir las unidades de disco duro. Para obtener más información, vea Common Information Model. WMI proporciona un esquema completo de estas clases preinstaladas que permiten acceder a los objetos administrados y controlarlo. Para obtener más información, vea Clases Win32 y Clases WMI.

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

... buscar un objeto WMI?

Para la API de scripting para WMI y PowerShell, WMI usa una combinación de propiedades de espacio de nombres, nombre de clase y clave para identificar de forma única una instancia de WMI determinada. Juntos, esto se conoce como ruta de acceso del objeto WMI. Para VBScript, la propiedad SWbemObject.Path_ describe la ruta de acceso de cualquier objeto determinado devuelto por la API de scripting. Para PowerShell, cada objeto WMI tendrá una propiedad __PATH. Para obtener más información, vea Descripción de la ubicación de un objeto WMI.

Además del espacio de nombres y el nombre de clase, un objeto WMI también tendrá una propiedad de clave, que identifica de forma única esa instancia en comparación con otras instancias de la máquina. Por ejemplo, la propiedad DeviceID es la propiedad clave de la clase Win32_LogicalDisk . Para obtener más información, consulte Formato de objeto administrado (MOF).

Por último, la ruta de acceso relativa es simplemente una forma abreviada de la ruta de acceso e incluye el nombre de clase y el valor de clave. En los ejemplos siguientes, la ruta de acceso puede ser "\\computerName\root\cimv2:Win32_LogicalDisk.DeviceID="D:"", mientras que la ruta de acceso relativa sería ""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  }

... establecer información en WMI?

Para VBScript y la API de scripting para WMI, use el método SWbemObject.Put_ .

Para PowerShell, puede usar el método Put o, de lo contrario, Set-WmiInstance.

Para obtener más información, consulte Modificación de una propiedad de instancia.

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 credenciales diferentes?

Para VBScript y la API de scripting para WMI, use los parámetros UserName y Password en el método SWbemLocator.ConnectServer .

Para PowerShell, use el parámetro -Credential .

Tenga en cuenta que solo puede usar credenciales alternativas en un sistema remoto. Para obtener más información, consulte Protección de clientes de scripting.

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

... acceder a un equipo remoto?

Para VBScript y la API de scripting para WMI, indique explícitamente el nombre del equipo en el moniker, o bien en la llamada a SWbemLocator.ConnectServer. Para obtener más información, consulte Conexión a WMI de forma remota con VBScript.

Para PowerShell, use el parámetro -ComputerName . Para obtener más información, consulte Conexión a WMI de forma remota con 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

... establezca los niveles de autenticación y suplantación?

Para VBScript y la API de scripting para WMI, use la propiedad SWbemServices.Security_ en el objeto de servidor devuelto, o bien establezca los valores pertinentes en el moniker.

Para PowerShell, use los parámetros -Authentication y -Impersonation , respectivamente. Para obtener más información, consulte Protección de clientes de scripting.

Para obtener más información, consulte Protección de clientes de scripting.

' 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

... controlar los errores en WMI?

Para la API de scripting para WMI, el proveedor puede proporcionar un objeto SWbemLastError para proporcionar más información sobre un error.

En VBScript en particular, también se admite el control de errores mediante el objeto Err nativo. También puede acceder al objeto SWbemLastError, como se ha descrito anteriormente. Para obtener más información, consulte Recuperación de un código de error.

Para PowerShell, puede usar las técnicas estándar de control de errores de PowerShell. Para obtener más información, consulte Introducción al control de errores en 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