Back to script library
Entra / Microsoft 365 · Users & guests

Update banned passwords list

This script updates the list of banned passwords in Microsoft Entra ID (Azure AD) using the Microsoft Graph PowerShell SDK.

Connect & set up

Run these once per session. All scopes are read-only unless the script makes changes.

Connect-MgGraph -Scopes Directory.ReadWrite.All -NoWelcome

Run it

The main script. Copy it, or download the .ps1 and run it from your console.

Connect-MgGraph -Scopes Directory.ReadWrite.All -NoWelcome
$Scopes = Get-MgContext | Select-Object -ExpandProperty Scopes
If ($Scopes -notcontains "Directory.ReadWrite.All") {
Write-Host "You need to consent to the Directory.ReadWrite.All scope to run this script" -ForegroundColor Red
Break
}
# Import the list of banned passwords from a CSV file. The CSV file should have a single column named 'Banned Passwords'.
$ImportPasswordFile = "C:\temp\BannedPasswords.csv"
[array]$NewBannedPasswordsInput = Import-CSV -Path $ImportPasswordFile | Select-Object -ExpandProperty 'Banned Passwords'
[array]$NewBannedPasswords = $null
If ($null -eq $NewBannedPasswordsInput -or $NewBannedPasswordsInput.Count -eq 0) {
Write-Host "No banned passwords found in the input file. Please check the file and try again." -ForegroundColor Red
Break
}
# Check that we have valid passwords to add
ForEach ($Password in $NewBannedPasswordsInput) {
If ($Password.Length -lt 4 -or $Password.Length -gt 16) {
Write-Host ("Password {0} is not between 4 and 16 characters long. It won't be added to the list of banned passwords." -f $Password) -ForegroundColor Red
Continue
} Else {
$NewBannedPasswords += $Password.Trim()
}
}
# Get directory setting object for password rules
$Policy = (Get-MgBetaDirectorySetting | Where-Object {$_.TemplateId -eq "5cf42378-d67d-4f36-ba46-e8b86229381d"})
If ($null -eq $Policy) {
# No custom directory setting found for password rules, so create a new one
Write-Host "No directory setting policy found for password rules - creating new policy"
[array]$NewBannedPasswords = $NewBannedPasswords -join ([char]9)
[int32]$LockOutDuration = 60
[int32]$LockOutThreshold = 10
# Create the values for the new directory setting
$Value1 = @{}
$Value1.Add("Name", "BannedPasswordList")
$Value1.Add("Value", $NewBannedPasswords)
$Value2 = @{}
$Value2.Add("Name", "BannedPasswordCheckOnPremisesMode")
$Value2.Add("Value", "Enforce")
$Value3 = @{}
$Value3.Add("Name", "EnableBannedPasswordCheckOnPremises")
$Value3.Add("Value", 'false')
$Value4 = @{}
$Value4.Add("Name", "EnableBannedPasswordCheck")
$Value4.Add("Value", 'true')
$Value5 = @{}
$Value5.Add("Name", "LockoutDurationInSeconds")
$Value5.Add("Value", $LockoutDuration -as [int32])
$Value6 = @{}
$Value6.Add("Name", "LockoutThreshold")
$Value6.Add("Value", $LockOutThreshold)
# Create the input hash table for the new directory setting
$NewBannedListParameters = @{}
$NewBannedListParameters.Add("templateId", "5cf42378-d67d-4f36-ba46-e8b86229381d")
$NewBannedListParameters.Add("values", ($Value1, $Value2, $Value3, $Value4, $Value5, $Value6))
# Try and create the new directory setting
Try {
$Policy = New-MgBetaDirectorySetting -BodyParameter $NewBannedListParameters -ErrorAction Stop
Write-Host "New directory setting created with ID {0}" -f $Policy.Id
} Catch {
Write-Host "Error creating directory setting for password rules"
Write-Host $_.Exception.Message
Break
}
} Else {
# The tenant already has a directory setting for password rules, so update it
Write-Host ("Directory setting found with ID {0}. Updating current policy" -f $Policy.Id)
[array]$PolicyValues = Get-MgBetaDirectorySetting -DirectorySettingId $Policy.Id | Select-Object -ExpandProperty Values
# Extract the current banned password list and merge it with the new passwords
# If you don't want to include the current banned passwords, comment out the next 2 lines so that only passwords from the CSV file are used
[array]$CurrentBannedList = $PolicyValues | Where-Object {$_.Name -eq "BannedPasswordList"} | Select-Object -ExpandProperty Value
[array]$CurrentBannedList = $CurrentBannedList -Split([char]9)
[array]$NewBannedPasswords = $NewBannedPasswords + $CurrentBannedList | Sort-Object -Unique
# Can only have 1000 banned passwords in the list, so trim if necessary
If ($NewBannedPasswords.count -gt 1000) {
Write-Host "Banned password list has more than 1000 entries. Trimming to first 1000 entries"
$NewBannedPasswords = $NewBannedPasswords | Select-Object -First 1000
} Else {
Write-Host ("Banned password list now includes {0} entries" -f $NewBannedPasswords.count)
}
[array]$NewBannedPasswords = $NewBannedPasswords -join ([char]9)
# Update the directory setting with the new banned password list
($PolicyValues | Where-Object {$_.Name -eq "BannedPasswordList"}).Value = $NewBannedPasswords
# And write the new values back into the directory setting
Try {
Update-MgBetaDirectorySetting -DirectorySettingId $Policy.id -Values $PolicyValues -ErrorAction Stop
Write-Host "Password rules updated successfully"
} Catch {
Write-Host "Error updating directory setting for password rules"
Write-Host $_.Exception.Message
Break
}
}
# Export the updated banned password list to a CSV file
$ExportFile = "C:\temp\UpdatedBannedPasswords.csv"
[array]$PolicyValues = Get-MgBetaDirectorySetting -DirectorySettingId $Policy.Id | Select-Object -ExpandProperty Values
[array]$CurrentBannedList = $PolicyValues | Where-Object {$_.Name -eq "BannedPasswordList"} | Select-Object -ExpandProperty Value
[array]$CurrentBannedList = $CurrentBannedList -Split([char]9)
$CurrentBannedList | Sort-Object -Unique | Out-File -Path $ExportFile
Write-Host ("Banned password list updated and exported to {0}" -f $ExportFile)
Attribution