Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to start a hidden process.
Microsoft Scripting Guy, Ed Wilson, is here. This morning I decided to try something a bit different. I am having a cup of English Breakfast tea, but I added strawberry leaves, blackberry leaves, marshmallow root, and a cinnamon stick. It is a nice pot of tea. Very relaxing, and just thing to help start the day.
Using the Invoke-CimMethod cmdlet
One of the nice thing about using the CIM cmdlets, is that they work with Windows Management Instrumentation (WMI). They use standard WMI classes, and so the techniques work with other versions of Windows PowerShell and with other scripting languages. For example, two WMI classes that have been around forever are Win32_Process and Win32_ProcessStartInfo. I used both of these back in the VBScript days.
Note The WMI Tasks: Processes page from MSDN shows how to accomplish this task via VBScript. The WMI team has begun to update some of these scenarios on the Windows Management Infrastructure Blog. For more information about using the Invoke-CimMethod cmdlet, see these Hey, Scripting Guy! Blog posts.
The basic syntax for the Invoke-CimMethod cmdlet is shown here:
Cmdlet | WMI class | Method from class | Arguments to method |
Invoke-CimMethod | -ClassName | -MethodName | -Arguments |
In the Start-Hidden function, the Invoke-CimMethod syntax becomes rather complex. First the easy parts:
Invoke-CimMethod -ClassName win32_process -MethodName create
Nice. Three of the four parts of the command are really easy. It is the –Arguments portion that is complex. Luckily, I have some help in adding the value for –Arguments. First, I know from looking at the Invoke-CimMethod help that –Arguments accepts a hash table. Second, I know what my three input parameters can be from looking at Create method of the Win32_Process class on MSDN. In addition, this site even has a nice VBScript script to provide some additional hints.
So then, my three input parameters are listed in the following table. It also lists the output parameter, which is the ProcessID.
Direction | Data type | Argument Name |
[in] | string | CommandLine |
[in] | string | CurrentDirectory |
[in] | Win32_ProcessStartup | ProcessStartupInformation |
[out] | uint32 | ProcessId |
Based on this information, I create the following script for my –Arguments section.
-Arguments @{
commandline = $commandline;
ProcessStartupInformation = New-CimInstance -CimClass (
Get-CimClass Win32_ProcessStartup) -Property @{ShowWindow=0} -Local;
CurrentDirectory = $null}
When I have script that works, I place the entire thing into a function, and try it out. In the command that follows, I load the function by running the script within the Windows PowerShell ISE. I then go to the immediate window and capture the returned method invocation object that contains the process ID and the error return script stored into the $rtn variable. I then use that object to check the process and to stop the process:
$rtn = Start-Hidden notepad.exe
Get-Process -id $rtn.ProcessId
Stop-Process -Id $rtn.ProcessId
The command and the output from the command are shown in the following image:
I uploaded the complete function to the Script Center Repository, and you can download it from this location: Start-Hidden function.
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