Creación de un script de WMI

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

Nota

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

 

Lenguajes de scripting de WMI

Los dos lenguajes principales admitidos por WMI son PowerShell y VBScript (por medio de Windows Script Host o WSH).

  • PowerShell se ha diseñado teniendo en cuenta su estrecha integración con WMI. Por tanto, gran parte de los elementos subyacentes de WMI se integrados en los cmdlets de 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 en la mayoría de estos ejemplos se usa Get-WMIObject, muchos de los cmdlets de WMI de PowerShell tienen los mismos parámetros, como -Class o -Credentials. Por tanto, muchos de estos procesos también funcionan para otros objetos. Para obtener una explicación más detallada de PowerShell y WMI, vea Uso del cmdlet Get-WMiObject y Windows PowerShell: conexión a WMI.

  • VBScript, por el contrario, realiza explícitamente llamadas a la API de scripting para WMI, como se ha mencionado antes. Otros lenguajes, como Perl, también pueden usar la API de scripting para WMI. Pero para los fines de esta documentación, en la mayoría de los ejemplos que muestran la API de scripting para WMI se usará VBScript. Pero cuando una técnica de programación sea específica de VBScript, se indicará.

    VBScript tiene básicamente dos formas independientes de acceder a WMI. En la primera se 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: sus credenciales, configuración de suplantación, el equipo al que quiere conectarse, el espacio de nombres de WMI (es decir, la ubicación general donde WMI almacena grupos de objetos) y el objeto WMI que quiere recuperar. En muchos de los ejemplos siguientes se describen ambas técnicas. Para más información, vea Construcción de una cadena de moniker y Descripción de la ubicación de un objeto de 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 de 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 de WMI. Para más información, vea Scripting con SWbemObject y Objetos auxiliares de scripting.

Uso de WMI y un lenguaje de scripting, Procedimiento para...

... 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. Después, puede usar el objeto para acceder a un espacio de nombres WMI específico o a una instancia de clase WMI.

Para PowerShell, la conexión a WMI se suele realizar directamente en la llamada de cmdlet; por tanto, no es necesario realizar ningún paso adicional.

Para más información, vea Descripción de la ubicación de un objeto de WMI, Construcción de una cadena de moniker y Conexión 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 tanto, no es necesario indicarlo explícitamente.

Para más información, vea Recuperación de datos de instancia o clase de 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 de 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 más información, vea 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 por una lista de objetos de 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 una instancia de 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 especialmente único para WMI.

Para más información, vea 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 }

... acceder 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"; pero muchas clases antiguas 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

... recuperar todas las instancias secundarias de una clase

En el caso de 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 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 informático basado en Windows. Por 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 más información, vea Modelo de información común. WMI proporciona un esquema completo de estas clases preinstaladas que le permite acceder a los objetos administrados y controlarlos. Para más información, vea Clases de 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 de 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. De manera conjunta, esto se conoce como ruta de acceso del objeto de 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 de WMI tendrá una propiedad __PATH. Para más información, vea Descripción de la ubicación de un objeto de WMI

Además del espacio de nombres y el nombre de clase, un objeto de WMI también tendrá una propiedad de clave, que identifica de forma única esa instancia en comparación con otras de la máquina. Por ejemplo, la propiedad DeviceID es la propiedad clave de la clase Win32_LogicalDisk. Para más información, vea Managed Object Format (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 "\\nombreEquipo\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 Set-WmiInstance.

Para más información, vea 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 otras credenciales

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 más información, vea 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 en la llamada a SWbemLocator.ConnectServer. Para más información, vea Conexión a WMI de forma remota con VBScript.

Para PowerShell, use el parámetro -ComputerName. Para más información, vea 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

... establecer 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 e -Impersonation, respectivamente. Para más información, vea Protección de clientes de scripting.

Para más información, vea 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 errores en WMI

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

En VBScript en concreto, 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 más información, vea Recuperación de un código de error.

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