PowerShell: Check Servers on Domain to Locate A Domain Account Being Set to Run Services and Scheduled Tasks

# Obtain the name of the default domain Administrator account (this account is expected to be disabled)
$domain=(net config workstation) -match 'Workstation domain\s+\S+$' -replace '.+?(\S+)$','$1';
$defaultDomainAdmin="$domain\Administrator"

# Regex key to search for server names: look back to CN= as $0, match anything but a comma as $1, capture CN|OU as $2,separated by =, capture next part as $3
$regexServers="(?<=CN=)(.*?),(OU|CN)=([^,]+)"

# Collect server names and their containers
$servers=dsquery * -Filter "(&(objectCategory=computer)(operatingSystem=*server*))" -limit 1000000| %{[void]($_ -match $regexServers);$matches[1];$matches[3]}|select @{Name="Name";expression={$matches[1]}},@{Name="container";expression={$matches[3]}}|sort-object -Property Name -Unique

Function checkServiceAccount($searchAccount,$sherver){

# Original function is meant to query multiple machines. It's now adapted to just one machine
$servers=$sherver
$runas=$searchAccount
$scheduledTasksMatch="";
$servicesMatch="";
$result="";

Function Search-ScheduledTasks{
Param(
[array]$ComputerNames = $servers, #Accepts input and cast it as an array
[string]$runasUser=$runas
)
Begin{
$Results = @() #Initializes an empty array
}
Process{
If ($_){ #Checks if this function is being called via pipe command. If so, use set $ComputerNames variable as pipe
$ComputerNames = $_
}
ForEach ($Computer in $ComputerNames){
If (Test-Connection $Computer -Quiet){ #Checks for connectivity before proceeding
# Use the legacy schtasks command from localhost to query remote machine and format an output int CSV format
$tasksAsCSV = schtasks.exe /query /s $Computer /V /FO CSV

# Process the CSV result into PowerShell. Filter entries that are not labeled as "TaskName" and by "Run as User" field
$result = $tasksAsCSV | ConvertFrom-Csv | Where { $_.TaskName -ne "TaskName" -and $_."Run As User" -eq $runasUser}

#Appends this result into array collection named results.
$Results += $result
}
} #end foreach
}
End{
if ($Results){
Return $Results."Task To Run"
}
else {
"No Scheduled Events were found for user $runasUser.";
}
}
} #end Search-ScheduledTasks function

$servicesMatch=(Get-Wmiobject win32_service -ComputerName $sherver | where-object{$_.startname -like $runasUser}|select @{name="ServiceName";expression={$_.name}}).ServiceName|out-string
$scheduledTasksMatch = Search-ScheduledTasks;

if($servicesMatch){$result+=("$servicesMatch").Trim()}else{"No services are currently using the $searchAccount."}
if($scheduledTasksMatch){$result+="`n$scheduledTasksMatch"}
return $result;
}

$servers | %{checkServiceAccount $defaultDomainAdmin $_}

Leave a Reply

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