Powershell to display services and scheduled Tasks

Jo Cox
Jo Cox used Ask the Experts™
on
Hi
I'd like a little windows powershell script that
Lists services on a remote computer and what logon (or better a specific logon) they use
Same for scheduled tasks

Anyone got any samples would be much appreciated.

Jo
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
A lack of information provides a lack of a decent solution.
Commented:
https://gallery.technet.microsoft.com/scriptcenter/PowerShell-script-to-find-6fc15ecb

That'll pull all your services

Get-scheduledtask would be the other one.

<#
.Synopsis
   PowerShell script to list all Scheduled Tasks and the User ID
.DESCRIPTION
   This script scan the content of the c:\Windows\System32\tasks and search the UserID XML value. 
   The output of the script is a comma-separated log file containing the Computername, Task name, UserID.
#>

Import-Module ActiveDirectory
$VerbosePreference = "continue"
$list = (Get-ADComputer -LDAPFilter "(&(objectcategory=computer)(OperatingSystem=*server*))").Name
Write-Verbose  -Message "Trying to query $($list.count) servers found in AD"
$logfilepath = "$home\Desktop\TasksLog.csv"
$ErrorActionPreference = "SilentlyContinue"

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 file with values for $computername"           
          Add-content -path $logfilepath -Value "$computername,$item,$check"
        }

    }
}

Open in new window


That'll do it.
Jo CoxICT Manager

Author

Commented:
Thank you. I'll give it a go.
Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
Wrote this some time ago. You can use the -Filter argument to look only for the accounts given you're looking for, but keep in mind that if it's a domain account, it may come in three different formats: DnsDomainName\SamAccountName, NetBiosDomainName\SamAccountName, or UserPrincipalName (usually  user@DnsDomainName).
Or you can just run it as it is, it will by default filter out anything that's running with one of the default accounts.
Save as Get-ServiceOrTaskAccount.ps1 or Whatever.ps1.
You can pipe a list of computer names to process to it, and you can pipe the output to Export-Csv.
Errors will be suppressed and listed in the output in the column "Exception".
<#
.SYNOPSIS
Gets a list of accounts used in services and tasks.
.DESCRIPTION
Gets a list of accounts used in services and tasks. Default Windows accounts will be filtered out.
.PARAMETER ComputerName
A list of computer names to query.
You can pipe strings to this argument.
.PARAMETER Filter
A list of strings with account names to look for; overrides the default filter.
Note that accounts may show up as DnsDomainName\User, NetBiosDomainName\User, or user@DnsDomainName.
.PARAMETER ServiceOnly
Process only services.
.PARAMETER TaskOnly
Process only tasks.
.INPUTS
System.String
.OUTPUTS
System.Management.Automation.PSCustomObject
.EXAMPLE
.\Get-ServiceOrTaskAccount
.EXAMPLE
.\Get-ServiceOrTaskAccount -ComputerName SomeMachine, SomeOtherMachine -ServiceOnly
.EXAMPLE
Get-Content .\servers.txt | .\Get-ServiceOrTaskAccount.ps1 -Filter "Domain\Administrator", "Administrator@domain.com"
.EXAMPLE
Get-Content .\servers.txt | .\Get-ServiceOrTaskAccount.ps1 | Export-Csv -Path -NoTypeInformation -Path C:\Temp\accounts.csv
#>
#requires -Version 3
[CmdletBinding(DefaultParameterSetName="Get_Service_Task")]
Param(
	[Parameter(Mandatory=$false, Position=0, ValueFromPipeline=$True)]
	[string[]]$ComputerName = @($ENV:ComputerName),
	[string[]]$Filter,
	[Parameter(Mandatory=$false, ParameterSetName="Get_Service")]
	[switch]$ServiceOnly,
	[Parameter(Mandatory=$false, ParameterSetName="Get_Task")]
	[switch]$TaskOnly
)
Begin {
	$ignoreAccounts = @()
	ForEach ($Name In ('NT AUTHORITY\LocalService', 'NT AUTHORITY\LocalSystem', 'NT Authority\NetworkService', 'NT AUTHORITY\SYSTEM')) {
		$ignoreAccounts += $Name
		$ignoreAccounts += $Name.Split('\')
	}
	ForEach ($sid In ('S-1-5-18', 'S-1-5-19', 'S-1-5-20', 'S-1-5-80-0')) {
		$principalSID = New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList $sid
		$principal = $principalSID.Translate([System.Security.Principal.NTAccount])
		$ignoreAccounts += $sid
		$ignoreAccounts += $principal.Value
		$ignoreAccounts += $principal.Value.Split('\')
	}
	$ignoreAccounts = $ignoreAccounts | Sort-Object -Unique
	$result = [ordered]@{
		'ComputerName' = $null
		'Type' = $null
		'Name' = $null
		'Account' = $null
		'Exception' = $null
	}
	If ($Filter) {
		Write-Warning "Will only list objects running with the following accounts:`r`n'$($Filter -join "', '")'"
	} Else {
		Write-Warning "Will list objects NOT running with the following accounts:`r`n'$($ignoreAccounts -join "', '")'"
	}
	
	Function Select-Account([System.Collections.Specialized.OrderedDictionary]$Result) {
		If ($Filter) {
			$skip = $Filter -notcontains $Result['Account']
		} Else {
			$skip = $ignoreAccounts -contains $Result['Account']
		}
		If ($skip) {
			Write-Verbose -Message "[$($Result['ComputerName'])] Ignored $($Result['Type']) '$($Result['Name'])', account '$($Result['Account'])'."
		} Else {
			New-Object -TypeName PSObject -Property $Result
		}
	}
}
Process {
	ForEach ($computer In $ComputerName) {
		Write-Host "Processing $($computer) ..."
		$result['ComputerName'] = $computer
		If ($PsCmdlet.ParameterSetName.Contains('Service')) {
			$result['Type'] = 'Service'
			Try {
				ForEach ($Service In (Get-WmiObject -Query "Select DisplayName, StartName From Win32_Service" -ComputerName $computer -ErrorAction Stop)) {
					$result['Name'] = $Service.DisplayName
					$result['Account'] = $Service.StartName
					Select-Account -Result $result
				}
			} Catch {
				$result['Name'] = $null
				$result['Account'] = $null
				$result['Exception'] = $_.Exception.Message
				New-Object -TypeName PSObject -Property $result
				$result['Exception'] = $null
			}
		}
		If ($PsCmdlet.ParameterSetName.Contains('Task')) {
			$result['Type'] = 'Task'
			$output = schtasks.exe /s $computer /xml ONE 2>&1
			If ($LastExitCode -eq 0) {
				[xml]$xml = $output -replace 'xmlns=', '_xmlns='
				ForEach ($Node In $xml.SelectNodes("Tasks/Task/Principals/Principal/UserId")) {
					$result['Name'] = $Node.SelectSingleNode('../../../preceding-sibling::comment()[1]').InnerText.Trim()
					$result['Account'] = $Node.'#text'
					Select-Account -Result $result
				}
			} Else {
				$result['Name'] = $null
				$result['Account'] = $null
				$result['Exception'] = $output -join " "
				New-Object -TypeName PSObject -Property $result
				$result['Exception'] = $null
			}
		}
	}
}

Open in new window

Jo CoxICT Manager

Author

Commented:
Thanks Alex
That gave me enough of a starting point to get me going.
Jo

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial