List Scheduled Tasks for Remote Servers

Recently, I was asked to find out of a certain service account was being used in scheduled tasks on any server. Being a PowerShell guy, I turned to the Get-ScheduledTask cmdlet. I tried querying a list of scheduled tasks by Author.

I created a variable $VMs and used it to filter any Powered on Windows VM. I then checked each of these VMs for a scheduled task with the author of svc.tasks. I found no server with an author of this user.

$VMs = Get-VM | Where {$_.PowerState -eq "PoweredOn" -AND $_.Guest -match "Win"}
foreach ($VM in $VMs) {
Get-ScheduledTask -Cimsession $VM.Name | Where {$_.Author -match "svc.tasks"}
}

However, what I found later was, AUTHOR and the RUNAS User were two different things and that Get-ScheduledTask didn’t output the UserID field, which was running the service.

I then did some searching and found a post on superuser.com that used Active Directory to query. I figured this was easier than querying powered on and Windows VMs, since AD was made up mostly of Windows machines. This is the script I ended up modifying and using. Instead of searching for a specific UserID, I exported all of them, figuring it may be handy to see what other service accounts are being used.

# Import the ActiveDirectory Module. If it isn't installed, Install it.
     if (Get-Module -ListAvailable -Name ActiveDirectory) {
         Write-Host "ActiveDirectory Module exists"
     } 
          else {
         Write-Host "Installing ActiveDirectory Module"
	     Install-Module ActiveDirectory 
     }

# Get a list of all Servers in AD
     $list = (Get-ADComputer -LDAPFilter "(&(objectcategory=computer)(OperatingSystem=*server*))").Name

# List how many servers were found
     Write-Verbose -Message "Trying to query $($List.count) Servers found in AD"

# List where log will be written
     $logfilepath = "C:\ben\tasks_log.csv"

# Find tasks listed in the c:\windows\system32\tasks folder and export the Computername, Service, and UserID
	foreach ($Computername in $List) {
		$path = "\\" + $computername + "\c$\windows\system32\tasks"
		$tasks = Get-ChildItem -Path $path -File
		if ($tasks)
		{
			Write-Verbose -Message "I found $($tasks.count) tasks for $computername"
		}
		foreach ($item in $tasks)
		{
			$Absolutepath = $path + "\" + $item.Name
			$task = [xml] (Get-Content $Absolutepath)
			[STRING]$check = $task.Task.Principals.Principal.UserID
			if ($task.Task.Principals.Principal.UserID)
			{
				Write-Verbose -Message "Writing the log with the values for $computername"
				Add-Content -Path $logfilepath -Value "$Computername, $Item, $check"
			}
		}
	}

The results look something like this: (my script had a typo and I didn’t put a space between I and found.) #TyposHappen 🙂

Here’s what the log file looks like;

You can see in the CSV, the UserID listed is a SID. This particular one is also known as SYSTEM or LocalSystem. You might also see users listed like APPS\Administrator or DOMAIN\svc_user.

Ben Liebowitz, VCP, vExpert
NJ VMUG Leader

Share This:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.