Reputation: 27
Could someone help me find disabled accounts from AD within a specific timeframe?
For example, I can run a script that shows me the last 30 days, 60 , 90 whatever
Search-ADAccount -SearchBase "DC=A,DC=B,DC=C,DC=X" -AccountDisabled -UsersOnly | Get-ADUser -Properties whenChanged | Where whenChanged -gt (Get-Date).AddDays(-60) | Export-CSV “C:\Disabledusers60.CSV” –NoTypeInformation
The problem is that this way I would see the present ones from January 2022 as well, and my idea is to be able to run a specific date, so in the end of February to have a list of disabled users between 1st of December- 31th of Dec. Then on March to have the list from 1st of January till 31th January and so on.
That way will not pull out from AD last 60 days including the disabled accounts from the current month.
Sorry for the big thread explanation, hopefully, someone could bring some light here.
Upvotes: 2
Views: 10094
Reputation: 61103
This should give you a list of AD Users which are Disabled and their WhenChanged attribute is between the first and last day of the Month.
$today = [datetime]::Today
$firstDay = [datetime]::new($today.Year, $today.Month, 1, 0, 0, 0)
$lastDay = $firstDay.AddMonths(1).AddSeconds(-1)
$params = @{
SearchBase = 'OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM'
Properties = 'whenChanged'
LDAPFilter = -join @(
'(&'
'(userAccountControl:1.2.840.113556.1.4.803:=2)'
'(whenChanged>={0:yyyyMMddHHmmss.0Z})' -f $firstDay
'(whenChanged<={0:yyyyMMddHHmmss.0Z})' -f $lastDay
')'
)
}
Get-ADUser @params | Export-Csv ...
If you need to query a different time range you would need to update the variables $firstDay
and $lastDay
, for example, for September 2021:
$firstDay = [datetime]::new(2021, 9, 1, 0, 0, 0)
$lastDay = [datetime]::new(2021, 10, 1, 0, 0, 0).AddSeconds(-1)
# 10 => Being the next Month and .AddSeconds(-1) for
# the last second of the Previous Month (9)
# If this was for the Month of December:
# [datetime]::new(2022, 1, 1, 0, 0, 0).AddSeconds(-1)
Upvotes: 3
Reputation: 61218
As commented, the whenChanged
attribute does not necessarily be the date and time a user was disabled, because there could have been other modifications to the user account afterwards.
How about probing the windows Event log for event 4725 (==> a user account was disabled) ?
Thanks to ZivkoK, who commented that events are not replicated across Domain Controllers, you need to loop over all of them to get the results
# example timeframe December 2021
$startTime = [datetime]'12/1/2021'
$endTime = $startTime.AddMonths(1).AddDays(-1)
$filter = @{LogName='Security';ProviderName='Microsoft-Windows-Security-Auditing';ID=4725;StartTime=$startTime;EndTime=$endTime }
$DCs = (Get-ADDomainController -filter *).Name # or HostName for fqdn
$result = foreach ($dc in $DCs) {
# you may need to use the -Credential parameter on Get-WinEvent
# to supply the credentials of a domain administrator
Get-WinEvent -FilterHashtable $filter -ComputerName $dc | ForEach-Object {
# convert the event to XML and grab the Event node
$eventXml = ([xml]$_.ToXml()).Event
$userName = ($eventXml.EventData.Data | Where-Object { $_.Name -eq 'TargetUserName' }).'#text'
$userSID = ($eventXml.EventData.Data | Where-Object { $_.Name -eq 'TargetSid' }).'#text'
$userDomain = ($eventXml.EventData.Data | Where-Object { $_.Name -eq 'TargetDomainName' }).'#text'
# output the properties you need
[PSCustomObject]@{
UserName = $userName
UserSID = $userSID
UserDomain = $userDomain
Disabled = [DateTime]$eventXml.System.TimeCreated.SystemTime
}
}
}
# output on screen
$result | Format-Table -AutoSize # or use Out-GridView if you prefer
# output to CSV file
$outFile = 'X:\DisabledUsers_{0:MMM-yyyy}.csv' -f $startTime
$result | Export-Csv -Path $outFile -NoTypeInformation
Upvotes: 3