Creazione di uno script WMI

È possibile visualizzare o modificare qualsiasi informazione resa disponibile tramite WMI usando script. Gli script possono essere scritti in qualsiasi linguaggio di scripting che supporta l'hosting di script Microsoft ActiveX, tra cui Visual Basic Scripting Edition (VBScript), PowerShell e Perl. Windows Script Host (WSH), Pagine server attive e Internet Explorer possono ospitare tutti gli script WMI.

Nota

Il linguaggio di scripting primario attualmente supportato da WMI è PowerShell. WMI contiene tuttavia anche un corpo affidabile del supporto di script per VBScript e altri linguaggi che accedono all'API scripting per WMI.

 

Linguaggi di scripting WMI

I due linguaggi principali supportati da WMI sono PowerShell e VBScript (tramite l'host script di Windows o WSH).

  • PowerShell è stato progettato con un'integrazione stretta con WMI in mente. Di conseguenza, gran parte degli elementi sottostanti di WMI sono incorporati nei cmdlet WMI: Get-WmiObject, Set-WmiInstance, Invoke-WmiMethod e Remove-WmiObject. Nella tabella seguente vengono descritti i processi generali usati per l'accesso alle informazioni WMI. Si noti che la maggior parte di questi esempi usa Get-WMIObject, molti dei cmdlet WMI di PowerShell hanno gli stessi parametri, ad esempio -Class o -Credentials. Pertanto, molti di questi processi funzionano anche per altri oggetti. Per una discussione più approfondita su PowerShell e WMI, vedere Uso del cmdlet Get-WMiObject e Windows PowerShell - Connessione WMI.

  • VBScript, al contrario, effettua in modo esplicito chiamate all'API scripting per WMI, come indicato in precedenza. Altri linguaggi, ad esempio Perl, possono anche usare l'API di scripting per WMI. Tuttavia, ai fini di questa documentazione, la maggior parte degli esempi che illustrano l'API di scripting per WMI userà VBScript. Quando una tecnica di programmazione è specifica di VBScript, tuttavia, verrà chiamata.

    VBScript ha essenzialmente due modi separati per accedere a WMI. Il primo consiste nell'usare un oggetto SWbemLocator per connettersi a WMI. In alternativa, è possibile usare GetObject e un moniker. Un moniker è una stringa che può descrivere un numero di elementi: le credenziali, le impostazioni di rappresentazione, il computer a cui si vuole connettersi, lo spazio dei nomi WMI (ovvero la posizione generale in cui WMI archivia gruppi di oggetti) e l'oggetto WMI da recuperare. Molti degli esempi seguenti descrivono entrambe le tecniche. Per altre informazioni, vedere Creazione di una stringa moniker e descrizione della posizione di un oggetto WMI.

    Indipendentemente dalla tecnica usata per connettersi a WMI, è probabile che venga recuperato uno o più oggetti dall'API scripting. Il più comune è SWbemObject, che WMI usa per descrivere un oggetto WMI. In alternativa, è possibile usare un oggetto SWbemServices per descrivere il servizio WMI stesso o un oggetto SWbemObjectPath per descrivere la posizione di un oggetto WMI. Per altre informazioni, vedere Scripting con oggetti helper SWbemObject e scripting.

Uso di WMI e di un linguaggio di scripting, come fare io...

... connettersi a WMI?

Per VBScript e l'API scripting per WMI, recuperare un oggetto SWbemServices con un moniker e una chiamata a GetObject. In alternativa, è possibile connettersi al server con una chiamata a SWbemLocator.ConnectServer. È quindi possibile usare l'oggetto per accedere a uno spazio dei nomi WMI specifico o a un'istanza di classe WMI.

Per PowerShell, la connessione a WMI viene in genere eseguita direttamente nella chiamata al cmdlet; di conseguenza, non sono necessari passaggi aggiuntivi.

Per altre informazioni, vedere Descrizione della posizione di un oggetto WMI, costruzione di una stringa moniker e connessione 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

... recuperare informazioni da WMI?

Per VBScript e l'API di scripting per WMI, usare una funzione di recupero, ad esempio WbemServices.Get o WbemServices.InstancesOf. È anche possibile inserire il nome della classe dell'oggetto da recuperare in un moniker, che potrebbe essere più efficiente.

Per PowerShell, usare il parametro -Class . Si noti che -Class è il parametro predefinito; di conseguenza, non è necessario specificarlo in modo esplicito.

Per altre informazioni, vedere Recupero di dati della classe WMI o dell'istanza.

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

... creare una query WMI?

Per VBScript e l'API di scripting per WMI, usare il metodo SWbemServices.ExecQuery .

Per PowerShell, usare il parametro -Query . È anche possibile filtrare usando il parametro -Filter .

Per altre informazioni, vedere Query su 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:'"

... enumerare tramite un elenco di oggetti WMI?

Per VBScript e l'API scripting per WMI, usare l'oggetto contenitore SWbemObjectSet , considerato nello script come raccolta che può essere enumerata. È possibile recuperare un oggetto SWbemObjectSet da una chiamata da SWbemServices.InstancesOf o SWbemServices.ExecQuery.

PowerShell è in grado di recuperare e gestire le enumerazioni perché sarebbe qualsiasi altro oggetto; non c'è nulla di particolarmente univoco per WMI.

Per altre informazioni, vedere Accesso a una raccolta.

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 }

