Création d’un script WMI

Vous pouvez afficher ou manipuler toutes les informations rendues disponibles via WMI à l’aide de scripts. Les scripts peuvent être écrits dans n’importe quel langage de script qui prend en charge l’hébergement de scripts Microsoft ActiveX, y compris Visual Basic Scripting Edition (VBScript), PowerShell et Perl. Windows Script Host (WSH), les pages Active Server et Explorer Internet peuvent tous héberger des scripts WMI.

Notes

Le langage de script principal actuellement pris en charge par WMI est PowerShell. Toutefois, WMI contient également un ensemble robuste de prise en charge des scripts pour VBScript et d’autres langages qui accèdent à l’API Scripting pour WMI.

 

Langages de script WMI

Les deux principaux langages pris en charge par WMI sont PowerShell et VBScript (via l’hôte de script Windows ou WSH).

  • PowerShell a été conçu avec une intégration étroite avec WMI à l’esprit. Par conséquent, la plupart des éléments sous-jacents de WMI sont intégrés aux applets de commande WMI : Get-WmiObject, Set-WmiInstance, Invoke-WmiMethod et Remove-WmiObject. Le tableau suivant décrit les processus généraux utilisés pour accéder aux informations WMI. Notez que bien que la plupart de ces exemples utilisent Get-WMIObject, la plupart des applets de commande WMI PowerShell ont les mêmes paramètres, tels que -Class ou -Credentials. Par conséquent, la plupart de ces processus fonctionnent également pour d’autres objets. Pour une présentation plus approfondie de PowerShell et de WMI, consultez Utilisation de l’applet de commande Get-WMiObject et Windows PowerShell : la connexion WMI.

  • VBScript, en revanche, effectue explicitement des appels à l’API Scripting pour WMI, comme mentionné ci-dessus. D’autres langages, tels que Perl, peuvent également utiliser l’API Scripting pour WMI. Toutefois, pour les besoins de cette documentation, la plupart des exemples qui illustrent l’API Scripting pour WMI utilisent VBScript. Toutefois, lorsqu’une technique de programmation est spécifique à VBScript, elle est appelée.

    VBScript a essentiellement deux façons distinctes d’accéder à WMI. La première consiste à utiliser un objet SWbemLocator pour se connecter à WMI. Vous pouvez également utiliser GetObject et un moniker. Un moniker est une chaîne qui peut décrire un certain nombre d’éléments : vos informations d’identification, les paramètres d’emprunt d’identité, l’ordinateur auquel vous souhaitez vous connecter, l’espace de noms WMI (c’est-à-dire, l’emplacement général où WMI stocke des groupes d’objets) et l’objet WMI que vous souhaitez récupérer. Bon nombre des exemples ci-dessous décrivent les deux techniques. Pour plus d’informations, consultez Construction d’une chaîne moniker et Description de l’emplacement d’un objet WMI.

    Quelle que soit la technique que vous utilisez pour vous connecter à WMI, vous allez probablement récupérer un ou plusieurs objets à partir de l’API Scripting. Le plus courant est SWbemObject, que WMI utilise pour décrire un objet WMI. Vous pouvez également utiliser un objet SWbemServices pour décrire le service WMI lui-même ou un objet SWbemObjectPath pour décrire l’emplacement d’un objet WMI. Pour plus d’informations, consultez Créer des scripts avec SWbemObject et Objets d’aide à la création de scripts.

À l’aide de WMI et d’un langage de script, comment...

...me connecter à WMI ?

Pour VBScript et l’API Scripting pour WMI, récupérez un objet SWbemServices avec un moniker et un appel à GetObject. Vous pouvez également vous connecter au serveur avec un appel à SWbemLocator.ConnectServer. Vous pouvez ensuite utiliser l’objet pour accéder à un espace de noms WMI ou à une instance de classe WMI spécifique.

Pour PowerShell, la connexion à WMI s’effectue généralement directement dans l’appel d’applet de commande. Par conséquent, aucune étape supplémentaire n’est nécessaire.

Pour plus d’informations, consultez Description de l’emplacement d’un objet WMI, Construction d’une chaîne moniker et Connexion à WMI avec 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

...récupérer des informations à partir de WMI ?

Pour VBScript et l’API Scripting pour WMI, utilisez une fonction de récupération, telle que WbemServices.Get ou WbemServices.InstancesOf. Vous pouvez également placer le nom de classe de l’objet à récupérer dans un moniker, ce qui peut être plus efficace.

Pour PowerShell, utilisez le paramètre -Class. Notez que -Class est le paramètre par défaut. En tant que tel, vous n’avez pas besoin de l’indiquer explicitement.

Pour plus d’informations, consultez Récupération de données de classe ou d’instance 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

...créer une requête WMI ?

Pour VBScript et l’API Scripting pour WMI, utilisez la méthode SWbemServices.ExecQuery.

Pour PowerShell, utilisez le paramètre -Query. Vous pouvez également filtrer à l’aide du paramètre -Filter.

Pour plus d'informations, consultez Interrogation 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:'"

...énumérer par le biais d’une liste d’objets WMI ?

Pour VBScript et l’API Scripting pour WMI, utilisez l’objet conteneur SWbemObjectSet, qui est traité dans le script comme une collection pouvant être énumérée. Vous pouvez récupérer un SWbemObjectSet à partir d’un appel de SWbemServices.InstancesOf ou de SWbemServices.ExecQuery.

