Modifying a Read-Write Property Using Get-WMIObject
So what’s your favorite Windows PowerShell cmdlet? Well, if you’re a system administrator, your favorite cmdlet is probably Get-WMIObject . After all, not only is Get-WMIObject (which enables you to access WMI from Windows PowerShell) the cmdlet of choice for carrying out system administration work, but Get-WMIObject is also one of the few Windows PowerShell 1.0 cmdlets that can be used against a remote computer. What’s not to like, right?
Well, at the risk of being picky, there is onething: at first glance, it doesn’t appear as if you can use Get-WMIObject to modify the value of a read-write property. For example, take a look at this VBScript script, a script that changes the default value of the LoggingLevelproperty from 1 (on) to 0 (off):
Set objWMIService =
GetObject("winmgmts:\\atl-fs-01\root\cimv2")
As you can see, this
is pretty straightforward: we simply assign the value 0 to the
property LoggingLevel, then call the
Put_method to save the new value to the operating system.
Nothing could be simpler. Now, let’s try this
very same thing with Windows PowerShell:
$a = Get-WMIObject
Win32_WMISetting –computername atl-fs-01
If we run this
script, it will run just fine, and without generating an error
message. If we then take a peek at the value of the LoggingLevel
property we’ll see that it – uh-oh:
1
Oh, dear, that’s not
what we expected, not what we expected at all. Instead, we expected
LoggingLevel to be equal to 0. Wait; we know what’s wrong. In
Windows Powershell methods must be followed by a set of
parentheses. Let’s change our last line of code to the
following:
$a.Put_()
Now let’s re-run the
script and see what happens:
Method invocation
failed because
[System.Management.ManagementObject#root\cimv2\Win32_WMISetting]
Hmmm, according to
that error message there’s no such
thingas the Put_ method. That’s odd; after all, VBScript
doesn’t have any problem using the Put_ method. Oh, well,
apparently you can’t modify the value of a read-write property
using Windows PowerShell. Easy come, easy go. See you next
week.
Wait, don’t go; this
time we
doknow what the problem is. (Promise.) As it turns
out, you can modify the value of a read-write property using
Windows PowerShell just as easily as you can modify that value
using VBScript. In fact, here’s some Windows PowerShell code that
does just that:
$a = Get-WMIObject
Win32_WMISetting –computername atl-fs-01
So what did we do
different here? Just one thing: we called the
Putmethod rather than the
Put_method. That’s all we had to do. Just call the Put
method, and you’ll be able to change the value of LoggingLevel (or
any other read-write property) using Windows PowerShell.
Good question: why
dowe use the Put_ method in VBScript and the Put method in
Windows PowerShell? Well, without going into too much detail, when
you write a WMI script using VBScript you make use of WMI’s
scripting API. In the scripting API, the SWbemObject object uses
the Put_ method to save changes to a read-write property.
By contrast, Windows
PowerShell accesses WMI through the .NET Framework and
System.Management class. Rather than using SWbemObject, Windows
PowerShell uses the System.Management.ManagementObject class. For
better or worse, this class uses a method named Put to save changes
to a read-write property. Ideally SWbemObject and
System.Management.ManagementObject would use the same method names
but, for some reason, they don’t.
But don’t worry too
much about that. Just use Put in your Windows PowerShell scripts
(and Put_ in your VBScript scripts) and we’ll all live happily ever
after.
Set colItems = objWMIService.ExecQuery("Select * From
Win32_WMISetting")
For Each objItem in colItems
objItem.LoggingLevel = 0
objItem.Put_
Next
$a.LoggingLevel = 0
$a.Put_
doesn't contain a method named 'Put_'.
At line:1 char:8
+ $a.Put_( <<<< )
$a.LoggingLevel = 0
$a.Put()