There are a few approaches to manipulating scheduled tasks in PowerShell.
- WMI – Useful if you are only going to manipulate them via script. The tasks will not be visible in the control panel applet.
- SCHTASKS.EXE – Works ok, but has a somewhat arcane syntax, and is a text-only tool.
- Task Scheduler API -Best of both worlds, but only on Vista (not XP).
My current environment is an XP laptop, and hundreds of W2k3 and W2k8 servers. I really need to be able to hit the tasks from the control panel (don’t have PowerShell installed everywhere…but that’s in process). Since I have to use SCHTASKS.EXE , I figured I should write a PowerShell interface that makes things a bit easier.
The main thing I wanted was to get objects back. Once you’ve started using PowerShell, you realize that “everything returns objects” makes for a very powerful scripting experience. So, when you have to fall back to an external command like SCHTASKS.EXE, you really feel the pain. The approach I took was to ask SCHTASKS for a verbose output (no reason not to get all of the properties), and also to write the output as CSV. I then send the output into a file. A problem that arises when trying to get PowerShell to import the CSV is that the column headers are not very friendly (e.g. “Repeat: Until: Time”). So, before importing we need to “massage” a little bit. I simply removed spaces (leaving Pascal-cased words) and replaced colons with underscores. Another issue was that different versions of SCHTASKS.EXE would sometimes include an extra blank line in the file. Finally, I decided that I should add some methods using Add-Member to allow me to run or delete the task without having to remember the syntax.
I hope you find this script useful. If you have suggestions for improvements, or questions about how part of it works, feel free to leave a comment.
function get-tasks($server="", $taskname="",[switch]$help){ if ($help) { $msg = @" Get scheduled tasks from a remote server as objects. Optionally you may supply a substring to be found in the task names. Usage: get-tasks [Server] [substring] [-help] ex: get-tasks MACHINE1 LOGS #to get all scheduled tasks from MACHINE1 containing LOGS "@ Write-Host $msg return } $filename = [System.IO.Path]::GetTempFileName() if ($server){ schtasks /query /fo csv /s $server /v > $filename } else { schtasks /query /fo csv /v > $filename } $lines=Get-Content $filename if ($lines -is [string]){ return $null } else { if ($lines[0] -ne ''){ Set-Content -path $filename -Value ([string]$lines[0]).Replace(" ","").Replace(":","_") $start=1 } else { Set-Content -path $filename -Value ([string]$lines[1]).Replace(" ","").Replace(":","_") $start=2 } if ($lines.Count -ge $start){ Add-content -Path $filename -Value $lines[$start..(($lines.count)-1)] } $tasks=Import-Csv $filename Remove-Item $filename $retval=@() foreach ($task in $tasks){ if (($taskname -eq '') -or $task.TaskName.contains($taskname)){ $task.PSObject.TypeNames.Insert(0,"DBA_ScheduledTask") Add-Member -InputObject $task -membertype scriptmethod -Name Run -Value { schtasks.exe /RUN /TN $this.TaskName /S $this.HostName} Add-Member -InputObject $task -membertype scriptmethod -Name Delete -Value { schtasks.exe /DELETE /TN $this.TaskName /S $this.HostName} $retval += $task } } return $retval } }
Links: