820
CHAPTER 19
M
ANAGEMENT
OBJECTS
: WMI 
AND
WS-MAN
Let’s take  a second  and examine  the type  of  object  that  was  returned from  this 
command:
PS (2) > $result.GetType().FullName 
System.Management.ManagementBaseObject
This  isn’t  an  instance  of  the 
Win32_Process
class. Instead, it’s a 
Management-
BaseObject
, which rather, like the PowerShell 
PSCustomObject
, just serves as a 
base for other object types. It has two interesting properties that give you the result of 
the operation, 
ProcessID
and 
ReturnValue
:
PS (3) > $result | Format-Table ProcessId, ReturnValue
ProcessId          ReturnValue 
---------          -----------
9376               0
If the method call was successful, then the 
ReturnValue
will be 0, indicating this 
success, and the 
ProcessID
will contain the process 
ID
or handle of the new process. 
It’s 0 here, so a new instance of the calculator applet should have appeared on the 
desktop. You can also use a 
WQL
query to confirm this:
PS (4) > $proc = Get-WmiObject -Query @" 
>> SELECT __PATH, Handle 
>> FROM Win32_PROCESS 
>> WHERE ProcessId = $($result.ProcessID) 
>> "@ 
>>
The result of this query is a 
Win32_Process
object instance representing the 
calc 
process, which you can confirm using 
Get-Member
. In this case, you’re going to limit 
the output from 
Get-Member
to include only the methods on the object:
PS (6) > $proc | Get-Member -MemberType Method
TypeName: System.Management.ManagementObject#root\cimv2\Win32 
_Process
Name           MemberType Definition 
----           ---------- ----------
AttachDebugger Method     System.Management.ManagementBaseObj... 
GetOwner       Method     System.Management.ManagementBaseObj... 
GetOwnerSid    Method     System.Management.ManagementBaseObj... 
SetPriority    Method     System.Management.ManagementBaseObj... 
Terminate      Method     System.Management.ManagementBaseObj...
In the list of methods displayed, you see the 
Terminate()
method. On a wider dis-
play, you’d see that the full signature for this method is
System.Management.ManagementBaseObject Terminate(System.UInt32 Reason)
Pdf move pages - re-order PDF pages in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Support Customizing Page Order of PDF Document in C# Project
rearrange pdf pages reader; pdf move pages
Pdf move pages - VB.NET PDF Page Move Library: re-order PDF pages in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Sort PDF Document Pages Using VB.NET Demo Code
how to change page order in pdf document; how to move pages in a pdf
T
HE
WMI 
CMDLETS
821
This is the method you need to terminate (i.e., stop) a running process. The method 
takes a single argument that encodes the reason for terminating this process. You’re 
going to pass 
0
for this value. Now let’s look at the 
__PATH
property on the object:
PS (7) > $proc | Format-List __PATH
__PATH : \\BRUCEPAYX61\root\cimv2:Win32_Process.Handle="9376"
This property allows you to target this specific object using 
Invoke-WmiMethod
’s 
-Path
parameter. Let’s run the command. You’ll use the 
__PATH
member on the object 
in 
$proc
to identify the process object you’re going to terminate, set the method name 
to be 
Terminate
using 
-Name
, and pass it the value 
0
using 
-Argument
:
PS (9) > Invoke-WmiMethod -Path $proc.__PATH ` 
>>   -Name Terminate -Argument 0 
>>
Invoke-WmiMethod : Unable to cast object of type 'System. 
Management.Automation.PSObject' to type 'System.IConvertible'. 
At line:1 char:17 
+ Invoke-WmiMethod <<<<  -Path $proc.__PATH `
+ CategoryInfo          : NotSpecified: (:) 
[Invoke-WmiMeth   od], InvalidCastException
+ FullyQualifiedErrorId : System.InvalidCastException,
Micro   soft.PowerShell.Commands.InvokeWmiMethod
And it fails! What did you do wrong? As it turns out, absolutely nothing. What you 
wrote is correct, but there’s a bug in the 
Set-WmiInstance
cmdlet that’s causing it to 
fail. You’ll encounter this bug anytime a numeric literal is passed directly as an argu-
ment to the method.
The Invoke-WmiMethod bug details
For those who are interested, here are the nitty-gritty details behind this bug. When 
the PowerShell parser encounters a command-line argument that “looks” like a 
number, it compiles that token as a number, but just in case you really wanted a 
string, it then wraps this number in a PSObject and adds the original text of the 
string as a note on this PSObject. This is done because you’re doing this at parse 
time and won’t know the actual type of the argument until runtime when you look up 
the actual command. The reason you need to preserve the original token string is 
that there were a lot of people using arguments like 0001 for filenames. PowerShell 
was taking  these tokens  and  turning  them into  numbers. The  argument 0001 
becomes 1 as a number. As a result, the file was named 1 instead of 0001. 
To fix this, you can add a wrapper that retains the original string. So why does this 
cause Invoke-WmiMethod to fail? The reason is that the cmdlet is just taking its 
arguments and passing them directly through to the WMI client layer. Because this 
layer doesn’t understand the PSObject type, it fails. By using an expression like
(1) instead of a simple number 1, you can force the runtime to pass an unwrapped 
number.
C# TIFF: How to Reorder, Rearrange & Sort TIFF Pages Using C# Code
Using this C#.NET Tiff image management library, you can easily change and move the position of any two or more Tiff file pages or make a totally new order for
reordering pdf pages; change page order in pdf reader
C# Word - Sort Word Pages Order in C#.NET
page reorganizing library control, developers can swap or adjust the order of all or several Word document pages, or just C# DLLs: Move Word Page Position.
move pages in pdf; how to rearrange pdf pages online
822
CHAPTER 19
M
ANAGEMENT
OBJECTS
: WMI 
AND
WS-MAN
To avoid this error and work around the bug, you need to use a literal expression 
instead of a simple numeric token as the argument. To do so, you just have to put 
parentheses around the number. Let’s run the command updated to do this:
PS (10) > Invoke-WmiMethod -Path $proc.__PATH ` 
>>   -Name Terminate -Argument (0) | 
>>      select -First 1 -Property '[a-z]*' 
>>
ReturnValue      : 0
Properties       : {ReturnValue}
SystemProperties : {__GENUS, __CLASS, __SUPERCLASS, __DYNASTY...
}
Qualifiers       : {} 
ClassPath        : __PARAMETERS 
Site             : 
Container        :
The return value is 0, indicating that the call was successful. At this point, the 
calc 
process will have vanished from the desktop. To confirm that the process has been 
terminated, call the 
Get-Process
cmdlet:
PS (11) > Get-Process calc 
Get-Process : Cannot find a process with the name "calc". Verify
the process name and call the cmdlet again. 
At line:1 char:12 
+ Get-Process <<<<  calc
+ CategoryInfo          : ObjectNotFound: (calc:String) 
[Ge   t-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,
Micros   oft.PowerShell.Commands.GetProcessCommand
No process with the name 
calc
was found, confirming that it has been terminated 
(assuming, of course, that there aren’t other 
calc
processes still running from earlier 
examples).
Now, let’s look at the last of the 
WMI
cmdlets, which will let you remove objects 
from the system or the 
CIM
repository.
19.2.5
The Remove-WmiObject cmdlet
The final 
WMI
cmdlet to cover is 
Remove-WmiObject
, which is shown in figure 19.7.
By now, you should have a good handle on these parameters, so let’s jump right 
into the example. You’ll start another 
calc
process, and then use a 
WQL
query to get 
the path to this process instance:
PS (1) > calc
PS (2) > $proc = Get-WmiObject -Query @" 
>> SELECT __PATH 
>> FROM Win32_PROCESS 
>> WHERE Name='calc.exe' 
>> "@ 
>>
C# PowerPoint - Sort PowerPoint Pages Order in C#.NET
library control, developers can swap or adjust the order of all or several PowerPoint document pages, or just change the C# DLLs: Move PowerPoint Page Position.
change page order in pdf reader; rearrange pdf pages reader
C# PDF File & Page Process Library SDK for C#.net, ASP.NET, MVC
RasterEdge XDoc.PDF allows you to easily move PDF document pages position, including sorting pages and swapping two pages. Copying and Pasting Pages.
reorder pages in pdf preview; how to rearrange pages in a pdf file
T
HE
WMI 
CMDLETS
823
When you have the path, you can call 
Remove-WmiObject
:
PS (3) > Remove-WmiObject -Path $proc.__PATH 
PS (4) >
This code will cause the process to be terminated, just as if you’d called the 
Termi-
nate()
method. You can also use this cmdlet to remove the environment variable 
you created earlier. First, verify that it still exists:
PS (5) > Get-WmiObject -Class Win32_Environment ` 
>>   -Filter 'Name = "TestProperty"' | 
>>     Format-List Name,VariableValue,__PATH 
>>
Name          : TestProperty 
VariableValue : Hello 
__PATH        : \\BRUCEPAYX61\root\cimv2:Win32_Environment.Name=
"TestProperty",UserName="<SYSTEM>"
To remove this variable, pipe the output of 
Get-WmiObject
into the 
Remove-Wmi-
Object
cmdlet:
PS (6) > Get-WmiObject -Class Win32_Environment ` 
>>   -Filter 'Name = "TestProperty"' | 
>>     Remove-WmiObject 
>>
And finally, verify that it’s been removed:
PS (7) > Get-WmiObject -Class Win32_Environment ` 
>>  -Filter 'Name = "TestProperty"' | 
>>    Format-List Name,VariableValue,__PATH 
>>
PS (8) >
Nothing is returned from the query, confirming that the variable has been removed.
This covers all of the cmdlets that PowerShell includes for working with 
WMI
but there’s one more thing to cover: the 
WMI
object adapter and the 
WMI
type
Remove-WmiObject 
[-Namespace <string>] 
[-Class] <string>
[-InputObject] <managementObject>
[-Path] <string>
Specify target object by class, by
path, or by reading from pipeline
Select target object
using its class name 
Get target object
from pipeline
Select target object using
path that includes key 
property specification
Namespace of class
(
defaults to root\cimv2) 
Figure 19.7 The 
Remove-WmiObject
cmdlet allows you to remove objects from the 
system using WMI.
C# PDF insert text Library: insert text into PDF content in C#.net
int pageIndex = 0; // Move cursor to (400F, 100F). String outputFilePath = Program.RootPath + "\\" output.pdf"; doc.Save(outputFilePath);
move pdf pages; move pdf pages in preview
VB.NET PDF insert text library: insert text into PDF content in vb
Dim pageIndex As Integer = 0 ' Move cursor to (400F, 100F). Dim outputFilePath As String = Program.RootPath + "\\" output.pdf" doc.Save(outputFilePath).
how to reorder pages in pdf preview; change page order pdf
824
CHAPTER 19
M
ANAGEMENT
OBJECTS
: WMI 
AND
WS-MAN
shortcuts, which we’ll look at next. These mechanisms make it easier to work with 
WMI
from PowerShell.
19.3
T
HE
WMI 
OBJECT
ADAPTER
Let’s take a closer look at the objects returned from the 
WMI
cmdlets. Once again, we’ll 
look at the 
Win32_Process
class for this investigation and an instance of the calculator 
applet. You start the program and then get the 
Win32_Process
object for that process:
PS (1) > calc
PS (2) > $g=Get-WmiObject Win32_process ` 
>> -filter 'Name = "calc.exe"' 
>>
Use 
Get-Member
to examine the methods and properties on the object that was 
returned:
PS (3) > $g |gm -membertype "Method,Property"
TypeName: System.Management.ManagementObject#root\cimv2\Win32_Process
Name                       MemberType Definition 
----                       ---------- ----------
AttachDebugger             Method     System.Management.... 
GetOwner                   Method     System.Management.... 
GetOwnerSid                Method     System.Management.... 
SetPriority                Method     System.Management.... 
Terminate                  Method     System.Management.... 
__CLASS                    Property   System.String __CL... 
__DERIVATION               Property   System.String[] __... 
__DYNASTY                  Property   System.String __DY... 
__GENUS                    Property   System.Int32 __GEN... 
__NAMESPACE                Property   System.String __NA... 
__PATH                     Property   System.String __PA... 
__PROPERTY_COUNT           Property   System.Int32 __PRO... 
__RELPATH                  Property   System.String __RE...
What you see here are the adapted 
WMI
methods for that process object, not the 
methods and  properties on the .
NET
type 
System.Management.ManagementOb-
ject
. To get at the method of the base .
NET
object, you need to use the 
PSBase 
property. From chapter 11 (section 11.6.2), you know that 
PSBase
is the way to 
bypass the type adapter and get at the native capabilities of an object. Let’s see what 
this gives you:
PS (7) > $g.PSBase | Get-Member -MemberType Method
TypeName: System.Management.Automation.PSMemberSet
Name                      MemberType Definition 
----                      ---------- ----------
add_Disposed              Method     System.Void add_Dis... 
Clone                     Method     System.Object Clone() 
CompareTo                 Method     System.Boolean Comp...
C# PDF Image Extract Library: Select, copy, paste PDF images in C#
Get image information, such as its location, zonal information, metadata, and so on. Able to edit, add, delete, move, and output PDF document image.
rearrange pdf pages online; reverse page order pdf
VB.NET PDF Library SDK to view, edit, convert, process PDF file
Rapidly and multiple PDF document (pages) creation and edit methods file formats; merge, append, and split PDF files; insert, delete, move, rotate, copy
reorder pdf pages online; reordering pages in pdf document
T
HE
WMI 
OBJECT
ADAPTER
825
CopyTo                    Method     System.Management.M... 
CreateObjRef              Method     System.Runtime.Remo... 
Delete                    Method     System.Void Delete(... 
Dispose                   Method     System.Void Dispose() 
Equals                    Method     System.Boolean Equa... 
Get                       Method     System.Void Get(), ... 
get_ClassPath             Method     System.Management.M...
Notice the 
Delete()
method that the base object exposes. This is what 
Remove-
WmiObject
calls in order to delete an object instance. Also notice in the earlier output 
that there was  no 
Delete()
method on the adapted object. This is because the 
Delete operation is supported by the infrastructure rather than a specific class. This 
illustrates  why  you may occasionally have to use  the  raw  object—sometimes  the 
adapted type hides something that you need.
Another feature that makes it easy to use 
WMI
from PowerShell is the 
WMI
short-
cuts, which we’ll explore in the next section.
19.3.1
The WMI type accelerators
PowerShell provides three type aliases or accelerators for working with 
WMI
[WMI]
[WMICLASS]
, and 
[WMISEARCHER]
. Let’s look at each of these accelerated types.
The [WMISEARCHER] type accelerator
The 
[WMISEARCHER]
alias is a type accelerator for
[System.Management.ManagementObjectSearcher]
This type accelerator allows the user to directly cast a string containing a 
WQL
query 
into a searcher object. Once you have this searcher object, you just have to call its 
GET()
method to retrieve the corresponding data:
PS (1) > $qs = 'Select * from Win32_Process ' + 
>> 'where Handlecount > 1000' 
>>
PS (2) > $s = [WmiSearcher] $qs 
PS (3) > $s.Get() | sort handlecount | 
>> fl handlecount,__path,name 
>>
handlecount : 1124 
__PATH      : \\BRUCEPAY64H\root\cimv2:Win32_Process.Handle
="3144" 
name        : iexplore.exe
handlecount : 1341 
__PATH      : \\BRUCEPAY64H\root\cimv2:Win32_Process.Handle
="3380" 
name        : OUTLOOK.EXE
handlecount : 1487 
__PATH      : \\BRUCEPAY64H\root\cimv2:Win32_Process.Handle
="2460" 
name        : powershell.exe
826
CHAPTER 19
M
ANAGEMENT
OBJECTS
: WMI 
AND
WS-MAN
handlecount : 1946 
__PATH      : \\BRUCEPAY64H\root\cimv2:Win32_Process.Handle
="988" 
name        : svchost.exe
The [WMI] type accelerator
The 
[WMI]
alias is a type accelerator or shortcut for the type
[System.Management.ManagementObject]
which, as you know from our earlier experiments, is how .
NET
wraps a 
WMI
object 
instance.
You can use this accelerator to cast a string containing a 
WMI
instance path (see 
section 19.2) into the corresponding 
WMI
object instance. You’ll use this accelerator 
in an example where you use the calculator app again. Let’s start the target process:
PS (1) > calc
Then, create a 
WmiSearcher
instance, which you’ll use to get the process object’s 
WMI
path:
PS (2) > $s = [WmiSearcher] ` 
>> 'Select * from Win32_Process where Name = "calc.exe"' 
>>
You’ll call 
Get()
on the searcher instance to retrieve the object, but you’re going to 
need a trick to get the actual object. This is because the output of the call to 
Get()
is 
always a collection, even if the query matched only a single object. To complicate 
matters, this collection can’t be indexed, like an array. Instead it’s an enumeration, so 
to get at the objects in the collection, you need to enumerate that collection. Fortu-
nately, PowerShell enumerates by default, making this process easy to do: just use the 
collection as input to a pipeline. To do so with no additional processing, you pipe 
into the 
Write-Output
cmdlet and it will stream the enumeration.
NOTE
The approach just described is probably the only real practical 
use for 
Write-Output
. It’s the easiest way to transform an enumeration 
into a collection that can be indexed with no additional processing. 
Another pedagogical application for some people is to use the cmdlet to 
make explicit the fact that output is being done. They use the command 
Write-Output $foo
instead of simply 
$foo
to make the write opera-
tion explicit. This approach is largely a matter of personal preference.
Let’s stream the enumeration to get our target object:
PS (3) > $proc = $s.Get() | Write-Output
When you have the object, you can get the path to the object using the 
_PATH
prop-
erty as you saw earlier:
PS (4) > $proc = [WMI] $so.__PATH
T
HE
WMI 
OBJECT
ADAPTER
827
This code yields an instance of the process object. Now that you have this instance, 
you can examine the process’s properties:
PS (4) > $proc.Name 
calc.exe 
PS (5) > $proc.HandleCount 
49
You can update properties (which we won’t show here) and you can call methods. For 
example, you can terminate the process by calling the 
Terminate()
method:
PS (6) > $proc.Terminate()
__GENUS          : 2 
__CLASS          : __PARAMETERS 
__SUPERCLASS     : 
__DYNASTY        : __PARAMETERS 
__RELPATH        : 
__PROPERTY_COUNT : 1 
__DERIVATION     : {} 
__SERVER         : 
__NAMESPACE      : 
__PATH           : 
ReturnValue      : 0
This code performs the same operation as when you called the 
Terminate()
method 
using 
Invoke-WmiMethod
.
Whereas the 
[WMI]
accelerator allows you to cast a path to an instance, the 
[WMI-
CLASS]
accelerator casts a path into a class, as you’ll see next.
The [WMICLASS] type accelerator
The 
[WMICLASS]
alias is a type accelerator for the
[System.Management.ManagementClass]
class. This accelerator can be used to cast a 
WMI
class path into a 
WMI
class object as 
follows:
PS (7) > $c = [WMICLASS]"Win32_Process"
When you use 
Get-Member
to look at the methods on this class
PS (8) > $c | Get-Member -MemberType method | Format-List
TypeName   : System.Management.ManagementClass#ROOT\cimv2\Win32_
Process
Name       : Create 
MemberType : Method 
Definition : System.Management.ManagementBaseObject Create(Syste
m.String CommandLine, System.String CurrentDirector
y, System.Management.ManagementObject#Win32_Process
Startup ProcessStartupInformation)
828
CHAPTER 19
M
ANAGEMENT
OBJECTS
: WMI 
AND
WS-MAN
you see that there’s one method, 
Create()
, for creating processes. Let’s use it to start 
a Notepad process:
PS (9) > $c.Create("notepad.exe") | 
>>   Format-Table ReturnValue, ProcessId 
>>
ReturnValue                       ProcessId
-----------                       ---------
                           8588
