When managing large Active Directory environments, administrators occasionally need to perform bulk operations like password resets. The challenge becomes particularly complex when dealing with Organizational Units (OUs) containing thousands of users. This guide will walk through a PowerShell solution that's efficient, secure, and compliant with Active Directory best practices.
- Active Directory Module for PowerShell installed
- Appropriate permissions (at least "Reset Password" rights)
- Knowledge of the target OU's Distinguished Name (DN)
Here's the fundamental script that will reset passwords for all users in a specified OU:
Import-Module ActiveDirectory
$TargetOU = "OU=Users,DC=domain,DC=com"
$NewPassword = ConvertTo-SecureString "P@ssw0rd123!" -AsPlainText -Force
Get-ADUser -Filter * -SearchBase $TargetOU | ForEach-Object {
Set-ADAccountPassword -Identity $_ -NewPassword $NewPassword -Reset
Set-ADUser -Identity $_ -ChangePasswordAtLogon $true
}
For production environments, consider this more robust version:
try {
Import-Module ActiveDirectory -ErrorAction Stop
$TargetOU = "OU=Employees,DC=corp,DC=example,DC=com"
$LogFile = "C:\Temp\PasswordResetLog_$(Get-Date -Format 'yyyyMMdd').csv"
$NewPassword = ConvertTo-SecureString "TempP@ss123" -AsPlainText -Force
$Users = Get-ADUser -Filter * -SearchBase $TargetOU -Properties Enabled
foreach ($User in $Users) {
if ($User.Enabled) {
try {
Set-ADAccountPassword -Identity $User -NewPassword $NewPassword -Reset -ErrorAction Stop
Set-ADUser -Identity $User -ChangePasswordAtLogon $true
"$($User.SamAccountName),Success" | Out-File $LogFile -Append
}
catch {
"$($User.SamAccountName),Failed - $($_.Exception.Message)" | Out-File $LogFile -Append
}
}
}
}
catch {
Write-Error "Critical error: $_"
exit 1
}
For enhanced security, you might want to generate unique temporary passwords:
function Generate-TemporaryPassword {
$Chars = [char[]]"ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789!@#$%^&*"
return -join (1..12 | ForEach-Object { $Chars | Get-Random })
}
Get-ADUser -Filter * -SearchBase $TargetOU | ForEach-Object {
$TempPassword = ConvertTo-SecureString (Generate-TemporaryPassword) -AsPlainText -Force
Set-ADAccountPassword -Identity $_ -NewPassword $TempPassword -Reset
}
- Always run such scripts in a test environment first
- Consider temporarily disabling password complexity requirements if you're using a common temporary password
- Ensure the script runs with minimum necessary privileges
- Secure the log files containing password reset information
When dealing with 10,000+ users, consider these optimizations:
$BatchSize = 1000
$Users = Get-ADUser -Filter * -SearchBase $TargetOU -ResultSetSize $BatchSize
for ($i=0; $i -lt $Users.Count; $i+=$BatchSize) {
$Batch = $Users[$i..($i+$BatchSize-1)]
$Batch | ForEach-Object -Parallel {
$Password = ConvertTo-SecureString "TempP@ss_$($using:i)" -AsPlainText -Force
Set-ADAccountPassword -Identity $_ -NewPassword $Password -Reset
} -ThrottleLimit 10
}
When you need to reset passwords for multiple users in an Active Directory Organizational Unit (OU), PowerShell provides the most efficient solution. The TechNet article you referenced contains the core cmdlet (Set-ADAccountPassword
), but let's break down how to implement this properly.
- Active Directory module for PowerShell installed (RSAT or on domain controller)
- Sufficient AD permissions to reset passwords
- Proper OU distinguished name
Here's a complete script that will reset passwords for all users in a specified OU:
# Import Active Directory module
Import-Module ActiveDirectory
# Define OU and new password
$targetOU = "OU=Users,DC=domain,DC=com"
$newPassword = ConvertTo-SecureString "TempP@ss123" -AsPlainText -Force
# Get all users in the OU and reset passwords
Get-ADUser -Filter * -SearchBase $targetOU | ForEach-Object {
Set-ADAccountPassword -Identity $_ -NewPassword $newPassword -Reset
Set-ADUser -Identity $_ -ChangePasswordAtLogon $true
Write-Output "Reset password for $($_.SamAccountName)"
}
For better security and logging, consider this enhanced version:
# Parameters
$targetOU = "OU=Sales,OU=Departments,DC=company,DC=com"
$logFile = "C:\logs\PasswordReset_$(Get-Date -Format 'yyyyMMdd').log"
# Generate random passwords
function Generate-RandomPassword {
$chars = [char[]]"ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789!@#$%"
return -join (1..12 | ForEach-Object { $chars | Get-Random })
}
# Main execution
try {
$users = Get-ADUser -Filter * -SearchBase $targetOU -Properties mail
foreach ($user in $users) {
$tempPassword = Generate-RandomPassword
$securePassword = ConvertTo-SecureString $tempPassword -AsPlainText -Force
Set-ADAccountPassword -Identity $user -NewPassword $securePassword -Reset
Set-ADUser -Identity $user -ChangePasswordAtLogon $true
# Log the action
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Reset password for $($user.SamAccountName) (Email: $($user.mail))" | Out-File $logFile -Append
# Optional: Email notification would go here
}
Write-Output "Successfully processed $($users.Count) users."
}
catch {
Write-Error "Error occurred: $_"
$_ | Out-File $logFile -Append
}
- Password policies: Ensure temporary passwords comply with your domain's complexity requirements
- Account lockout policies: Bulk operations might trigger lockout detection systems
- User communication: Plan how users will receive their temporary credentials
- Testing: Always test with a small OU first
For very large OUs (10k+ users), consider batching the operations:
$batchSize = 500
$users = Get-ADUser -Filter * -SearchBase $targetOU
$totalUsers = $users.Count
for ($i = 0; $i -lt $totalUsers; $i += $batchSize) {
$batch = $users | Select-Object -First $batchSize -Skip $i
$batch | ForEach-Object {
# Reset password logic here
}
Write-Progress -Activity "Processing users" -Status "$i of $totalUsers completed" -PercentComplete ($i/$totalUsers*100)
Start-Sleep -Seconds 5 # Brief pause between batches
}