Summary: Guest blogger, Trevor Sullivan, talks about using Windows PowerShell and CIM to manipulate information.
Microsoft Scripting Guy, Ed Wilson, is here. Today we have a guest post from Trevor Sullivan. Trevor is an Honorary Scripting Guy, and a recognized Microsoft Community Contributor (MCC). To see more of Trevor’s guest posts, see these Hey, Scripting Guy! Blog posts.
Note This is the third in a series of five posts by Trevor where he talks specifically about using the CIM cmdlets. Today’s post talks about using the CIMCmdlets PowerShell
module to manipulate information.
- Yesterday’s post, Introduction to the CIMCmdlets PowerShell Module, talked about the CIM cmdlets module in a general fashion.
- Monday’s post, What is CIM and Why Should I Use It in PowerShell?, provided a little bit of background on CIM and explained why you will want to use this exciting technology.
Take it away, Trevor…
In yesterday’s post, we introduced the CimCmdlets PowerShell module. Today, we’ll take a look at how to manipulate information by using the various commands in the module.
The commands that we’ll look at are:
- Get-CimSession
- New-CimSession
- Remove-CimSession
- Get-CimInstance
- Set-CimInstance
- Get-CimClass
WMI namespaces
The information that is stored in the Windows Management Instrumentation (WMI) is organized into namespaces. The vast majority of Windows functionality is exposed in the root\cimv2 WMI namespace, which just so happens to be the default.
Note The terms WMI and CIM are generally used interchangeably. However, in the context of Windows PowerShell, the WMI cmdlets and CIM cmdlets are two very different things.
WMI classes
Each WMI namespace contains a series of WMI classes that represent some sort of component. For example, instances of the Win32_PhysicalMemory class represent the RAM that is installed in a system, and instances of the Win32_NetworkAdapter class represent network adapters that are installed in a system.
It is important to note that the WMI classes themselves do not represent the underlying objects, but rather instances of the class do. The class definition merely defines what the object could look like. An instance of a class represents a real object.
If you’re new to WMI and CIM, you might not know all of the WMI class names that are available to you. To get a list of WMI classes in the default root\cimv2 WMI namespace, simply run:
(Get-CimClass | Sort-Object -Property CimClassName).CimClassName;
Exploring a WMI class
If we want to examine a CIM class definition (such as for a network adapter), we can use the Get-CimClass cmdlet. After you get a reference to the class definition, you can explore what sorts of properties are available. Properties are descriptors that help you understand what an object looks like. When you explore a CIM class, you will find a property called CimClassProperties that allows you to see which properties are available.
$NetworkAdapterClass = Get-CimClass -ClassName Win32_NetworkAdapter;
($NetworkAdapterClass.CimClassProperties).Name | Sort-Object;
Upon running the above script, you will see some output with a list of properties for the Win32_NetworkAdapter WMI class. Many of these properties are useful, such as:
- Speed
- ServiceName
- InterfaceIndex
- NetEnabled
- MACAddress
- Manufacturer
Retrieving WMI class instances
Now that we’ve seen how to explore the properties on a WMI class definition, you might want to view the instances of the class. We’ll use the same Win32_NetworkAdapter WMI class, as shown in the previous example. To do this, we use the Get-CimInstance cmdlet.
$NetworkAdapterList = Get-CimInstance -ClassName Win32_NetworkAdapter;
$NetworkAdapterList | Select-Object -Property Manufacturer,Speed,NetEnabled,MACAddress;
On my computer, these commands produced the following result:
Changing WMI object information
Certain properties for WMI classes can be modified directly, and then written back to WMI. There are many properties that are Read-only, however, so don’t get discouraged if you come across them. Sometimes, the underlying WMI provider simply does not implement the capability of modifying object’s properties that are exposed through CIM.
I’ve written a simple Windows PowerShell script that will help you find writable WMI properties. These properties are decorated with a WMI “qualifier,” which is simply a piece of metadata that indicates that the property can be written to.
$ClassList = Get-CimClass;
foreach ($CimClass in $ClassList) {
foreach ($CimProperty in $CimClass.CimClassProperties) {
if ($CimProperty.Qualifiers.Name -contains 'write') {
[PSCustomObject]@{
ClassName = $CimClass.CimClassName;
PropertyName = $CimProperty.Name;
Writable = $true;
};
};
};
};
After you’ve found a property that you want to change, the process of changing it looks like this:
- Retrieve the CIM instance by using Get-CimInstance, and assign to a variable.
- Change the desired property value.
- Call Set-CimInstance, and pass it in the variable.
Let’s use a Printer object as an example. The Comment property on the Win32_Printer class is directly writable. I was able to discover this by using my previous script, which enumerates all writable properties in WMI. If we assume that you have Microsoft Office installed on your computer, you should have a Microsoft XPS Document Writer. Let’s update the Comment property for that printer.
$Printer = Get-CimInstance -ClassName Win32_Printer -Filter "Name = 'Microsoft XPS Document Writer'";
$Printer.Comment = 'Hello from PowerShell!';
Set-CimInstance -InputObject $Printer;
See how easy that was? Hopefully you can find your own use cases for editing WMI objects via the CIMCmdlets PowerShell module.
CIM sessions
So far, we have only performed CIM operations against the local computer. Let’s take a look at how to create a CIM session, so that we can perform work against remote computers. To create a CIM session, we simply use the New-CimSession cmdlet:
$CimSession = New-CimSession -ComputerName sql01;
Now that we have created a CIM session, we can interact with CIM on the remote computer. Let’s get a list of printers from it:
Get-CimInstance -CimSession $CimSession -Class Win32_Printer;
When you have completed a CIM session, you can clean it up by using the Remove-CimSession cmdlet:
Remove-CimSession -CimSession $CimSession;
Well, that’s all for today, folks! Come back tomorrow to talk about invoking CIM methods by using the CIMCmdlets PowerShell module!
~Trevor
Thank you, Trevor, for taking the time to share with us. This is a useful foundation.
CIM Week will continue tomorrow when Trevor returns to talk about invoking CIM methods.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy