Wissensdatenbank

Fix or Disable the Windows RDP "Account Locked Out" Error (via PowerShell)

If your Remote Desktop (RDP) login suddenly fails with a message like "As a security precaution, the user account has been locked out because there were too many logon attempts or password change attempts", the account hit the Windows Account Lockout Policy – almost always because someone (or a bot) brute-forced your RDP from the internet.

In this guide, we'll show you how to unlock the account, see which IP addresses are triggering the lockouts, and adjust (or disable) the lockout policy – all from a single PowerShell script, without clicking through the Group Policy Editor.

To begin, open Windows PowerShell as Administrator (right-click "Windows PowerShell" in the Start menu → "Run as administrator") and paste the following script:

#Requires -RunAsAdministrator

# KernelHost - Fix / Unlock a locked-out Windows RDP account
# Run in Windows PowerShell as Administrator.

# ----------------------------------------------------------------------------
#  Settings - adjust to your needs
# ----------------------------------------------------------------------------
$Username = 'Administrator'   # the local account to unlock (your RDP user)

$ApplyPolicy      = $true     # set to $false to leave the lockout policy untouched
$LockoutThreshold = 10        # failed attempts before lock-out  (0 = DISABLE lock-out)
$LockoutDuration  = 15        # minutes the account stays locked
$LockoutWindow    = 15        # minutes over which failed attempts are counted
# ----------------------------------------------------------------------------

# 1) Show the current account-lockout policy
Write-Host "`n=== 1) Current account lockout policy ===" -ForegroundColor Cyan
net accounts | Select-String 'Lockout'

# 2) Unlock the account
Write-Host "`n=== 2) Unlocking '$Username' ===" -ForegroundColor Cyan
try {
    $user = [ADSI]"WinNT://$env:COMPUTERNAME/$Username,user"
    if ($user.InvokeGet('IsAccountLocked')) {
        $user.InvokeSet('IsAccountLocked', $false)
        $user.SetInfo()
        Write-Host "  '$Username' was locked and is now UNLOCKED." -ForegroundColor Green
    } else {
        Write-Host "  '$Username' is not locked." -ForegroundColor Yellow
    }
} catch {
    Write-Warning "  Could not unlock '$Username': $($_.Exception.Message)"
}

# 3) (Optional) Re-tune or disable the lockout policy
if ($ApplyPolicy) {
    Write-Host "`n=== 3) Applying lockout policy ===" -ForegroundColor Cyan
    if ($LockoutThreshold -eq 0) {
        net accounts /lockoutthreshold:0 | Out-Null
        Write-Host "  Account lockout DISABLED (threshold 0)." -ForegroundColor Yellow
        Write-Warning "  Disabling lockout is NOT recommended on internet-facing servers."
    } else {
        net accounts /lockoutthreshold:$LockoutThreshold /lockoutduration:$LockoutDuration /lockoutwindow:$LockoutWindow | Out-Null
        Write-Host "  threshold=$LockoutThreshold  duration=$LockoutDuration min  window=$LockoutWindow min" -ForegroundColor Green
    }
}

# 4) See WHO is triggering the lock-outs (RDP brute-force sources)
Write-Host "`n=== 4a) Recent lock-out events (Security ID 4740) ===" -ForegroundColor Cyan
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4740} -MaxEvents 10 -ErrorAction SilentlyContinue |
    ForEach-Object {
        $x = [xml]$_.ToXml()
        [pscustomobject]@{
            Time          = $_.TimeCreated
            LockedAccount = ($x.Event.EventData.Data | Where-Object { $_.Name -eq 'TargetUserName' }).'#text'
            CallerHost    = ($x.Event.EventData.Data | Where-Object { $_.Name -eq 'TargetDomainName' }).'#text'
        }
    } | Format-Table -AutoSize

Write-Host "=== 4b) Top source IPs of failed logons, last 24h (Security ID 4625) ===" -ForegroundColor Cyan
$since = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=$since} -ErrorAction SilentlyContinue |
    ForEach-Object {
        ([xml]$_.ToXml()).Event.EventData.Data |
            Where-Object { $_.Name -eq 'IpAddress' } | Select-Object -ExpandProperty '#text'
    } |
    Where-Object { $_ -and $_ -ne '-' } |
    Group-Object | Sort-Object Count -Descending | Select-Object -First 10 |
    Format-Table Count, @{N='SourceIP'; E={$_.Name}} -AutoSize

What this does:

  1. Prints the current account lockout policy (threshold, duration and observation window) via net accounts.

  2. Unlocks the account set in $Username using the WinNT directory provider (the local-account equivalent of Unlock-ADAccount).

  3. Optionally re-tunes the policy. Leave the defaults to make lockout less aggressive, or set $LockoutThreshold = 0 to disable lockout completely.

  4. Shows the recent lock-out events (Event ID 4740) and the top source IPs of failed logons in the last 24 hours (Event ID 4625) – i.e. the addresses brute-forcing your RDP.

Note: the script targets a local account (the typical case on a standalone vServer / root server). On a domain controller, unlock the account with Unlock-ADAccount -Identity <user> instead.

Warning: setting $LockoutThreshold = 0 turns the lockout protection off entirely. On an internet-facing server this is not recommended – without it, attackers can try unlimited passwords. Prefer a sane threshold (e.g. 10) plus the hardening below.

Stop it from happening again. A locked-out RDP account is a symptom of RDP being exposed to the whole internet. To remove the root cause, you can:

  • Restrict RDP to your own IP in the Windows Firewall (the single most effective fix):

# Allow inbound RDP only from your own IP - blocks every brute-force attempt
Set-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' -RemoteAddress '203.0.113.5'
  • Block a specific attacker IP reported in step 4b:

New-NetFirewallRule -DisplayName 'Block RDP attacker 203.0.113.9' -Direction Inbound -Action Block -RemoteAddress '203.0.113.9'


Do you have a vServer / root server and would like to have more performance? Then a look at our range of root servers couldn't hurt!

With the discount code "KernelHost-Tutorials" you also receive a 10% discount (permanent) on your tariff!

More details:

Hardware: https://www.kernelhost.com/en/hardware

Datacenter: https://www.kernelhost.com/en/datacenter

DDoS-Protection: https://www.kernelhost.com/en/ddos-protection

PrePaid: https://www.kernelhost.com/en/prepaid

Didn't the instructions help you? You can contact us here via ticket! We're here to help.

© KernelHost.com - Re-posting these instructions on your website is not permitted.

  • 0 Benutzer fanden dies hilfreich

War diese Antwort hilfreich?

Verwandte Beiträge

Änderung des RDP Ports in Windows ohne einem Server-Neustart

In dieser Anleitung zeigen wir, wie Sie über PowerShell den Remote-Desktop-Port (RDP) unter...