MR M.
MR M.

Reputation: 27

How to find users who were disabled specific dates

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

Answers (2)

Santiago Squarzon
Santiago Squarzon

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

Theo
Theo

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

Related Questions