Service account usage finder
A read-only service account discovery pass for Windows services, scheduled tasks, and IIS application pools.
Good For
- service account review
- password rotation planning
- identity cleanup
- incident scoping
- least-privilege audit
How to Use It
- Start with a host list from a password rotation, application inventory, or account owner request.
- Collect Windows service identities and record service name, display name, run-as account, and state.
- Collect scheduled task run-as identities and preserve task path so owners can find the exact task.
- On IIS servers, collect application pool identity settings and note custom user names separately from built-in identities.
- If the same account appears on unrelated workloads, split the findings by owner before recommending rotation or gMSA migration.
- Group findings by account so owners can see every endpoint and workload using the identity.
- Use the report to plan rotations, gMSA migration, or decommissioning work through separate change tickets.
Execution Modes
- local
- remote-single-host
- remote-host-list
- ad-filtered
Inputs and Outputs
Inputs
- computer name
- CSV or TXT server list
- Active Directory computer scope
- known service account list
Outputs
- verbose-console
- csv
Command Starter
Safe to run: read-only
# ---------------------------------------------------------------------
# Operator inputs
# ---------------------------------------------------------------------
$ComputerNames = @('appserver01')
$OutputPath = '.\service-account-usage.csv'
# ---------------------------------------------------------------------
# Collect run-as identities from services, tasks, and IIS app pools
# ---------------------------------------------------------------------
$Results = foreach ($ComputerName in $ComputerNames) {
try {
Invoke-Command -ComputerName $ComputerName -ErrorAction Stop -ScriptBlock {
# Domain or UPN-style service identities used by Windows services.
Get-CimInstance -ClassName Win32_Service |
Where-Object { $_.StartName -match '\\' -or $_.StartName -like '*@*' } |
ForEach-Object {
[pscustomobject]@{
ComputerName = $env:COMPUTERNAME
WorkloadType = 'WindowsService'
WorkloadName = $_.Name
RunAsIdentity = $_.StartName
State = $_.State
}
}
# Scheduled tasks can hide durable service-account dependencies.
Get-ScheduledTask |
Where-Object { $_.Principal.UserId -match '\\' -or $_.Principal.UserId -like '*@*' } |
ForEach-Object {
[pscustomobject]@{
ComputerName = $env:COMPUTERNAME
WorkloadType = 'ScheduledTask'
WorkloadName = "$($_.TaskPath)$($_.TaskName)"
RunAsIdentity = $_.Principal.UserId
State = $_.State
}
}
# IIS may not exist on every target. Skip gracefully when the module is absent.
if (Get-Module -ListAvailable -Name WebAdministration) {
Import-Module WebAdministration -ErrorAction SilentlyContinue
Get-ChildItem IIS:\AppPools |
Where-Object { $_.processModel.userName } |
ForEach-Object {
[pscustomobject]@{
ComputerName = $env:COMPUTERNAME
WorkloadType = 'IISAppPool'
WorkloadName = $_.Name
RunAsIdentity = $_.processModel.userName
State = $_.State
}
}
}
}
}
catch {
[pscustomobject]@{
ComputerName = $ComputerName
WorkloadType = 'CollectionError'
WorkloadName = $null
RunAsIdentity = $null
State = $null
Error = $_.Exception.Message
}
}
}
$Results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
$Results | Sort-Object RunAsIdentity, ComputerName, WorkloadType | Format-Table -AutoSizeValidation
- Every scoped host has service-account evidence or an access/error note.
- Each discovered identity is mapped to at least one service, task, app pool, or unknown-use bucket.
- Any later password rotation has owner approval, dependency checks, and a rollback plan.
Reporting
- export service, task, and app-pool identity usage to CSV
- group usage by account, server, workload type, and owner
- promote repeated use into a service-account dependency report
Safety Notes
- This discovery pass is read-only and should not change service, task, or app-pool identities.
- Do not rotate, disable, or delete service accounts until dependency owners and rollback paths are confirmed.