Windows Scheduled Tasks inventory


posted by tao.yang
05-28-2009

Downloads: 936
File size: 6.9kB
Views: 7,190

Embed
Windows Scheduled Tasks inventory
  1. #=========================================================================================== 
  2. # AUTHOR:  Tao Yang  
  3. # DATE:    2nd April 2009 
  4. # Version: 1.0 
  5. # COMMENT: Windows server scheduled jobs inventory for specific OU in a domain 
  6. #=========================================================================================== 
  7.  
  8. $erroractionpreference = "SilentlyContinue" 
  9.  
  10. function GetServersFromOU([string]$strDomainName, [array]$arrOUs
  11.     $arrDCs = $strDomainName.split("."
  12.     $strFullDC = $null 
  13.     foreach ($DC in $arrDCs
  14.     
  15.         if ($strFullDC -eq $null
  16.         
  17.             $strFullDC = "DC=$DC" 
  18.         
  19.         else 
  20.         
  21.             $strFullDC = "$strFullDC,DC=$DC" 
  22.         
  23.                          
  24.     
  25.              
  26.     $arrComputers = @( ) 
  27.     foreach ($Ou in $arrOUs
  28.     
  29.         $strFilter = "computer" 
  30.                                          
  31.         $objDomain = New-Object System.DirectoryServices.DirectoryEntry 
  32.                                          
  33.         $objSearcher = New-Object System.DirectoryServices.DirectorySearcher 
  34.         $objSearcher.SearchRoot = "LDAP://OU=$OU,$strFullDC" 
  35.         $objSearcher.SearchScope = "subtree"  
  36.         $objSearcher.PageSize = 3000 
  37.                                          
  38.         $objSearcher.Filter = "(objectCategory=$strFilter)" 
  39.         $colResults = $objSearcher.FindAll() 
  40.                      
  41.                          
  42.         foreach ($i in $colResults
  43.         
  44.             $objComputer = $i.GetDirectoryEntry() 
  45.             $arrComputers += $objComputer.Name 
  46.         
  47.     
  48.         $arrcomputers = $arrcomputers | Sort-Object 
  49.     return $arrComputers 
  50.  
  51. function CheckComputerConnectivity($computer
  52.     $bPing = $false 
  53.     $bShare = $false 
  54.     $result = $false 
  55.     #Firstly check if the computer can be pinged. 
  56.     "checking $computer" 
  57.     $ping = New-Object Net.NetworkInformation.Ping 
  58.     $PingResult = $ping.send($computer
  59.     if ($PingResult.Status.Tostring().ToLower() -eq "success"
  60.     
  61.         $bPing = $true 
  62.         #Secondly check if can browse to the scheduled task share 
  63.         $path = "\\$computer\admin`$\tasks" 
  64.         $ShareErr = $null 
  65.         $ShareResult = Get-ChildItem $path -ErrorVariable ShareErr 
  66.         if ($ShareErr.count -eq 0) { $bShare = $true
  67.                          
  68.     
  69.     if ($bPing -eq $true -and $bShare -eq $true
  70.     { $result = $true
  71.     return $result 
  72.      
  73.  
  74.  
  75. $thisScript = Split-Path $myInvocation.MyCommand.Path -Leaf 
  76. $scriptRoot = Split-Path(Resolve-Path $myInvocation.MyCommand.Path
  77. $OutPutCSVFile = Join-Path $scriptRoot "SchTasks.csv" 
  78. $strSMTP = "<smtp.yourdomain.com>" 
  79.  
  80. $strDomain = "<yourdomain.com>" 
  81. $arrOUs = @( ) 
  82. $arrOus += "OU1" 
  83. $arrOus += "OU2" 
  84.  
  85. $arrComputers = GetServersFromOU $strDomain $arrOUs 
  86.  
  87. $arrSchTasksAttributes = @( ) 
  88.  
  89. $arrSchTasksAttributes += "HostName" 
  90. $arrSchTasksAttributes += "TaskName" 
  91. $arrSchTasksAttributes += "Next Run Time" 
  92. $arrSchTasksAttributes += "Status" 
  93. $arrSchTasksAttributes += "Logon Mode" 
  94. $arrSchTasksAttributes += "Last Run Time" 
  95. $arrSchTasksAttributes += "Last Result" 
  96. $arrSchTasksAttributes += "Creator" 
  97. $arrSchTasksAttributes += "Schedule" 
  98. $arrSchTasksAttributes += "Task To Run" 
  99. $arrSchTasksAttributes += "Start In" 
  100. $arrSchTasksAttributes += "Comment" 
  101. $arrSchTasksAttributes += "Scheduled Task State" 
  102. $arrSchTasksAttributes += "Scheduled Type" 
  103. $arrSchTasksAttributes += "Start Time" 
  104. $arrSchTasksAttributes += "Start Date" 
  105. $arrSchTasksAttributes += "End Date" 
  106. $arrSchTasksAttributes += "Days" 
  107. $arrSchTasksAttributes += "Months" 
  108. $arrSchTasksAttributes += "Run As User" 
  109. $arrSchTasksAttributes += "Delete Task If Not Rescheduled" 
  110. $arrSchTasksAttributes += "Stop Task If Runs X Hours and X Mins" 
  111. $arrSchTasksAttributes += "Repeat: Every" 
  112. $arrSchTasksAttributes += "Repeat: Until: Time" 
  113. $arrSchTasksAttributes += "Repeat: Until: Duration" 
  114. $arrSchTasksAttributes += "Repeat: Stop If Still Running" 
  115. $arrSchTasksAttributes += "Idle Time" 
  116. $arrSchTasksAttributes += "Power Management" 
  117.  
  118. $arrObjTasks = @() 
  119. foreach ($computer in $arrComputers
  120.     "Auditing $computer" 
  121.     $IsComputerAccessible = CheckComputerConnectivity $computer 
  122.     "$IsComputerAccessible" 
  123.     if ($IsComputerAccessible -eq $true
  124.     
  125.         "Successfully connected to $computer" 
  126.         $arrtasks = @( ) 
  127.         $arrtasks = schtasks /query /S $computer /fo csv /nh /
  128.         $arrtasksTemp = @( ) 
  129.         #whe description contains multiple lines, the schtasks command returns multiple lines as well. 
  130.         #We need to combine them into one line. 
  131.         #remove the spaces and empty lines 
  132.         $arrtasks | foreach-object { $_=$_.trimEnd(); $_=$_.trimstart() ; if ($_.length -ne 0) { $arrtasksTemp += $_ } } 
  133.         $arrtasks = $arrtasksTemp 
  134.         $arrtasksTemp = @( ) 
  135.         $strTemp = $null 
  136.         #join the muti-line description field into one line 
  137.         for ($i = 0; $i -le ($arrtasks.count -1); $i++
  138.         
  139.             # for a string starts and ends with the quotation mark, it is OK 
  140.             if ( $arrtasks[$i].substring(0, 1) -eq '"' -and $arrtasks[$i].substring($arrtasks[$i].length-1,1) -eq '"'
  141.                 
  142.                     $arrtaskstemp += $arrtasks[$i
  143.                 
  144.                 elseif ( $arrtasks[$i].substring(0, 1) -eq '"' -and $arrtasks[$i].substring($arrtasks[$i].length-1,1) -ne '"'
  145.                     
  146.                         $strTemp = $arrtasks[$i
  147.  
  148.                     
  149.                     elseif ( $arrtasks[$i].substring(0, 1) -ne '"' -and $arrtasks[$i].substring($arrtasks[$i].length-1,1) -ne '"'
  150.                         
  151.                             $strTemp = $strTemp + " " + $arrTasks[$i
  152.                         
  153.                         elseif ( $arrtasks[$i].substring(0, 1) -ne '"' -and $arrtasks[$i].substring($arrtasks[$i].length-1,1) -eq '"'
  154.                             
  155.                                 $strTemp = $strTemp + " " + $arrTasks[$i
  156.                                 $arrtaskstemp += $strTemp 
  157.                                 $strTemp = $null 
  158.                                                                  
  159.                             
  160.                         
  161.                         $arrtasks = $arrtaskstemp 
  162.                         $arrtasksTemp = @() 
  163.          
  164.          
  165.         foreach ($task in $arrtasks
  166.         
  167.             $task = $task -replace ('","', "^"
  168.             #Remove the first character, which is a quotation mark 
  169.             if ( $task.substring(0, 1) -eq '"' ) {$task = $task.substring(1,$task.length-1)} 
  170.                 #Remove the last character, which is a quotation mark 
  171.                 if ( $task.substring($task.length-1, 1) -eq '"' ) {$task = $task.substring(0,$task.length-1)} 
  172.                     $objtasks = $null 
  173.                     $objtasks = New-Object psobject 
  174.                     $arrtaskvalues = @( ) 
  175.                     $arrtaskvalues = $task.split("^"
  176.                     for ($i = 0; $i -le ($arrtaskvalues.count -1); $i++
  177.                     
  178.                         Add-Member -inp $objTasks -membertype noteproperty -name $arrSchTasksAttributes[$i] -value $arrtaskvalues[$i]                                                 
  179.                     
  180.                     $arrObjTasks += $objTasks 
  181.         
  182.     
  183.              
  184.         $arrObjTasks | Select-Object * | Export-Csv -notypeinformation $OutPutCSVFile 
  185.                  
  186. #email the output csv file 
  187.         $date = ((Get-Date).dateTime).tostring() 
  188.         $strSubject = "PMPLIMITED Domain Server Scheduled Tasks Audit Report - $date"     
  189.         $strBody = "report attached." 
  190.      
  191.         $MailMessage = New-Object System.Net.Mail.MailMessage 
  192.         $SMTPClient = New-Object System.Net.Mail.smtpClient 
  193.         $SMTPClient.host = $strSMTP 
  194.         $Recipient = New-Object System.Net.Mail.MailAddress("Recipient@yourdomain.com", "Recipient"
  195.         $Sender = New-Object System.Net.Mail.MailAddress("Sender@yourdomain.com", "Sender"
  196.         $MailMessage.Sender = $Sender 
  197.         $MailMessage.From = $Sender 
  198.         $MailMessage.Subject = $strSubject 
  199.         $MailMessage.To.add($Recipient
  200.         $MailMessage.Body = $strBody 
  201.         $MailMessage.attachments.add($OutPutCSVFile
  202.         $SMTPClient.Send($MailMessage

As you may know, there are 2 APIs to manage scheduled tasks in Windows: schtasks (used by normal GUI interface) and wmi class win32_scheduledjob.

These 2 APIs do not work well with each other. Win32_ScheduledJob class can not access the jobs created by schtasks and jobs created via Win32_ScheduledJob class only have a very limited number of properties. Additional, schtasks cannot modify the jobs created by Win32_ScheduledJob class.

Because of this limitation in the WMI class Win32_ScheduledJob, I was unable to collect Scheduled jobs data in SMS 2003. Therefore I've written a powershell script to connect to every server in a given OU in the given domain and use schtasks to inventory the scheduled jobs on each machine.

The report is in CSV file and the script also email out the report. At work, I've scheduled this to run on a weekly basis. this is particularly helpful when you need to update service accounts and troubleshoot account lockout issues.

Before you run it, please make sure you update the script with your domain, OU, SMTP server, sender, recipient info. and the account you use to run it must have admin access to all the servers....

Cheers

Tao

Comments

marelly wrote re: Windows Scheduled Tasks inventory
on 08-31-2010 1:58 PM

Hello

Wonder if you can help

I get the following error when running the script on my SCOM2007 RMS server

"Auditing

checking  False"

IOU name PROD and DEV to replace OU1 and OU2 in

$arrOus += "prod"

$arrOus += "dev"

the 2 OUs are in domain name mjq.local.

Thank you

tao.yang wrote re: Windows Scheduled Tasks inventory
on 09-15-2010 9:30 PM

Did you also specify the domain name? are these OUs on top level?

rpertusio wrote re: Windows Scheduled Tasks inventory
on 02-18-2011 2:55 PM

I had the same error as marelly. When replacing the domain name for the script, be sure to remove the "less than" and "greater than" symbols around the domain.

For instance   <YourDomain.com>  should be replaced entirely, Symbols < > and all.

- rp

jpreece wrote re: Windows Scheduled Tasks inventory
on 03-22-2011 4:14 PM

How would you modify the OUs if they are not top level OUs?  Right now, I have

$arrOUs = @( )  

$arrOus += computers  

#$arrOus += "OU2"

but this still gives me a:

Auditing

checking failed

jpreece wrote re: Windows Scheduled Tasks inventory
on 03-22-2011 4:15 PM

sorry the last line should say: checking false

wboaz wrote re: Windows Scheduled Tasks inventory
on 03-23-2011 3:59 PM

Enter sub OUs in the format:

Production Servers,OU=Servers

The leading OU isn't required as the script prepends it on line 35. You could change that part of the script to remove the OU if you use Containers (CN=).

Kamgan wrote re: Windows Scheduled Tasks inventory
on 03-24-2011 12:44 PM

I have been able to get this script working on an XP machine and it connects to servers in our domain and creates report for only some of them.  My real need is to get this working on Vista against Vista macines in our domain.  It runs, but never produces the report.  Well, produces the report, but it is empty.  I put some test tasks out there and see that the displays says true on these boxes, but never writes them to the report.  Can anyone HELP PLEASE.  

Also, is the $path = "\\$computer\admin`$\tasks"  

now this for Vista $path = "\\$computer\c$\Windows\System32\tasks"  

Any help would be greatly appreciated!!!

dok1128 wrote re: Windows Scheduled Tasks inventory
on 06-22-2011 7:13 PM

How would I enter the OU if i want to query the 3rd level OU (F/P server under Oklahoma)? My OU structure is below:

mydomain.com

New Member Servers_US

  Oklahoma

     File and Print Servers

Concentrated Tech NSoftware Dell Compellent Sponsored by Idera and Concentrated Tech and NSoftware and Dell Compellent
Copyright 2011 PowerShell.com. All rights reserved.