Skip to content

PowerShell Active Directory Scripts to Check for Service Account Lockouts and Pull Event Logs From Domain Controllers

by on July 19, 2016

So if you’ve ever had users repeatedly locking out a service account, you may know what a nightmare it can be to track down and fix, as well as the problems it can cause with applications or automations. While the best approach is for users to use their own accounts, in some cases (due to legacy or configuration requirements) it is not possible. Also, sometimes users who know better are the culprits, like developers.

Here are two scripts for checking and getting details on the lockouts. I recommend setting them in Task Scheduler to check every 5 minutes and alert your team.

AD_lockoutalert.ps1

 

########## c:\ps_scripts\ad_lockoutalert.ps1

import-module activedirectory

#######variables
$email ="ebruce@thedomain.com,helpdesk@thedomain.com"
$mailfrom ="ebruce@thedomain.com"
$mailsmtp ="mail.thedomain.com"
$Reportname ="[Error] Sensitive Accounts Locked Out in Active Directory"
$alertflag= $False
$filepath = "c:\ps_output\checklocked.txt"

####### users to check - by AD username/samaccountname
$users = @("ServiceAccount1","ServiceAccount2","ServiceAccount3")
write-host $users

########### add headers
"<style> p {font-family:arial;} </style>" | out-file $filepath -append
"<p><b>Sensitive Accounts Locked Out in Active Directory</b></p><hr />" | out-file $filepath -append

########## Check users
foreach ($user in $users){
  $usertocheck = get-aduser $user -prop LockedOut
  $lockedstatus = $usertocheck.LockedOut
  $line = "[" + $lockedstatus + "] <b>"+ $usertocheck.samaccountname + ":</b> AD LockedOut status"
  write-host $line
  write-host ---------------------------------------
    if ($lockedstatus -eq $True){ 
	write-host Locked out has validated to True
	$alertflag = $True
	write-host alertflag is $alertflag
        "<p style="color: red">$line is <b>LOCKED!</b><p></p>" | out-file $filepath -append
    }else{ 
	write-host FALSE
	"<p>$line is <b>UNLOCKED</b></p>" | out-file $filepath -append
    }

  
  }

########## send mail only on Lockout = True found
if($alertflag -eq $True){
send-mailmessage -to "$email" -from "$mailfrom" -smtp "$mailsmtp" -subject "$Reportname" -bodyashtml -body "$(get-content $filepath | out-string)" #-att $filepath
}

###########Delete created file
write-host "deleting $filepath"
Remove-Item "$filepath"

#While(Test-Path $filepath) {Remove-Item $filepath}
#$userslocked = search-adaccount -lockedout
#$userslocked | select samaccountname | write-host

 

Get-EventLogsLockouts.ps1


# c:\ps_scripts\get-eventlogslockouts.ps1
import-module ActiveDirectory

########### variables
$S = "DC1","DC2"
[xml]$a = Get-Content "C:\ps_scripts\getEventLogsLockouts.xml"
$filepath = "c:\ps_output\dev_Get-eventslogslockouts.txt"
$Reportname = "[Error] Event Log Lockout Details"
$email ="ebruce@thedomain.com,helpdesk@thedomain.com"
$mailfrom ="ebruce@thedomain.com"
$mailsmtp ="mail.thedomain.com"

########### Check each dc server for events
foreach ($server in $S){
  Write-host Checking $server ...
  $myevents = Get-WinEvent -FilterXml $a -computername $server 
  write-host EVENTS FROM $server
  "EVENTS FROM $server"| out-file $filepath -append
  $myevents = $myevents| format-list -prop message
  $myevents | out-file $filepath -append
}

########## send email
$content = Get-Content $filepath
Write-host $filepath | out-string
send-mailmessage -to "$email" -from "$mailfrom" -smtp "$mailsmtp" -subject "$Reportname" -body "$(get-content $filepath | out-string)" 

-att $filepath

###########Delete created file
write-host "deleting $filepath"
Remove-Item "$filepath"

The XML file

<querylist>
<query id="0" path="Security">
<select path="Security"> *[System[(EventID=4740)]] and *[EventData[Data[@Name='TargetUserName']='MyServiceAccountName']]</select>
</query>
</querylist>
Leave a Comment

Leave a comment