Nine in the morning, and you haven’t sat down yet. Twelve lockouts. Three people who can’t see the share. One bloke who’s certain the network’s down.
I worked that queue for years the slow way — Active Directory Users and Computers open, one account at a time, right-click, unlock, next. Nobody handed me a list. I built it by getting sick of clicking.
These are the seven lines that clear a help desk morning. Not the flashiest PowerShell you’ll see this week — the ones I actually ran, in the order the tickets arrive. Each one is a single line, and each one replaces something you’re currently doing with a mouse.
Follow along the video – https://youtu.be/qNxOl7xFjNM
Why one-liners and not scripts
Because a script is something you write once and then can’t find in six months. A one-liner is something you remember.
The commands below aren’t a toolkit you install. They’re muscle memory. The skill isn’t memorising all seven — it’s recognising which ticket each one belongs to. Get that mapping right and you stop troubleshooting by feel.
Which box do you run these on?
This matters more than any install step, and it’s the thing most write-ups skip.
Four of them run on the domain controller — #1, #2, #4 and #5 all ask Active Directory a question, so run them where Active Directory already lives. In a lab that’s simplest: RDP to the DC and work there.
Three of them run where the problem is. #3 you run from the client, because the whole point is testing the path from where the user is sitting. #6 runs from anywhere and targets the workstation. #7 runs on the machine you’re auditing.
If you’d rather drive everything from a client VM, that’s when you need RSAT:
# Only needed if you're running the AD commands from a client, not the DC
Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
Import-Module ActiveDirectory
Everything below runs in my lab: domain trevtech.lab, DC01 as the domain controller, bwayne as the test user, WS01 as the workstation.
1. Clear the entire lockout queue
# Every locked user account in the domain — unlocked
Search-ADAccount -LockedOut -UsersOnly | Unlock-ADAccount
The ticket: it’s 9am on a Monday and the queue is full of lockouts. Usually the Monday after a password policy change.
Read the list before you run it. Get the names on screen first:
Search-ADAccount -LockedOut -UsersOnly | Select-Object Name, SamAccountName, LastLogonDate
Four names, four different people — that’s a normal Monday. Forty names is not forty people fat-fingering a password; that’s a policy change, a service account hammering a stale credential, or something walking the domain. Don’t unlock that. Go and find out what did it.
Then, once you’re happy with the list, pipe it. And read the command again before you do — it unlocks every locked account in the domain.
Most days that’s fine — the 9am sweep is exactly what you want. But know which one you’re running:
# One account only
Unlock-ADAccount -Identity bwayne
# Or see what you're about to unlock before you do it
Search-ADAccount -LockedOut -UsersOnly | Select-Object Name, SamAccountName, LastLogonDate
-UsersOnly matters too — without it you’re including computer accounts in the search.
2. Is it the password, or is it the account?
# The three properties that tell you which story you're in
Get-ADUser bwayne -Properties LastBadPasswordAttempt, badPwdCount, PasswordLastSet, LockedOut |
Format-List Name, LockedOut, PasswordLastSet, badPwdCount, LastBadPasswordAttempt
The ticket: the same person, locked out for the third time this week.
I unlocked Bruce on Monday. I unlocked him again Tuesday. Wednesday I unlocked him and told him to slow down when he typed it. By Thursday I’d stopped believing him.
He wasn’t typing it wrong. His phone was.
Three properties decode it:
- PasswordLastSet — if that’s this morning, something on his kit is still holding the old one.
- badPwdCount — the running tally of failed attempts.
- LastBadPasswordAttempt — a timestamp that keeps moving while he’s sitting in front of you doing nothing is not a man mistyping.
The gotcha nobody mentions: badPwdCount is not replicated between domain controllers. Each DC maintains its own count independently. Ask the wrong one and it’ll happily tell you everything’s fine. It’s like asking a single checkout how many times the card got declined when they tried every till in the shop.
3. Is the domain controller actually answering?
# Port 389 = LDAP. This is the question every domain-joined machine asks.
Test-NetConnection dc01.trevtech.lab -Port 389
The ticket: the user says it’s broken, the app team says it’s the network, the network team says it’s the app, and you’re the one holding it.
Run this one from the client, not the DC — you want the answer from where the problem is.
Ping tells you the lights are on. A port test tells you somebody answers the door.
And that distinction matters more than it sounds: plenty of places block ICMP — that’s ping — on principle. The ping fails, everyone panics, and the server was fine the whole time.
TcpTestSucceeded : True means the DC is up, listening, and the problem is not the network — go look at the app. False gives the network team something that isn’t a feeling.
And because you passed a hostname rather than an IP, you just tested DNS resolution on the way through. Two answers, one line.
4. He’s in the group. So why can’t he see the share?
Get-ADPrincipalGroupMembership bwayne | Select-Object Name
The ticket: you added him to IT-Admins an hour ago. He still can’t open the folder.
The command confirms he’s in the group. He is. The permission is right. And it still doesn’t work — which is where most people start doubting the file server.
Here’s why. His access token was built when he logged on. Adding him to a group afterwards changes Active Directory; it does not change the token sitting on his machine. It’s the wristband at the door — he’s on the list now, but he’s still wearing yesterday’s band.
Log off, log back on. Not a reboot for the sake of it — a fresh logon, so Windows builds a new token.
To prove it before you make him do it, run this on his machine:
whoami /groups
That’s what he’s actually carrying right now.
5. What is actually locking him out
# The last 5 lockout events — run this against the PDC emulator
Get-WinEvent -ComputerName (Get-ADDomain).PDCEmulator -FilterHashtable @{LogName='Security';ID=4740} -MaxEvents 5 |
Select-Object TimeCreated,
@{n='LockedAccount'; e={$_.Properties[0].Value}},
@{n='CallerComputer';e={$_.Properties[1].Value}}
The ticket: the one that keeps coming back.
I unlocked that account every morning for a fortnight. I reset his password. I checked his laptop. I blamed his laptop. I made him change it to something he could not possibly mistype.
It was his iPad. In a kitchen drawer. With the old password saved on the wifi, retrying every few minutes.
Event ID 4740 is the account lockout event, and the field that matters is Caller Computer Name — the device holding the old credential. Not the account. The device. That field is the entire reason this command exists.
Then read the timestamps. Four minutes apart. Then four. Then four. A person doesn’t retry on a schedule — that’s a device with a saved password and a retry timer. If the intervals are irregular and clustered around the times he says he tried, you’re looking at a human after all.
Two things will give you an empty list:
- You queried the wrong DC. Lockouts are processed by the PDC emulator, and that’s where the event lands.
(Get-ADDomain).PDCEmulatorfinds it for you. - Account management auditing isn’t enabled. That’s a Group Policy setting.
6. Fix it without walking to the desk
Invoke-Command -ComputerName WS01 -ScriptBlock { gpupdate /force }
The ticket: the policy isn’t applying, and the user is on the far side of the building.
This needs WinRM enabled on the target. Enable-PSRemoting -Force and a firewall rule. If it isn’t on, the command fails and the error won’t tell you why in plain English — which is exactly the wall a beginner hits and gives up at.
Read what comes back. “Computer Policy update has completed successfully” is a pass. “The following warnings were encountered” is not — that’s your next twenty minutes, and the detail is in the Group Policy operational log.
There’s a second door most people don’t know about:
Invoke-GPUpdate -Computer WS01 -Force
Invoke-GPUpdate doesn’t use WinRM at all. It schedules the gpupdate as a task on the remote machine over RPC, which needs the Remote Scheduled Tasks Management and WMI firewall rules instead. Different requirement, different rules — and it works in plenty of environments where WinRM is locked down.
Then prove it took:
gpresult /r /s WS01
Look for Applied Group Policy Objects. Your GPO is either in that list or it isn’t. There’s no arguing with that, which is exactly why it’s worth pasting into the ticket.
7. The audit nobody asks for until they do
Get-LocalGroupMember -Group Administrators
The ticket: there isn’t one. Until there is.
I once inherited a site where every workstation had the same local admin password. Nobody thought that was strange. It was written on a sticky note in the comms room.
One line tells you who actually has admin on a machine. Wrap it in Invoke-Command and you have it across the fleet:
Invoke-Command -ComputerName WS01, WS02, WS03 -ScriptBlock { Get-LocalGroupMember -Group Administrators } |
Select-Object PSComputerName, Name, PrincipalSource
The column nobody looks at is PrincipalSource. ActiveDirectory means a domain group — fine, that’s how it’s meant to work. Local means an account living on that machine and only that machine. That’s the sticky note: nobody rotates it, nobody audits it, and nobody remembers creating it.
You’ll find the contractor from 2019. You’ll find Domain Users, which should stop your heart. You’ll find a name nobody recognises.
One honest note: on a machine with an orphaned SID in that group — someone deleted from the domain years ago — the cmdlet throws Failed to compare two elements in the array and returns nothing at all. It’s a long-standing known bug, not something you did. Fall back to:
net localgroup administrators
and you’ll see the raw S-1-5-21-… string sitting there. That’s your finding.
The field that actually decides it
Knowing the command is the easy half. This is the half nobody teaches:
| # | Command | The field to read | What it’s telling you |
|---|---|---|---|
| 1 | Search-ADAccount -LockedOut | the list length | 4 names = Monday. 40 = an incident, don’t sweep it. |
| 2 | Get-ADUser | LastBadPasswordAttempt | Still moving while he stands at your desk = a device, not a typo. |
| 3 | Test-NetConnection | RemoteAddress, then TcpTestSucceeded | DNS resolved to the right IP; then whether anyone answers. |
| 4 | whoami /groups vs AD | presence of the group | AD says yes, token says no = he needs a fresh logon. |
| 5 | Get-WinEvent 4740 | Caller Computer Name, then the interval | Which device holds the old credential — and a retry timer proves it’s not a person. |
| 6 | gpresult /r /s | Applied Group Policy Objects | Whether your GPO actually landed, not whether the command ran. |
| 7 | Get-LocalGroupMember | PrincipalSource | Local = an unmanaged account on that box. That’s the finding. |
The gotchas, all in one place
| # | Gotcha |
|---|---|
| 1 | Search-ADAccount -LockedOut | Unlock-ADAccount unlocks the whole domain. Use -Identity for one account. |
| 2 | badPwdCount is not replicated — it’s per-DC. Query the right one. |
| 3 | Know which box each one runs on — four on the DC, three where the problem is. RSAT only if you’re driving from a client. |
| 4 | Group membership changes need a fresh logon, not a reboot. |
| 5 | Event 4740 lives on the PDC emulator, and only if account management auditing is on. |
| 6 | Invoke-Command needs WinRM. Invoke-GPUpdate doesn’t — it uses scheduled tasks over RPC. |
| 7 | Get-LocalGroupMember fails silently on orphaned SIDs. Fall back to net localgroup administrators. |
Is it worth learning these cold?
Yes — and not because seven commands make you a sysadmin. They won’t.
They’re worth it because they change how you talk about a ticket. There’s a real difference between “he’s locked out again, I’ve unlocked him” and “he’s locked out again, 4740 says it’s coming from a device that isn’t his laptop, so I need five minutes with his phone.” The first one closes a ticket. The second one ends it.
That difference is also, in my experience, the difference between sounding like someone who’s read about help desk and someone who’s worked it. Walk into an interview and say you check bad password count before you reset anything, that you pull 4740 off the PDC to find the device, that you know a group change needs a fresh logon — and the conversation changes.
The certs get you the interview. This gets you through the first week.
What’s next
There’s a video walking through all seven in the lab — every command run against a live domain, the real output held on screen, and the field that decides each ticket called out as it goes. The 4740 event gets frozen with an arrow on Caller Computer Name. It’s linked below.
If the machine in front of the user is the problem rather than the domain, I’ve got a separate list of nine CMD commands that covers that side of the queue.
Tags: powershell, active directory, windows server, help desk, sysadmin, enterprise IT, homelab
— Trev | I broke it. Fixed it.

