Windows Scheduled Task Reporting

scheduled-taskwindowswindows-server-2003windows-server-2008

We have about 12-14 Win200[3,8] servers online at a time (some VMs are transient). Most of these run some scheduled tasks. How can I get a list of all scheduled tasks running on each server and, more importantly, the domain user they are running as? We could certainly log into each server and ask, but am wondering if there's some powershell or other system to do this (or something in Active Directory?)

A nice to have would allow this to run on our Windows XP Desktops, too… Not a requirement but more of a FYI. Thanks!

Best Answer

Schtasks is your friend for this - AT is old and does not (SFAIK) comprehend tasks creates with schtasks. Unfortunately, the Win32_ScheduledTask WMI object is based on AT, otherwise it would be perfect for this.

Unfortunately, neither AT nor schtasks report on the user that the job runs as. There's probably a COM object somewhere that lets you get at that; maybe you could ask on stackoverflow?

If you want to script it you would probably do something like this:

$servers = 'server1','server2','server3'
$allTasks = @()
$servers | %{ 
    $data = schtasks /query /S $_ /fo list
    # Data looks like this:
    # <blank line> 
    # HostName:      [SERVER]
    # TaskName:      [TASK NAME]
    # Next Run Time: 12:00:00 PM, 5/9/2009
    # Status:        [BLANK or SOME ERROR]
    foreach ($line in $data){
        $blob=""|select Host, Task, Next, Status
        [void]$foreach.MoveNext(); $l = $foreach.Current.length;
        $blob.Host = $foreach.current.substring(15, $l-15)
        [void]$foreach.MoveNext(); $l = $foreach.Current.length;
        $blob.Task = $foreach.current.substring(15, $l-15)
        [void]$foreach.MoveNext(); $l = $foreach.Current.length;
        $blob.Next = $foreach.current.substring(15, $l-15)
        [void]$foreach.MoveNext(); $l = $foreach.Current.length;
        $blob.Status = $foreach.current.substring(15, $l-15)
        $allTasks += $blob
    }
}
$allTasks|format-table

This has become an evil code essay - it would be easier to use the /FO csv option to dump to a text file the use import-csv to get the data back into PS, but that way you lose the server name. So instead you get to show off a bit and do custom object creation and hacking around with the foreach enumerator. Calling MoveNext moves you to the next item in the list, so you skip the first empty line of output and then take each of the next 4 lines and make them into something useful.