PowerShell est en mesure de récupérer et de gérer des énumérations comme il le ferait avec n’importe quel autre objet. Il n’y a rien de particulier à WMI.

Pour plus d’informations, consultez Accès à une collection.

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 }

...accéder à un autre espace de noms WMI ?

Pour VBScript et l’API Scripting pour WMI, indiquez l’espace de noms dans le moniker, sinon vous pouvez indiquer explicitement l’espace de noms dans l’appel à SwbemLocator.ConnectServer.

Pour PowerShell, utilisez le paramètre -Namespace. L’espace de noms par défaut est « root\cimV2 ». Toutefois, de nombreuses classes plus anciennes sont stockées dans « root\default ».

Pour trouver l’emplacement d’une classe WMI donnée, consultez la page de référence. Vous pouvez également explorer manuellement un espace de noms à l’aide de 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

...récupérer toutes les instances enfants d’une classe ?

Pour les langages qui utilisent directement l’API Scripting pour WMI et PowerShell, WMI prend en charge la récupération des classes enfants d’une classe de base. Par conséquent, pour récupérer les instances enfants, vous devez uniquement rechercher la classe parente. L’exemple suivant recherche CIM_LogicalDisk, qui est une classe WMI préinstallée qui représente des disques logiques sur un système informatique basé sur Windows. Par conséquent, la recherche de cette classe parente retourne également des instances de Win32_LogicalDisk, ce que Windows utilise pour décrire les disques durs. Pour plus d’informations, consultez Common Information Model. WMI fournit un schéma entier de ces classes préinstallées qui vous permettent d’accéder aux objets managés et de les contrôler. Pour plus d’informations, consultez Classes Win32 et Classes WMI.

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

...localiser un objet WMI ?

Pour l’API Scripting pour WMI et PowerShell, WMI utilise une combinaison de propriétés d’espace de noms, de nom de classe et de clé pour identifier de manière unique une instance WMI donnée. Cet ensemble de propriétés est connu comme chemin d’accès de l’objet WMI. Pour VBScript, la propriété SWbemObject.Path_ décrit le chemin d’accès d’un objet donné retourné par l’API de script. Pour PowerShell, chaque objet WMI aura une propriété __PATH. Pour plus d’informations, consultez Description de l’emplacement d’un objet WMI

En plus de l’espace de noms et du nom de classe, un objet WMI aura également une propriété clé, qui identifie de manière unique l’instance par rapport à d’autres instances sur votre ordinateur. Par exemple, la propriété DeviceID est la propriété clé de la classe Win32_LogicalDisk. Pour plus d’informations, consultez Format MOF.

Enfin, le chemin d’accès relatif est simplement une forme abrégée du chemin d’accès et inclut le nom de la classe et la valeur de clé. Dans les exemples ci-dessous, le chemin d’accès peut être « \\computerName\root\cimv2:Win32_LogicalDisk.DeviceID="D:" », alors que le chemin d’accès relatif est « "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  }

...définir des informations dans WMI ?

Pour VBScript et l’API Scripting pour WMI, utilisez la méthode SWbemObject.Put_.

Pour PowerShell, vous pouvez utiliser la méthode Put, ou bien Set-WmiInstance.

Pour plus d’informations, consultez Modification d’une propriété d’instance.

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}

...utiliser d’autres informations d’identification ?

Pour VBScript et l’API Scripting pour WMI, utilisez les paramètres UserName et Password dans la méthode SWbemLocator.ConnectServer.

Pour PowerShell, utilisez le paramètre -Credential.

Notez que vous pouvez uniquement utiliser d’autres informations d’identification sur un système distant. Pour plus d’informations, consultez Sécurisation des clients de scripts.

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

...accéder à un ordinateur distant ?

Pour VBScript et l’API Scripting pour WMI, indiquez explicitement le nom de l’ordinateur dans le moniker ou dans l’appel à SWbemLocator.ConnectServer. Pour plus d’informations, consultez Connexion à WMI à distance à partir de VBScript.

Pour PowerShell, utilisez le paramètre -ComputerName. Pour plus d’informations, consultez Connexion à WMI à distance à partir de 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

...définir les niveaux d’authentification et d’emprunt d’identité ?

Pour VBScript et l’API Scripting pour WMI, utilisez la propriété SWbemServices.Security_ sur l’objet serveur retourné, ou définissez les valeurs appropriées dans le moniker.

Pour PowerShell, utilisez les paramètres -Authentication et -Impersonation, respectivement. Pour plus d’informations, consultez Sécurisation des clients de scripts.

Pour plus d’informations, consultez Sécurisation des clients de scripts.

' 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

...gérer les erreurs dans WMI ?

Pour l’API Scripting pour WMI, le fournisseur peut fournir un objet SWbemLastError pour fournir des informations supplémentaires sur une erreur.

Dans VBScript en particulier, la gestion des erreurs est également prise en charge à l’aide de l’objet Err natif. Vous pouvez également accéder à l’objet SWbemLastError, comme décrit ci-dessus. Pour plus d’informations, consultez Récupération d’un code d’erreur.

Pour PowerShell, vous pouvez utiliser les techniques de gestion des erreurs PowerShell standard. Pour plus d’informations, consultez Présentation de la gestion des erreurs dans 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