Summary: Microsoft Scripting Guy, Ed Wilson, continues his discussion about Windows PowerShell scheduled jobs.
Microsoft Scripting Guy, Ed Wilson, is here. Last night was the Expo floor meet-and-greet at TechEd in Houston. It was a crazy time, and we had literally thousands of people stopping by to say "hi," and to meet up with other Windows PowerShell peeps. It was an awesome opportunity to hang out with so many people who are interested in using Windows PowerShell. The cool thing is that many people had already read yesterday’s post about Windows PowerShell scheduled jobs, and several had questions. So I dashed back to my hotel room last night and went to work on today’s post.
Note This is the second in a series of posts about the Windows PowerShell scheduled jobs feature. You should read the first post, Introduction to PowerShell Scheduled Jobs, before you read today’s post.
Yesterday I created a Windows PowerShell scheduled job with a time trigger, and it ran successfully. Then, I shut down my laptop. Now, we are back at the hotel, I power up my laptop, and guess what? When I use the Get-ScheduledJob cmdlet, I see that the Windows PowerShell scheduled jobs still exist. They are shown here:
Note To use any of the *job cmdlets (for example, Get-Job or Receive-Job), the PSScheduledJob module must load into the current session. This happens when you use a cmdlet such as Get-ScheduledJob. You can also specifically import the module by using Import-Module PSScheduledJob.
I can also check to see if the job completed and if there is any data left. To do this, I use the Get-Job cmdlet. I can then use the name or the job ID. The easiest thing to do is to give the job a decent name, and use the name. This is because the job ID from Get-ScheduledJob and the job ID from Get-Job are different numbers. When I get the job, I pipe it to the Format-List cmdlet as shown here:
One thing that I like to do is see how long the scheduled job takes to run. This is useful to help to develop some sort of a track record for comparison. I can use the New-TimeSpan cmdlet and select the PSBeginTime and the PSEndTime properties to obtain this information. Here is the command I use:
New-TimeSpan -Start (get-job -name gps).psbegintime -End (get-job -name gps).psendtime
The command returns a TimeSpan object. I generally simply return the entire object because, at times, I do not know how long the job runs. Pay really close attention when reading the object because the first portion contains the number of days, hours, minutes, seconds, and milliseconds the job takes to complete. I have to add these parts together to get a total time. Or I can go to the Total* section. For example, this job took a total of 2.2812358 seconds.
Days : 0
Hours : 0
Minutes : 0
Seconds : 2
Milliseconds : 281
Ticks : 22812358
TotalDays : 2.64031921296296E-05
TotalHours : 0.000633676611111111
TotalMinutes : 0.0380205966666667
TotalSeconds : 2.2812358
TotalMilliseconds : 2281.2358
Even though I rebooted my computer, I can still look at the job results. This is because I used the –Keep parameter when viewing the results. This is shown here:
One of the cool things I can do is run the job directly. This is useful, for example, when I have a scheduled job that was set up to run on a schedule, and I want an impromptu run. A classic illustration of this situation is when I have a scheduled backup that runs each morning, but I have made a significant number of changes to a system (or I am getting ready to make a significant number of changes), and I would like to run an impromptu backup without modifying my regularly scheduled backup.
To run a scheduled job as a one-off, all I need to do is to use the Start-Job cmdlet and specify the name of the job as shown here:
PS C:\> Start-Job -DefinitionName gps
Id Name PSJobTypeName State HasMoreData Location
-- ---- ------------- ----- ----------- --------
5 GPS PSScheduledJob Running True localhost
Deleting stuff
To remove job triggers, I can use the Remove-JobTrigger cmdlet. One way to do this is to remove the job trigger by the name of the trigger itself. To find this, I can use the Get-ScheduledJob cmdlet and pipe the results to Get-JobTrigger. I can also use the ID of the trigger, or I can pipe a scheduled job definition object to the cmdlet. Here are a couple of examples:
Remove-JobTrigger -Id 1
Get-ScheduledJob | Get-JobTrigger
Keep in mind that the input object is a ScheduledJobDefinition object that comes from Get-ScheduledJob, and not a ScheduledJobTrigger object. Therefore, the following command fails:
To delete Windows PowerShell scheduled jobs, you use the Unregister-ScheduledJob cmdlet.
Note It is a bit confusing that the PSScheduledJob module uses Register-ScheduledJob and Unregister-ScheduledJob instead of the New and Remove verbs. But with scheduled jobs, you are actually registering and unregistering, so the verbs make sense from a technical perspective.
If I want to delete all of my Windows PowerShell scheduled jobs, I use the following command:
Get-ScheduledJob | Unregister-ScheduledJob
There you have more info about using Windows PowerShell scheduled jobs. Scheduled Jobs Week will continue tomorrow when I will talk about more cool stuff.
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