Home » Articles » Save those service accounts!

Save those service accounts!

Have you ever woken up at 2:33 am to the phone ringing off the hook because some service is not longer running and it must be fixed right now? And this service not running is because someone reset the password on a service account last week? I’ve seen this scenario play out way more than it ever should. Let’s nip that problem of service accounts running wild right away.

<#
.SYNOPSIS
Checks all servers available in the domain for services running under service
accounts.
.DESCRIPTION
Find-AllServiceAccounts grabs a list of all servers from the current domain and
uses WMI calls to retrieve a list of services from the servers. It then loops
through the services checking for service accounts and writes any service
accounts found to a CSV specifically for that server.
.NOTES
You will be prompted for credentials when first running this.
#>
Import-Module ActiveDirectory
# Default system accounts to exclude
$ExcludedServices = "NT AUTHORITY\LocalService", "LocalSystem", "NT AUTHORITY\NETWORK SERVICE", "NT AUTHORITY\NetworkService"

# Will pop up a prompt to provide credentials for making WMI calls
# to the remote systems
$Credentials = Get-Credential

# Uses the LDAP search results for computers
$HostList = Get-ADObject -SearchBase (Get-ADRootDSE).defaultNamingContext -LDAPFilter "(&(objectCategory=computer)(|(operatingSystem=Windows Server*)(operatingSystem=Windows 2000 Server)))" -Properties Name
$HostName = Get-Content env:computername

# Pass a service name in and check to see if it matches the excluded
# service accounts that you've preconfigured
function Check-ServiceName($ThisServiceName)
{
<#
.SYNOPSIS
Check-ServiceName verifies if a service is not a default service account
.DESCRIPTION
Check-ServiceName checks the service account for the specified service against
the list of excluded services from the $ExcludedServices variable. Returns $true
or $false.
.PARAMETER ThisServiceName
The service account to be checked against.
#>
  foreach($ExcludedName in $ExcludedServices)
  {
     if($ThisServiceName -eq $ExcludedName.ToLower())
     {
       return $true
     }
  }
  return $false
}

[array]$BadHostList = $null
# Our main loop, iterates through each system listed in
# the file and pulls all of their services
foreach($HostServer in $HostList)
{
  # Grab the list of services from the system
  if ($HostServer.Name -ne $HostName)
  {
    $ServiceList = get-WMIObject -Class win32_service -ComputerName $HostServer.name -Credential $Credentials -Property name,startname
  }
  # If it is the localhost then we need to exclude the credentials parameter
  else
  {
    $ServiceList = get-WMIObject -Class win32_service -ComputerName $HostServer.name -Property name,startname
  }

  # If the host could be contacted, loop through and check each service
  if($ServiceList)
  {
    [array]$CSVArray = $null

    foreach($ThisService in $ServiceList)
    {
      $CheckResult = Check-ServiceName($ThisService.StartName.ToLower())
      if ($CheckResult -eq $false)
      {
        Write-Host "Service: " $ThisService.name
        Write-Host "Account: " $ThisService.StartName
        $CSVArray += ,$ThisService | select Name,StartName    
      }
    }

    if ($CSVArray.count -gt 0)
    {
      Write-Host "Saving .csv for $HostServer"
      Write-Host ""
      $CSVArray | Export-CSV "$HostServer.csv"
      $CSVCount++
    }
  }
  # The host could not be contacted, note it down
  else
  {
    Write-Host "$($HostServer.name) is unreachable."
    $BadHostList += $HostServer
  }
}

if($CSVCount -gt 1)
{
  Write-Host "Done, wrote out $($CSVCount) .csv files."
}
elseif($CSVCount -eq 1)
{
  Write-Host "Done, wrote out $($CSVCount) .csv file."
}
else
{
  Write-Host "No .csv files written out, no service accounts found."
}

if($BadHostList)
{
  foreach($TargetHost in $BadHostList)
  {
    Write-Host "$($TargetHost.Name) at $($TargetHost.DistinguishedName) was unreachable."
  }
}

What this does for you is that it runs through all of your servers (assuming they will respond to WMI queries, you’ll want to check your firewall policies) and dumps out a CSV for any server with service accounts reporting what services are using service accounts and which service accounts those are. This will save you much frustration in tracking down who will be impacted by a service account password reset, security audits, password reset frenzies and just plain documentation.

Speaking of security audits and password resets, in an upcoming post I’ll show you how to easily update all of your service account passwords so that you can spend the rest of the day playing Animal Crossing rather than remoting from server to server to server …

Did this post help you out? Do you have any questions or a specific topic you’d like me to delve into? Just let me know, thanks!


Leave a comment

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

wordpress visitor counter

RSS Subscriptions

Contact Me