Condividi tramite


Creazione di uno script WMI

È possibile visualizzare o modificare le informazioni rese disponibili 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 di Active Server 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 scripting per VBScript e altri linguaggi che accedono all'API di scripting per WMI.

 

Linguaggi di scripting WMI

I due linguaggi principali supportati da WMI sono PowerShell e VBScript (tramite Windows Script Host o WSH).

  • powerShell è stato progettato con una stretta integrazione con WMI. Di conseguenza, gran parte degli elementi sottostanti di WMI sono incorporati nei cmdlet WMI: Get-WmiObject, Set-WmiInstance, Invoke-WmiMethode Remove-WmiObject. Nella tabella seguente vengono descritti i processi generali usati per accedere alle informazioni WMI. Si noti che, mentre la maggior parte di questi esempi usa Get-WMIObject, molti dei cmdlet WMI di PowerShell hanno gli stessi parametri, ad esempio -Class o -Credentials. Di conseguenza, molti di questi processi funzionano anche per altri oggetti. Per una descrizione più approfondita di PowerShell e WMI, vedere Using the Get-WMiObject Cmdlet and Windows PowerShell - the WMI Connection.

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

    VBScript ha essenzialmente due modi distinti 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 diversi elementi: le credenziali, le impostazioni di rappresentazione, il computer a cui ci si vuole connettere, lo spazio dei nomi WMI (ad esempio, la posizione generale in cui WMI archivia gruppi di oggetti) e l'oggetto WMI a cui si desidera recuperare. Molti degli esempi seguenti descrivono entrambe le tecniche. Per altre informazioni, vedere Costruzione di una stringa moniker e Descrizione della posizione di un oggetto WMI.

    Indipendentemente dalla tecnica usata per connettersi a WMI, è probabile che si recuperi uno o più oggetti dall'API di scripting. Il più comune è SWbemObject, che WMI usa per descrivere un oggetto WMI. In alternativa, è possibile utilizzare un oggetto SWbemServices per descrivere il servizio WMI stesso oppure un oggetto SWbemObjectPath per descrivere la posizione di un oggetto WMI. Per ulteriori informazioni, vedere Script con SWbemObject e Oggetti di Aiuto per Script.

Utilizzando WMI e un linguaggio di scripting, come faccio a...

... connettersi a WMI?

Per VBScript e l'API di scripting per WMI, ottenere 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 della 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 monikere 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 risultare più efficiente.

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

Per altre informazioni, vedere Recuperare la classe WMI o i dati 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 metodoSWbemServices.ExecQuery.

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

Per altre informazioni, vedere Interrogare 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 un elenco di oggetti WMI?

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

PowerShell è in grado di recuperare e gestire enumerazioni come 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, è necessario specificare lo spazio dei nomi nel moniker, oppure è possibile indicare esplicitamente 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 meno recenti vengono archiviate in "root\default".

Per trovare la posizione di una determinata classe WMI, esaminare 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 figlie di una classe?

Per i linguaggi che usano direttamente l'API di scripting per WMI e PowerShell, WMI supporta il recupero delle classi figlio di una classe di base. Di conseguenza, per recuperare le istanze figlio, è sufficiente cercare la classe padre. L'esempio seguente cerca CIM_LogicalDisk, ovvero una classe WMI preinstallata che rappresenta i dischi logici in un sistema di computer basato su Windows. Di conseguenza, la ricerca di questa classe padre restituisce anche istanze di Win32_LogicalDisk, che è 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?

Sia per l'API di scripting per WMI che per PowerShell, WMI utilizza una combinazione di spazio dei nomi, nome della classe e proprietà chiave per identificare in modo univoco una determinata istanza di WMI. Insieme, questo percorso è 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 del 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  }

... settare le informazioni su WMI?

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

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

Per altre informazioni, vedere Modifica di una proprietà dell'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, indicare in modo esplicito il nome del computer nel moniker oppure nella chiamata a SWbemLocator.ConnectServer. Per altre informazioni, vedere Connessione remota a WMI 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 impersonazione?

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

Per PowerShell, utilizzare 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 di 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'oggettoSWbemLastError, come descritto in precedenza. Per altre informazioni, vedere Recupero di un codice di errore.

Per PowerShell, è possibile usare le tecniche standard di gestione degli errori di PowerShell. 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