Imagine waking up to an email full of alerts about unwanted access attempts. It is every administrator’s nightmare. The truth is that many security incidents can be traced back to disabled accounts that were not properly reviewed. You might wonder, “What about disabled accounts? “Aren’t they harmless?” Well, not quite. There are reasons we need to, Audit Disabled Accounts.
Disabled accounts in Active Directory (AD) are analogous to lost keys to your home. They may be out of sight, but they do exist. Those who look hard enough can find them. If you do not audit these accounts on a regular basis, you risk exposing your network to vulnerabilities. Neglected accounts may result in attacks or compliance difficulties.
I discovered this the hard way during my early days as a sysadmin. I believed I had things under control. One day, an audit found multiple disabled accounts that had been left neglected for months. It was a wakeup call. Since then, reviewing disabled accounts has been an important part of my routine.
Why should you consider auditing disabled accounts? It’s not just about checking the compliance box. It is about ensuring a safe and well-managed environment. It is critical to keep your network secure from unauthorized access and breaches. In this post, I’ll show you how to build up a PowerShell script to audit disabled accounts. We will also automate the process using a scheduled task. Believe me, it’s easier than you think. Your future self will thank you for this.
Let us begin our path toward greater security and peace of mind.
The Why Audit Disabled Accounts?
Picture this: It’s the middle of the day, when the CFO’s account is abruptly deactivated. Chaos ensues. The support desk is frantic, and everyone is on edge. You are left wondering, “Who did this, and when?” It’s a frustrating situation that could have been prevented with routine audits.
Auditing disabled accounts is more than just a boring process; it is critical for determining exactly when and by whom an account was disabled. Consider installing a surveillance camera on your network doors. You know precisely who locked which door and at what time. This level of visibility is critical for keeping control of your Active Directory (AD).
This PowerShell script was built in response to a particularly stressful occurrence. A help desk technician unintentionally shut down the CFO’s account. The names were nearly identical: bholts for the CFO, and bsholts for a floor technician. One tiny error resulted in a major problem. The CFO was naturally furious, demanding to know who was to blame. That’s when I realized I needed a solid technique to keep track of these actions.
Security is a significant reason for auditing disabled accounts. If an attacker acquires access to one of these accounts, they may be able to explore your network without detection. It’s like leaving the front door wide open. Regular audits ensure that these accounts are appropriately managed and secured, preventing unwanted access.
Compliance
Compliance is another reason to keep track of disabled accounts. Many regulatory regimes impose severe controls on user accounts. GDPR, HIPAA, and other regulations need proper account management, including for disabled accounts. Failure to comply might result in costly fines and a tarnished reputation.
However, it is not simply about avoiding undesirable results. Regular auditing of disabled accounts is also excellent housekeeping. It keeps your Active Directory clean and orderly. An clean Active Directory makes it easier to manage active users and keeps your environment running smoothly.
In my early sysadmin days, I underestimated the necessity of auditing disabled accounts. That was until the incident with the CFO’s account. Since then, auditing has been an essential component of my managerial routine. It’s a modest step that provides significant peace of mind.
So take a time to reflect on your current practices. Do you periodically audit disabled accounts? If not, this is a great moment to start. It represents an investment in your network’s security and efficiency. And believe me, it is worth every minute.
The Script
#Hourly
[cmdletbinding()]
param (
[int]$HoursBack = 1,
[string[]]$Servers,
[string]$OutCSVfile
)
$StartTimeStamp = ((Get-Date).AddHours(-($HoursBack)))
$EndTimeStamp = (Get-Date)
$ReturnInfo = @()
$FilterTable = @{
'StartTime' = $StartTimeStamp
'EndTime' = $EndTimeStamp
'LogName' = 'Security'
'Id' = 4725
}
$Events = foreach ($Server in $Servers) {
Get-WinEvent -ComputerName "$Server" -FilterHashtable $FilterTable -ErrorAction SilentlyContinue
}
foreach ($Event in $Events) {
$ReturnInfo += [pscustomobject][ordered]@{
Task = "Account Disabled"
Time = $Event.TimeCreated
DC = $Event.MachineName
Name = (get-aduser -Identity "$($Event.Properties[0].Value)" -Properties DIsplayname).Displayname
Username = $Event.Properties[0].Value
Admin = $Event.Properties[4].Value
}
}
$ReturnInfo | Export-Csv $OutCSVfile -NoClobber -NoTypeInformation -Append
The Breakdown
Let’s dive into the heart of this guide: the PowerShell script that will help you audit disabled accounts in Active Directory. We’ll break it down line by line, so you understand exactly how it works and how to customize it for your needs.
[cmdletbinding()]
param (
[int]$HoursBack = 1,
[string[]]$Servers,
[string]$OutCSVfile
)
- Parameters and Initialization
- [cmdletbinding()]: This line makes the script act like an advanced function, providing more control over parameters and runtime behavior.
- param: Here, we define three parameters:
$HoursBack
: The number of hours back to search for disabled accounts (default is 1).$Servers
: An array of server names to query.$OutCSVfile
: The file path to save the audit results.
$StartTimeStamp = ((Get-Date).AddHours(-($HoursBack)))
$EndTimeStamp = (Get-Date)
- Setting Up Timestamps
- $StartTimeStamp: Sets the start time for the search to one hour ago.
- $EndTimeStamp: Sets the end time to the current date and time.
$ReturnInfo = @()
$FilterTable = @{
'StartTime' = $StartTimeStamp
'EndTime' = $EndTimeStamp
'LogName' = 'Security'
'Id' = 4725
}
Grabbing the Events
- Filtering Events
- $ReturnInfo: Initializes an empty array to store the results. This allows us to collect the needed information for later.
- $FilterTable: Defines the criteria for filtering events:
StartTime
andEndTime
specify the time range. It’s important not to grab to many logs because Powershell can’t handle large amount of data.LogName
is set to ‘Security’ to search in the Security log because that is where the disabled accounts live.Id
is set to 4725, the event ID for account disablement.
$Events = foreach ($Server in $Servers) {
Get-WinEvent -ComputerName "$Server" -FilterHashtable $FilterTable -ErrorAction SilentlyContinue
}
- Retrieving Events
- foreach ($Server in $Servers): Iterates through each server in the
$Servers
list of strings. Remember, a list of strings is like an array but for strings. Reminds me of noodles before you cook them. Which my daughter made spaghetti the other day and I am proud of her. - Get-WinEvent: Retrieves the events that match the criteria in
$FilterTable
.-ErrorAction SilentlyContinue
suppresses errors. I liken this command to the spaghetti after it has been cooked.
- foreach ($Server in $Servers): Iterates through each server in the
foreach ($Event in $Events) {
$ReturnInfo += [pscustomobject][ordered]@{
Task = "Account Disabled"
Time = $Event.TimeCreated
DC = $Event.MachineName
Name = (get-aduser -Identity "$($Event.Properties[0].Value)" -Properties Displayname).Displayname
Username = $Event.Properties[0].Value
Admin = $Event.Properties[4].Value
}
}
Processing and Exporting Events
- Processing Events
- foreach ($Event in $Events): Iterates through each retrieved event. We like to loop a lot with powershell.
- $ReturnInfo += [pscustomobject][ordered]: Adds a custom object to the
$ReturnInfo
array, containing:Task
: Describes the task (“Account Disabled”).Time
: The time the event was created.DC
: The domain controller where the event occurred.Name
: The display name of the disabled account.Username
: The username of the disabled account.Admin
: The account of the administrator who performed the action.
$ReturnInfo | Export-Csv $OutCSVfile -NoClobber -NoTypeInformation -Append
- Exporting Results
- Export-Csv: Exports the
$ReturnInfo
array to a CSV file specified by$OutCSVfile
.-NoClobber
prevents overwriting existing files.-NoTypeInformation
omits type information from the CSV. That’s the crappy line that sucks at the top of csvs that powershell 5 likes to add. You don’t ahve to do this if you are using powershell 7.-Append
adds the results to the file without overwriting it.
- Export-Csv: Exports the
By understanding each part of this script, you can tailor it to your specific needs. Whether you’re dealing with multiple servers or need a different time range, you now have the tools to make those adjustments. From here, you can make scheduled tasks that points to the required devices and such. We will cover that next week.
In the end
Auditing disabled accounts in Active Directory is like keeping a vigilant eye on the silent guardians of your network. It’s a crucial step to ensure that your environment remains secure and compliant. With the PowerShell script we’ve walked through, you now have the tools to monitor when an account was disabled and by whom, saving you from potential security breaches and compliance headaches.
Remember the story of the help desk technician who accidentally disabled the CFO’s account? That incident was a wake-up call, highlighting the importance of regular audits. By setting up a scheduled task to run this script, you can prevent similar scenarios in the future. You’ll have clear, reliable records that can help you quickly identify and rectify mistakes, keeping your network safe and your users happy.
Regularly auditing disabled accounts isn’t just about avoiding problems; it’s about creating a culture of diligence and responsibility. It’s about taking proactive steps to manage your AD environment effectively. Whether you’re a seasoned sysadmin or new to the role, these practices are essential in maintaining a robust and secure network.
So, take a moment to implement these steps. Set up the script, configure the scheduled task, and rest easy knowing you’ve added a solid layer of protection to your network. Your future self, and your organization, will thank you.
What we can learn as a person?
Disabled accounts linger around and sometimes they can have emails and more attached to them. But they are not active. When I was working with the MSP, I often found ADs with a lot of these accounts and no documentation. Why were they disabled, and left there? Was it some compliance or something else?
Well, in our life, we have something like disabled accounts. They don’t activly hurt us, but over time they can add up and cause issues. That’s small truama. Some therapist call it death by a tousand paper cuts. By themselves, they are not damaging enough to cause PTSD or anything along those likes, but over time, they can cause major issues. A good example of this is, you get spanked each sunday because you fail asleep in church. Some people start seeing churchs as a place of abuse while others embrace the church as safty. By itself a simple spanking doesn’t cause trauma, unless it’s really ugly, but over time, it can cause all kinds of issues.
The shame child
The best way to handle these micro trauma’s is to address the distorted emotions that are born from them. A good example of this is a child who was shamed for being evil at birth. Hearing this one time is nothing, but hearing this daily makes this child believe he is evil. This translates to shame. This shame can come out in many different forms. To heal, he has to come to the conculsion himself that he wasn’t evil from birth and this belief is wrong.
It’s time for him to delete those accounts of shame. Knowing where they come from is half the battle. If you don’t kno where the emotion comes from, how do you find the emotion? It is a discovery process. It’s a rough one too. Seek a licensed therapist for this and have a good community.