Forum Discussion
Active Directory Locked out Users Auto-Locking Command to run every 15 Mins
My Requirement:
I want to view all On-premises AD Locked out users every 15 minutes. I want them to be exported to a CSV file with the proper time and date mentioned in the file name. I want this CSV file to get copied to my OneDrive. Also, I want this confirmation in an email with an attachment and on MS Teams.
Must haves: Active Directory Access, Active Directory Local Application, Incoming Web-hook URL(for MS Teams Message), Sender Email ID with password, Recipient Email ID, Proper OneDrive Synced path for CSV file.
The command that matched my expectations:
Step 1: Open PowerShell ISE & run,
Import-Module Active Directory
Step 2: Run the below-mentioned command through a text file in PowerShell ISE.
while($true) {
# Get the current date in UTC
$utcNow = (Get-Date).ToUniversalTime()
# Define the IST offset
$istOffset = New-TimeSpan -Hours 5 -Minutes 30
# Calculate the current date in IST
$istNow = $utcNow + $istOffset
# Format the IST timestamp
$timestamp = $istNow.ToString("yyyy-MM-dd_HH-mm")
# Define filename with timestamp, give the csv path as OneDrive synced folder
$csvPath = "csv-path\LockedOutUsers_$timestamp.csv"
# Get AD-locked users and select the required properties
$lockedUsers = Search-ADAccount -LockedOut -UsersOnly | Select-Object Name, UserPrincipalName, SamAccountName, Lockedout
Search-ADAccount -LockedOut -UsersOnly | Unlock-ADAccount
# Export the locked users to a CSV file
$lockedUsers | Export-Csv -Path $csvPath -NoTypeInformation
# Define the parameters for the email
$emailSmtpServer = "smtp.office365.com"
$emailSmtpServerPort = "587"
$emailSmtpUser = "Sender Email ID"
$emailSmtpPass = "Password"
$emailFrom = "Microsoft 365 Assistant <$emailSmtpUser>"
$emailTo = "Your Email ID"
$emailSubject = "Account Lockedout Users' Report @ $timestamp"
$emailBody = "Dear Venkat Sir,
Please find the AD Account Lockedout users' report attached. For your information, please.
We've successfully unlocked all of them.
Best Regards,
Microsoft365 Admin."
$emailAttachments = $csvPath
# Send the email
Send-MailMessage -To $emailTo -From $emailFrom -Subject $emailSubject -Body $emailBody -SmtpServer $emailSmtpServer -port $emailSmtpServerPort -UseSsl -Credential (New-Object System.Management.Automation.PSCredential ($emailSmtpUser, (ConvertTo-SecureString $emailSmtpPass -AsPlainText -Force))) -Attachments $emailAttachments
$csvContent = Get-Content -Path "$csvPath" -Raw
# Define the webhook URL
$webhookUrl = 'your webhook url'
function Send-TeamsMessage {
param (
[Parameter(Mandatory = $true)]
[String]$WebhookURL,
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[String]$CsvContent
)
# Convert the CSV content back to PowerShell objects
$users = $CsvContent | ConvertFrom-Csv
# Build a clearer message from the user objects
$messageText = "Locked Out Users Report:`r`n`r`n"
foreach ($user in $users) {
$messageText += "- **Name**: $($user.Name)`r`n"
$messageText += " **UPN**: $($user.UserPrincipalName)`r`n"
$messageText += " **SAM**: $($user.SamAccountName)`r`n`r`n"
}
# Structure the payload for Teams
$body = @{
"@type" = "MessageCard"
"@context" = "http://schema.org/extensions"
"summary" = "Locked Out Users Report"
"title" = "AD Account Locked Out Users Report"
"text" = $messageText
} | ConvertTo-Json
$headers = @{
"Content-Type" = "application/json"
}
Invoke-RestMethod -Method Post -Uri $WebhookURL -Body $body -Headers $headers
}
Send-TeamsMessage -WebhookURL $webhookUrl -CsvContent $csvContent
# Wait for 15 minutes (900 seconds)
Start-Sleep -Seconds 900
}
Conclusion:
To stop this process, need to stop the operation on PowerShell ISE else we need to close the PowerShell ISE else we need to re-start the system. It will run forever if this isn't stopped.
Reference Email Screenshot:
Reference MS Teams Message Screenshot:
Best Regards,
Venkat Kiran Kona.