Windows Management Instrumentation (WMI) has long been a core management feature in Windows. It offers amazing breadth, wide reach, and ubiquitous remoting.
What WMI lacked in the past, though, was a good way to get to it. Graphically, the wbemtest.exe utility lets you experiment with WMI, its namespaces, and classes. It truly is a testing tool, though, as its complex user interface makes it impractical to use for most scenarios (see Figure 28-1).
A more user-friendly alternative is the wmic.exe command-line tool. The WMIC tool lets you interactively query WMI—but more importantly, automate its behavior. As with PowerShell, results within WMIC retain a great deal of their structured information and let you write fairly detailed queries:
PS > WMIC logicaldisk WHERE drivetype=3 ` GET "name,freespace,SystemName,FileSystem,Size" FileSystem FreeSpace Name Size SystemName NTFS 10587656192 C: 34357637120 LEEHOLMES1C23
The language is limited, however, and all of the data’s structure is lost once WMIC converts its output to text.
By far, the most popular user interface for WMI has been VBScript, the administrator’s traditional scripting language. VBScript offers much richer language facilities than WMIC and retains WMI’s structured data for the entire duration of your script.
VBScript has its own class of usability difficulties, however. For example, generating a report of the processes running on a computer often ends up looking like this:
strComputer = "atl-dc-01" Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" _ & strComputer & " ootcimv2") Set colProcessList = objWMIService.ExecQuery _ ("Select * from Win32_Process") For Each objProcess in colProcessList Wscript.Echo "Process: " & objProcess.Name Wscript.Echo "Process ID: " & objProcess.ProcessID Wscript.Echo "Thread Count: " & objProcess.ThreadCount Wscript.Echo "Page File Size: " _ & objProcess.PageFileUsage Wscript.Echo "Page Faults: " _ & objProcess.PageFaults Wscript.Echo "Working Set Size: " _ & objProcess.WorkingSetSize Next
It also requires that you write an entire script, and it offers no lightweight interactive experience. The Microsoft Scripting Guys’ Scriptomatic tool helps make it easier to create many of these mundane scripts, but it still doesn’t address one-off queries.
PowerShell elevates WMI to a first-class citizen for both ad-hoc and structured queries. Since most of the template VBScript for dealing with WMI instances ends up being used to display the results, PowerShell eliminates this step completely. The PowerShell equivalent of the preceding VBScript is simply:
Get-WmiObject Win32_Process -Computer atl-dc-01
Or, if you want a subset of properties:
Get-WmiObject Win32_Process | Select Name,ProcessId,ThreadCount
By providing a deep and user-friendly integration with WMI, PowerShell puts a great deal of functionality at the fingertips of every administrator.
To retrieve all instances of a WMI class, use
the Get-WmiObject
cmdlet:
Get-WmiObject -ComputerName Computer
-Class Win32_Bios
To retrieve specific instances of a WMI class
using a WMI filter, supply an argument to the -Filter
parameter of the Get-WmiObject
cmdlet. This is the
WHERE
clause of a WQL statement, but without the
WHERE
keyword:
Get-WmiObject Win32_Service -Filter "StartMode = 'Auto'"
To retrieve instances of a WMI class using
WMI’s WQL language, use the [WmiSearcher]
type shortcut:
$query = [WmiSearcher] "SELECT * FROM Win32_Service WHERE StartMode = 'Auto'" $query.Get()
To retrieve a
specific instance of a WMI class using a WMI filter, use the [Wmi]
type shortcut:
[Wmi] 'Win32_Service.Name="winmgmt"'
To retrieve a property of a WMI instance, access that property as you would access a .NET property:
$service = [Wmi] 'Win32_Service.Name="winmgmt"' $service.StartMode
To invoke a method on a WMI instance, invoke that method as you would invoke a .NET method:
$service = [Wmi] 'Win32_Service.Name="winmgmt"' $service.ChangeStartMode("Manual") $service.ChangeStartMode("Automatic")
To invoke a method on a WMI class, use the
Invoke-WmiMethod
cmdlet. Alternatively,
use the [WmiClass]
type shortcut to
access that WMI class. Then, invoke that method as you would invoke a
.NET method:
Invoke-WmiMethod Win32_Process Create notepad $class = [WmiClass] "Win32_Process" $class.Create("Notepad")
To retrieve a WMI class from a specific
namespace, use its fully qualified name along with the
[WmiClass]
type shortcut:
[WmiClass] "\COMPUTERRootCimv2:Win32_Process"
Working with WMI has long been a staple of managing Windows systems—especially systems that are part of corporate domains or enterprises. WMI supports a huge number of Windows management tasks, albeit not in a very user-friendly way.
Traditionally, administrators required either VBScript or the WMIC command-line tool to access and manage these systems through WMI. While powerful and useful, these techniques still provided plenty of opportunities for improvement. VBScript lacks support for an ad-hoc investigative approach, and WMIC fails to provide (or take advantage of) knowledge that applies to anything outside WMIC.
In comparison, PowerShell lets you work with WMI just like you work with the rest of the shell. WMI instances provide methods and properties, and you work with them the same way you work with methods and properties of other objects in PowerShell.
Not only does PowerShell make working with WMI
instances and classes easy once you have them, but it also provides a
clean way to access them in the first place. For most tasks, you need
only to use the simple [Wmi]
,
[WmiClass]
, or [WmiSearcher]
syntax as shown in the
solution.
Along with WMI’s huge scope, though, comes a related problem: finding the WMI class that accomplishes your task. To assist you in learning what WMI classes are available, Appendix G provides a helpful listing of the most common ones. For a script that helps you search for WMI classes by name, description, property name, or property description, see Program: Search for WMI Classes.
Some advanced WMI tasks require that you enable your security privileges or adjust the packet privacy settings used in your request. All of PowerShell’s WMI cmdlets support these options through built-in parameters.
When you want to access a specific WMI
instance with the [Wmi]
accelerator,
you might at first struggle to determine what properties WMI lets you
search on. These properties are called key properties on the class. For
a script that lists these key properties, see Program: Determine Properties Available to WMI Filters.
For more information about the Get-WmiObject
cmdlet, type Get-Help Get-WmiObject
.
Use the Set-WmiInstance
cmdlet:
PS > $bootVolume = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DeviceID -eq 'C:' } PS > $bootVolume DeviceID : C: DriveType : 3 ProviderName : FreeSpace : 10587656192 Size : 34357637120 VolumeName : Boot Volume PS > $bootVolume | Set-WmiInstance -Arguments @{ VolumeName = 'Vista' } DeviceID : C: DriveType : 3 ProviderName : FreeSpace : 10587656192 Size : 34357637120 VolumeName : Vista
Although you can assign new property values to
the objects output by Get-WmiObject
, changes you make
ultimately are not reflected in the permanent system state, as this
example shows:
PS > $bootVolume = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DeviceID -eq 'C:' } PS > $bootVolume DeviceID : C: DriveType : 3 ProviderName : FreeSpace : 10587656192 Size : 34357637120 VolumeName : Vista PS > $bootVolume.VolumeName = "Boot Volume" PS > Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DeviceID -eq 'C:' } DeviceID : C: DriveType : 3 ProviderName : FreeSpace : 10587652096 Size : 34357637120 VolumeName : Vista
Instead, the
Set-WmiInstance
cmdlet lets you permanently modify
values of WMI instances. While the Set-WmiInstance
cmdlet supports WMI instances as pipeline input, you can also pass the
fully qualified path to the -Path
parameter:
Set-WmiInstance -Path "Win32_LogicalDisk.DeviceID='C:'" ` -Argument @{ VolumeName="Vista" }
To determine which
properties can be modified on an instance, you need to investigate the
WMI class that defines it. Each WMI class has a
Properties
collection, and each property has a
Qualifiers
collection. If Write
is
one of the qualifiers, then that property is writeable:
PS > [WmiClass] "Win32_LogicalDisk" | Select -Expand Properties (...) Name : VolumeName Value : Type : String IsLocal : True IsArray : False Origin : Win32_LogicalDisk Qualifiers : {CIMTYPE, MappingStrings, read, write} Name : VolumeSerialNumber Value : Type : String IsLocal : True IsArray : False Origin : Win32_LogicalDisk Qualifiers : {CIMTYPE, MappingStrings, read} (...)
To automatically see all writeable classes in the
ROOTCIMV2
namespace, simply run this snippet of
PowerShell script:
$writeableProperties = Get-WmiObject -List -Recurse | Select -Expand Properties | Where-Object { $_ | Select -Expand Qualifiers | Where-Object { $_.Name -eq "Write" } } | Select Origin,Name
Like
all other WMI-related cmdlets, the Set-WmiInstance
cmdlet lets you configure impersonation, authentication, and privilege
restrictions. For more information about working with WMI classes, see
Access Windows Management Instrumentation Data.
Use the Invoke-WmiMethod
cmdlet:
PS > Invoke-WmiMethod -Class Win32_Process -Name Create -Args notepad.exe
(notepad starts)
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId : 3644
ReturnValue : 0
As with .NET types, WMI classes describe the
functionality and features of a related set of items. For example, the
Win32_Process
class describes the features and
behavior of an entity called an operating system process. When WMI
returns information about a specific operating system process, that is
called an instance.
As with static methods on .NET types, many WMI
classes offer methods that relate broadly to the entity they try to
represent. For example, the Win32_Process
class
defines methods to start processes, stop them, and more. To invoke any
of these methods, call the Invoke-WmiMethod
cmdlet.
While you may already know the method you want
to call, PowerShell also offers a way to see the methods exposed by WMI
classes on your system. Each WMI class has a Methods
collection, and reviewing that collection lists all methods supported by
that class. The following snippet lists all methods supported by all
classes in the ROOTCIMV2
namespace:
Get-WmiObject -List -Recurse | Select -Expand Methods | Select Origin,Name
Like all other WMI-related cmdlets, the
Invoke-WmiMethod
cmdlet lets you configure
impersonation, authentication, and privilege restrictions.
In addition to the
Invoke-WmiMethod
cmdlet, the
[WmiClass]
type shortcut also lets you refer to a WMI
class and invoke its methods:
$processClass = [WmiClass] "Win32_Process" $processClass.Create("notepad.exe")
This method, however, does not easily support customization of impersonation, authentication, or privilege restrictions.
For more information about working with WMI classes, see Access Windows Management Instrumentation Data.
When you want to access a specific WMI instance with
PowerShell’s [Wmi]
type shortcut, you
might at first struggle to determine what properties WMI lets you search
on. These properties are called key properties on the class. Example 28-1 gets all the
properties you can use in a WMI filter for a given class.
Example 28-1. Get-WmiClassKeyProperty.ps1
############################################################################## ## ## Get-WmiClassKeyProperty ## ## From Windows PowerShell Cookbook (O'Reilly) ## by Lee Holmes (http://www.leeholmes.com/guide) ## ############################################################################## <# .SYNOPSIS Get all of the properties that you can use in a WMI filter for a given class. .EXAMPLE Get-WmiClassKeyProperty Win32_Process Handle #> param( ## The WMI class to examine [WmiClass] $WmiClass ) Set-StrictMode -Version Latest ## WMI classes have properties foreach($currentProperty in $wmiClass.Properties) { ## WMI properties have qualifiers to explain more about them foreach($qualifier in $currentProperty.Qualifiers) { ## If it has a 'Key' qualifier, then you may use it in a filter if($qualifier.Name -eq "Key") { $currentProperty.Name } } }
For more information about running scripts, see Run Programs, Scripts, and Existing Tools.
Along with WMI’s huge scope comes a related problem: finding the WMI class that accomplishes your task. To help you learn what WMI classes are available, Appendix G provides a helpful listing of the most common ones. If you want to dig a little deeper, though, Example 28-2 lets you search for WMI classes by name, description, property name, or property description.
Example 28-2. Search-WmiNamespace.ps1
############################################################################## ## ## Search-WmiNamespace ## ## From Windows PowerShell Cookbook (O'Reilly) ## by Lee Holmes (http://www.leeholmes.com/guide) ## ############################################################################## <# .SYNOPSIS Search the WMI classes installed on the system for the provided match text. .EXAMPLE Search-WmiNamespace Registry Searches WMI for any classes or descriptions that mention "Registry" .EXAMPLE Search-WmiNamespace Process ClassName,PropertyName Searches WMI for any classes or properties that mention "Process" .EXAMPLE Search-WmiNamespace CPU -Detailed Searches WMI for any class names, descriptions, or properties that mention "CPU" #> param( ## The pattern to search for [Parameter(Mandatory = $true)] [string] $Pattern, ## Switch parameter to look for class names, descriptions, or properties [switch] $Detailed, ## Switch parameter to look for class names, descriptions, properties, and ## property description. [switch] $Full, ## Custom match options. ## Supports any or all of the following match options: ## ClassName, ClassDescription, PropertyName, PropertyDescription [string[]] $MatchOptions = ("ClassName","ClassDescription") ) Set-StrictMode -Off ## Helper function to create a new object that represents ## a Wmi match from this script function New-WmiMatch { param( $matchType, $className, $propertyName, $line ) $wmiMatch = New-Object PsObject -Property @{ MatchType = $matchType; ClassName = $className; PropertyName = $propertyName; Line = $line } $wmiMatch } ## If they've specified the -detailed or -full options, update ## the match options to provide them an appropriate amount of detail if($detailed) { $matchOptions = "ClassName","ClassDescription","PropertyName" } if($full) { $matchOptions = "ClassName","ClassDescription","PropertyName","PropertyDescription" } ## Verify that they specified only valid match options foreach($matchOption in $matchOptions) { $fullMatchOptions = "ClassName","ClassDescription","PropertyName","PropertyDescription" if($fullMatchOptions -notcontains $matchOption) { $error = "Cannot convert value {0} to a match option. " + "Specify one of the following values and try again. " + "The possible values are ""{1}""." $ofs = ", " throw ($error -f $matchOption, ([string] $fullMatchOptions)) } } ## Go through all of the available classes on the computer foreach($class in Get-WmiObject -List -Rec) { ## Provide explicit get options, so that we get back descriptions ## as well $managementOptions = New-Object System.Management.ObjectGetOptions $managementOptions.UseAmendedQualifiers = $true $managementClass = New-Object Management.ManagementClass $class.Name,$managementOptions ## If they want us to match on class names, check if their text ## matches the class name if($matchOptions -contains "ClassName") { if($managementClass.Name -match $pattern) { New-WmiMatch "ClassName" ` $managementClass.Name $null $managementClass.__PATH } } ## If they want us to match on class descriptions, check if their text ## matches the class description if($matchOptions -contains "ClassDescription") { $description = $managementClass.Qualifiers | foreach { if($_.Name -eq "Description") { $_.Value } } if($description -match $pattern) { New-WmiMatch "ClassDescription" ` $managementClass.Name $null $description } } ## Go through the properties of the class foreach($property in $managementClass.Properties) { ## If they want us to match on property names, check if their text ## matches the property name if($matchOptions -contains "PropertyName") { if($property.Name -match $pattern) { New-WmiMatch "PropertyName" ` $managementClass.Name $property.Name $property.Name } } ## If they want us to match on property descriptions, check if ## their text matches the property name if($matchOptions -contains "PropertyDescription") { $propertyDescription = $property.Qualifiers | foreach { if($_.Name -eq "Description") { $_.Value } } if($propertyDescription -match $pattern) { New-WmiMatch "PropertyDescription" ` $managementClass.Name $property.Name $propertyDescription } } } }
For more information about running scripts, see Run Programs, Scripts, and Existing Tools.
You want to work with advanced features of WMI, but
PowerShell’s access (through the [Wmi]
, [WmiClass]
, and [WmiSearcher]
accelerators) does not directly
support them.
To interact with advanced features of WMI objects, access their methods and properties.
To get WMI instances related to a given
instance (its associators), call the GetRelated()
method:
$instance = [Wmi] 'Win32_Service.Name="winmgmt"' $instance.GetRelated()
To change advanced scope options, access the
Scope.Options
property. While the
Invoke-WmiMethod
cmdlet lets you enable privileges
directly through a parameter, this example provides another
option:
$system = Get-WmiObject Win32_OperatingSystem $system.Scope.Options.EnablePrivileges = $true $system.SetDateTime($class.ConvertFromDateTime("01/01/2007"))
To retrieve the WMI properties and
qualifiers of a class, access the Properties
property:
$class = [WmiClass] "Win32_Service" $class.Properties
To configure connection options on a query,
such as Packet Privacy and Authentication, set the options on the
Scope
property:
$credential = Get-Credential $query = [WmiSearcher] "SELECT * FROM IISWebServerSetting" $query.Scope.Path = "\REMOTE_COMPUTERRootMicrosoftIISV2" $query.Scope.Options.Username = $credential.Username $query.Scope.Options.Password = $credential.GetNetworkCredential().Password $query.Scope.Options.Authentication = "PacketPrivacy" $query.get() | Select-Object AnonymousUserName
The [Wmi]
,
[WmiClass]
, and [WmiSearcher]
type shortcuts return instances
of .NET System.Management.ManagementObject
, System.Management.ManagementClass
, and
System.Management.ManagementObjectSearcher
classes, respectively.
As might be expected, the .NET Framework provides comprehensive support for WMI queries, with PowerShell providing an easier-to-use interface to that support. If you need to step outside the support offered directly by PowerShell, these classes in the .NET Framework provide an advanced outlet.
For more information about working with classes from the .NET Framework, see Work with .NET Objects.
You want to perform a large-scale WMI operation across many computers, and you want to control how many computers should be managed at a time.
Use the -ThrottleLimit
parameter on the cmdlet,
and invoke that cmdlet as a job:
$computers = Get-Content computers.txt Get-WmiObject Win32_OperatingSystem -Computer $computers -ThrottleLimit 10 -AsJob
One problem with large-scale WMI operations against many computers is that most scripts invoke them sequentially. If your script acts against 10,000 servers, it will usually process the first computer, and then retrieve the results. Next, it will process the second computer, and then retrieve its results. Since WMI operations are traditionally network-bound, your script spends the vast majority of its time simply waiting for results from remote computers.
A genesis for this feature was a sobering story we heard from one of our large customers. The customer’s scripts had to deal with so many computers that the customer would have to start a second script before the first had finished!
The solution to this quandary comes from invoking the commands in parallel. Not entirely in parallel, however, as most machines would buckle under the load of 10,000 active WMI queries. While it is possible to recognize the solution and pitfalls, actually implementing it is something different altogether. Even with the proper skill set, a job manager that supports automatic throttling is usually not high on an administrator’s list of priorities when compared to the collection of fires the administrator needs to put out.
Instead, PowerShell’s WMI cmdlets handle all of this complexity for you. For more information about PowerShell’s job support, see Invoke a Long-Running or Background Command.
You want to perform a WMI task in PowerShell, but you can find only VBScript examples that demonstrate the solution to the problem.
To accomplish the task of a script that
retrieves data from a computer, use the Get-WmiObject
cmdlet:
foreach($printer in Get-WmiObject -Computer COMPUTER
Win32_Printer)
{
## Work with the properties
$printer.Name
}
To accomplish the task of a script that calls
methods on an instance, use the [Wmi]
or [WmiSearcher]
accelerators to
retrieve the instances, and then call methods on the instances like you
would call any other PowerShell method.
$service = [Wmi] 'Win32_Service.Name="winmgmt"' $service | Invoke-WmiMethod -Name ChangeStartMode -ArgumentList "Manual" $service | Invoke-WmiMethod -Name ChangeStartMode -ArgumentList "Automatic"
To accomplish the task of a script that calls
methods on a class, use the Invoke-Wmi
Method
cmdlet, or use the [WmiClass]
accelerator to retrieve the class,
and then call methods on the class like you would call any other
PowerShell method:
Invoke-WmiMethod Win32_Process Create notepad $class = [WmiClass] "Win32_Process" $class.Create("Notepad")
For many years, VBScript has been the preferred language that administrators use to access WMI data. Because of that, the vast majority of scripts available in books and on the Internet come written in VBScript.
These scripts usually take one of three forms: retrieving data and accessing properties, calling methods of an instance, and calling methods of a class.
Although most WMI scripts on the Internet accomplish unique tasks, PowerShell supports many of the traditional WMI tasks natively. If you want to translate a WMI example to PowerShell, first check that there aren’t any PowerShell cmdlets that might accomplish the task directly.
One of the most common uses of WMI is for data collection and system inventory tasks. A typical VBScript that retrieves data looks like Example 28-3.
Example 28-3. Retrieving printer information from WMI using VBScript
strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" & strComputer & " ootcimv2") Set colInstalledPrinters = objWMIService.ExecQuery _ ("Select * from Win32_Printer") For Each objPrinter in colInstalledPrinters Wscript.Echo "Name: " & objPrinter.Name Wscript.Echo "Location: " & objPrinter.Location Wscript.Echo "Default: " & objPrinter.Default Next
The first three lines prepare a WMI
connection to a given computer and namespace. The next two lines of
code prepare a WMI query that requests all instances of a class. The
For Each
block loops over all the
instances, and the
objPrinter.
Property
statements interact with properties on those instances.
In PowerShell, the Get-WmiObject
cmdlet takes care of most of
that by retrieving all instances of a class from the computer and
namespace that you specify. The first five lines of code then
become:
$installedPrinters = Get-WmiObject Win32_Printer -ComputerName computer
If you need to specify a different computer,
namespace, or query restriction, the Get-WmiObject
cmdlets supports those through
optional parameters. If you need to specify advanced connection
options (such as authentication levels), simply specify those in the
-Impersonation
and
-Authentication
parameters to the cmdlet.
In PowerShell, the For Each
block becomes:
foreach($printer in $installedPrinters) { $printer.Name $printer.Location $printer.Default }
Notice that we spend the bulk of the PowerShell conversion of this script showing how to access properties. If you don’t actually need to work with the properties (and only want to display them for reporting purposes), PowerShell’s formatting commands simplify that even further:
Get-WmiObject Win32_Printer -ComputerName computer
| Format-List Name,Location,Default
For more information about working with the
Get-WmiObject
cmdlet, see Access Windows Management Instrumentation Data.
Although data retrieval scripts form the bulk of WMI management examples, another common task is to call methods of an instance that invoke actions.
For example, Example 28-4 changes the startup type of a service.
Example 28-4. Changing the startup type of a service from WMI using VBScript
strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" & strComputer & " ootcimv2") Set colServiceList = objWMIService.ExecQuery _ ("Select * from Win32_Service where StartMode = 'Manual'") For Each objService in colServiceList errReturnCode = objService.ChangeStartMode("Disabled") Next
The first three lines prepare a WMI
connection to a given computer and namespace. The next two lines of
code prepare a WMI query that requests all instances of a class and
adds an additional filter (StartMode =
'Manual'
) to the query. The For
Each
block loops over all the instances, and the
objService.Change(…)
statement calls the Change()
method on
the service.
In PowerShell, the Get-WmiObject
cmdlet takes care of most of
the setup by retrieving all instances of a class from the computer and
namespace that you specify. The first five lines of code then
become:
$services = Get-WmiObject Win32_Service -Filter "StartMode = 'Manual'"
If you need to specify a different computer
or namespace, the Get-WmiObject
cmdlet supports those through optional parameters. If you need to
specify advanced connection options (such as authentication levels),
simply specify those in the -Impersonation
and
-Authentication
parameters to the cmdlet.
In PowerShell, the For Each
block becomes:
foreach($service in $services) { $service.ChangeStartMode("Disabled") }
For more information about working with the
Get-WmiObject
cmdlet, see Access Windows Management Instrumentation Data.
Although less common than calling methods on an instance, it is sometimes helpful to call methods on a WMI class. PowerShell makes this work almost exactly like calling methods on an instance.
For example, a script that creates a process on a remote computer looks like this:
strComputer = "COMPUTER" Set objWMIService = GetObject _ ("winmgmts:\" & strComputer & " ootcimv2:Win32_Process") objWMIService.Create("notepad.exe")
The first three lines prepare a WMI
connection to a given computer and namespace. The final line calls the
Create()
method on
the class.
In PowerShell, the Invoke-WmiMethod cmdlet lets you easily work with methods on a class. The entire segment of code then becomes:
Invoke-WmiMethod "\COMPUTERRootCimv2:Win32_Process" Create notepad.exe
For more information about invoking methods on WMI classes, see Invoke a Method on a WMI Class.
18.118.122.244