... accedere a uno spazio dei nomi WMI diverso?

Per VBScript e l'API di scripting per WMI, stato lo spazio dei nomi nel moniker oppure è possibile stato in modo esplicito lo spazio dei nomi nella chiamata a SwbemLocator.ConnectServer.

Per PowerShell usare il parametro -Namespace . Lo spazio dei nomi predefinito è "root\cimV2"; tuttavia, molte classi precedenti vengono archiviate in "root\default".

Per trovare la posizione di una determinata classe WMI, vedere la pagina di riferimento. In alternativa, è possibile esplorare manualmente uno spazio dei nomi 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

... recuperare tutte le istanze figlio di una classe?

Per le lingue che usano direttamente l'API scripting per WMI e PowerShell, WMI supporta il recupero delle classi figlio di una classe di base. Di conseguenza, per recuperare le istanze figlio, è necessario cercare solo la classe padre. L'esempio seguente cerca CIM_LogicalDisk, ovvero una classe WMI preinstallata che rappresenta i dischi logici in un sistema computer basato su Windows. Di conseguenza, la ricerca di questa classe padre restituisce anche istanze di Win32_LogicalDisk, ovvero ciò che Windows usa per descrivere i dischi rigidi. Per altre informazioni, vedere Common Information Model. WMI fornisce un intero schema di tali classi preinstallate che consentono di accedere e controllare gli oggetti gestiti. Per altre informazioni, vedere Classi Win32 e classi WMI.

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

... individuare un oggetto WMI?

Per l'API scripting per WMI e PowerShell, WMI usa una combinazione di spazi dei nomi, nome di classe e proprietà chiave per identificare in modo univoco un'istanza WMI specificata. Insieme, questo è noto come percorso dell'oggetto WMI. Per VBScript, la proprietà SWbemObject.Path_ descrive il percorso per qualsiasi oggetto specificato restituito dall'API di scripting. Per PowerShell, ogni oggetto WMI avrà una proprietà __PATH. Per altre informazioni, vedere Descrizione della posizione di un oggetto WMI

Oltre allo spazio dei nomi e al nome della classe, un oggetto WMI avrà anche una proprietà chiave, che identifica in modo univoco tale istanza rispetto ad altre istanze nel computer. Ad esempio, la proprietà DeviceID è la proprietà chiave per la classe Win32_LogicalDisk . Per altre informazioni, vedere Managed Object Format (MOF).

Infine, il percorso relativo è semplicemente una forma abbreviata del percorso e include il nome della classe e il valore della chiave. Negli esempi seguenti il percorso può essere "\\computerName\root\cimv2:Win32_LogicalDisk.DeviceID="D:"", mentre il percorso relativo sarà ""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  }

... impostare le informazioni in WMI?

Per VBScript e l'API scripting per WMI, usare il metodo SWbemObject.Put_ .

Per PowerShell è possibile usare il metodo Put oppure Impostare-WmiInstance.

Per altre informazioni, vedere Modifica di una proprietà di istanza.

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}

... usare credenziali diverse?

Per VBScript e l'API di scripting per WMI, usare i parametri UserName e Password nel metodo SWbemLocator.ConnectServer .

Per PowerShell, usare il parametro -Credential .

Si noti che è possibile usare solo credenziali alternative in un sistema remoto. Per altre informazioni, vedere Protezione dei client di 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

... accedere a un computer remoto?

Per VBScript e l'API di scripting per WMI, specificare in modo esplicito il nome del computer nel moniker oppure nella chiamata a SWbemLocator.ConnectServer. Per altre informazioni, vedere Connessione a WMI In remoto con VBScript.

Per PowerShell usare il parametro -ComputerName . Per altre informazioni, vedere Connessione a WMI In remoto 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

... impostare i livelli di autenticazione e rappresentazione?

Per VBScript e l'API scripting per WMI, usare la proprietà SWbemServices.Security_ nell'oggetto server restituito oppure impostare i valori pertinenti nel moniker.

Per PowerShell, usare rispettivamente i parametri -Authentication e -Impersonation . Per altre informazioni, vedere Protezione dei client di scripting.

Per altre informazioni, vedere Protezione dei client di 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

... gestire gli errori in WMI?

Per l'API scripting per WMI, il provider può fornire un oggetto SWbemLastError per fornire ulteriori informazioni su un errore.

In VBScript in particolare, la gestione degli errori è supportata anche usando l'oggetto Err nativo. È anche possibile accedere all'oggetto SWbemLastError, come descritto in precedenza. Per altre informazioni, vedere Recupero di un codice di errore.

Per PowerShell è possibile usare le tecniche di gestione degli errori di PowerShell standard. Per altre informazioni, vedere Introduzione alla gestione degli errori in 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