Microsoft ADFS (Active Directory Federation Services) has a feature known as extranet lockout and extranet smart lockout. ADFS extranet smart lockout allows you to differentiate between sign-in attempts from unknown locations and known locations. Which in turn prevents users getting locked on the Active Directory domain.
Pro tip: this post relies on basic Windows PowerShell skills. I can highly recommend O’reilly’s PowerShell cookbook to improve your basic PowerShell skills.
When a user get’s locked out, ADFS has a PowerShell cmdlet know Get-ADFSAccountActivity to get the lock out status of one particular user. You can use the cmdlet as follows:
Get-AdfsAccountActivity -Identity <username>
The response of the command looks like this:
Identifier : DOMAIN\Username BadPwdCountFamiliar : 0 BadPwdCountUnknown : 6 LastFailedAuthFamiliar : 1-1-0001 01:00:00 LastFailedAuthUnknown : 4-2-2020 12:36:11 FamiliarLockout : False UnknownLockout : True FamiliarIps : {}
Unfortunately Microsoft has not provided us with a PowerShell cmdlet to get the lockout status for all users. I created two scripts to allow you to fetch the activity status of all users. This first script get’s all the userprincipalnames from the Active Directory. You need the ActiveDirectory PowerShell module for this.
The scripts
Here is the first script:
import-module ActiveDirectory
$users = Get-ADUser -SearchBase "OU=Users,DC=contoso,DC=local" -filter * | Select-Object -Property userprincipalname
$users | export-csv -NoTypeInformation C:\Development\PowerShell\users.csv
You need to modify the “SearchBase” to match you Active Directory structure. Furthermore you need to change the the path of the CSV file to match your export location. I ran this script from my Windows 10 administration machine.
The second script needs to be run on the ADFS server using “Run as Administrator” (administrative privileges):
$users = import-csv users.csv
$export_users = @()
foreach ($user in $users)
{
try {
# Get ADFS activity
$activity = Get-AdfsAccountActivity -Identity $user.UserPrincipalName
if ($activity.UnknownLockout -eq $true -or $activity.FamiliarLockout -eq $true) {
$export_user = New-Object PSObject -Property @{
Username = $activity.identifier
UnknownLockout = $activity.UnknownLockout
FamiliarLockout = $activity.FamiliarLockout
}
$export_users += $export_user
}
} catch {
# Catch condition when user is not in ADFS database.
}
}
# Export users to HTML file
$export_users | ConvertTo-Html | out-file report.html
As you can see the second script requires an input CSV file which we generated using script 1. The script will generate a HTML file with the username and whether it is locked out on either the familiar or unknown locations.
awesome thanks.
How would I use the output to CSV to unlock in bulk all those with either familiar or unknown lockout?
Can you run this from a PC or does it require being installed on a server?
You need to run this on.an ADFS server. Better get rid though of ADFS in 2023. Look into Azure AD enterprise applications as alternative.