Verify the process creation with 
Get-WmiObject
:
PS (10) > Get-WmiObject Win32_Process ` 
>>   -Filter 'Name = "notepad.exe"' | 
>>     Format-Table Name, Handle 
>>
Name                             Handle 
----                             ------
notepad.exe                      8588
This mimics what you did with the 
Create()
method and 
Invoke-WmiMethod
.
There’s still one more detail about the 
WMI
object adapter that we need to cover 
in the last part of this section: writing data to the repository.
19.3.2
Putting modified WMI objects back
We need to cover one last, very important topic about using the 
WMI
type accelera-
tors. So far, we’ve looked at getting data, and we’ve looked at calling methods. Now, 
let’s look at putting data back. In other words, how do you go about saving changes 
you’ve made to a 
WMI
object back to the repository? 
Why is this even a topic, you ask? After all, you don’t have to do this with any of 
the other object types, right? The reason is that because the underlying store for a 
WMI
object may be on a remote computer, incrementally flushing a set of changes 
over a remote connection is too inefficient to use on a large scale. As a consequence, 
the PowerShell 
WMI
object adapter has a 
Put()
method that must be called before 
property changes made to the local copy of an object are reflected back to the under-
lying store. Let’s look at an example to see how this works. In this example, you’re 
going to use 
WMI
to change the volume name of the C: drive. First, get the 
WMI 
object for the logical 
C
: drive:
PS (9) > $disks = Get-WmiObject Win32_LogicalDisk
On this system, the 
C
: drive is the first logical disk:
PS (10) > $disks[0]
DeviceID     : C:
DriveType    : 3 
ProviderName : 
FreeSpace    : 95329701888
T
HE
WMI 
OBJECT
ADAPTER
829
Size         : 241447768064
VolumeName   : C_Drive
It currently has the boring name of 
C_Drive
. Let’s give it a rather more dramatic name:
PS (11) > $disks[0].VolumeName = "PowerShellRocks"
Verify that the property in the object has been changed:
PS (12) > $disks[0]
DeviceID     : C:
DriveType    : 3 
ProviderName : 
FreeSpace    : 95329701888 
Size         : 241447768064 
VolumeName   : PowerShellRocks
And it has. But has this information been updated in the system yet? You can check 
on this by querying the repository again, thereby getting a new instance, independent 
of the one you modified:
PS (13) > (Get-WmiObject Win32_LogicalDisk)[0]
DeviceID     : C:
DriveType    : 3 
ProviderName : 
FreeSpace    : 95329603584 
Size         : 241447768064 
VolumeName   : C_Drive
As you can see, the underlying system object hasn’t been updated. The change so far 
applies only to the object you modified. Now call the 
Put()
method on the object to 
flush the changes back to the system:
PS (14) >  $result = $disks[0].Put()
Notice that you’ve saved the result of the 
Put()
call. We’ll get to that in a second. 
First, let’s make sure that the system was properly updated:
PS (15) > (Get-WmiObject WIN32_LogicalDisk)[0]
DeviceID     : C:
DriveType    : 3 
ProviderName : 
FreeSpace    : 95329579008 
Size         : 241447768064 
VolumeName   : PowerShellRocks
This time you see that the system has been updated. Next, let’s look at what you got 
back from the 
Put()
call. Let’s look at the type first:
PS (16) > $result.GetType().FullName 
System.Management.ManagementPath 
PS (17) > "$result" 
\\localhost\root\cimv2:Win32_LogicalDisk.DeviceID="C:"
Documents you may be interested
Documents you may be interested