Active Directory Locked out Users Auto-Locking Command to run every 15 Mins

Brass Contributor

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 = ""

$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)]
[Parameter(Mandatory = $true)]

# 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" = ""
"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



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.

0 Replies