Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to start a process at random intervals.
Hey, Scripting Guy! I have a rather unusual request. I am testing a new monitoring application, and I need a script that will start processes at random intervals so I can check the effectiveness of the solution. Is this something you can help me with?
—BB
Hello BB,
Microsoft Scripting Guy, Ed Wilson, is here. This morning I am sitting on the porch, sipping a nice cup of green tea with orange flavorings in it. The tea is called Orange Cream, and it tastes exactly like the old Dreamsicles I used to eat when I was a kid. It is a different way to start the morning. I am cooling off after spending an hour in the gym. I have my Surface Pro 3 that the Scripting Wife got for me for my birthday (it was an early birthday present…I have had it for awhile now), and I am catching up with email sent to scripter@microsoft.com and Facebook. I don’t know about you, but lately, it seems like I am always multitasking. I find it hard to sit and do just one thing at a time anymore. I’m not sure if this is a good thing or a bad thing.
Picking out tools
BB, there are many ways to write a Windows PowerShell script that will generate new processes at random intervals. But when I hear this requirement, I think that I will need the following:
- Get-Random To generate random numbers. I also know that I will need to specify minimum and maximum values. I will accept the default seed.
- Start-Process To start the processes and give me a bit of control over the way they start. For testing purposes, I probably want to use a minimized window style so that it does not block other things (such as the Windows PowerShell ISE for example), and so I will still be able to see that the processes have in fact started. Obviously, I will need a way to specify the program name (and path if needed). I can do this with a variable.
- Start-Sleep To control the amount of time between the startup of the process. I will use the –seconds parameter and use the number I get back from Get-Random to control the sleeping. This also means that I will need to use numbers large enough to be minutes instead of seconds (for example, 300 for five minutes).
- Whilestatement To put the script in an infinite loop. I am only testing the script at this point, so this will work well because I am sitting here monitoring it. Later I may want to increase my minimum and maximum random values, and run the script over a twelve hour period of time. For this, I will use the For statement and control exactly how many times I want the script to execute.
Writing the script
Because I did a good job analysis, and I know pretty much all of the commands I am going to use in the script, writing the script does not take me very long at all. In fact, here is the script I wrote:
Note Using While ($true) puts the script into an infinite loop. To stop the loop, press the red square (stop button) in the Windows PowerShell ISE.
# StartProcessesAtRandomTimes.ps1
$prog = "notepad.exe"
while ($true)
{
$rnd = Get-Random -Minimum 1 -Maximum 5
Start-Sleep -Seconds $rnd
start-process -FilePath $prog -WindowStyle Minimized}
Testing the script
To test the script, I load it in the Windows PowerShell ISE, press the green triangle, and then wait for a while. Nothing appears, and nothing appears to happen. But, at least on my laptop, I see the screen flash every once in a while, and on my task bar, I see several Notepads stacked up. So I press the red square, and stop the script. Still nothing appears to have happened—at least not from looking at the Windows PowerShell ISE. Here is the screenshot:
In the interactive pane, I use Get-Process to find all the Notepad processes. As shown here, there were quite a few generated:
That is cool. Now I want to see if my randomizer is working—that is, at what time were the Notepad processes generated. That is easy enough. I use the StartTime property. It is probably best to also sort them. So I use the following script:
PS C:\> Get-Process notepad | Select StartTime | sort -Descending
The problem is that it does not sort properly. It looks like it is sorted, but I try the ascending and the descending sorts, and I see the order does not change. Dude.
I then realize that I need to expand the DateTime object (that is contained in the StartTime property) so I can specify WHAT I want to sort on. Obviously, I am interested in the TimeOfDay. So I revise my command to the following:
Get-Process notepad | select -expand StartTime | sort timeofday
Now I try it, and I see that it is working. In fact, I am getting random offsets between the process starts. This is shown here:
BB, that is all there is to using Windows PowerShell to create processes at random intervals. Process Week will continue tomorrow when I will talk about launching random processes at random times.
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