Błąd RDP: odblokowanie zablokowanego konta Windows (PowerShell)
Zablokowane konto Windows przy logowaniu RDP to zwykle skutek zautomatyzowanych ataków. Ten skrypt PowerShell odblokuje konto, pokaże źródłowe adresy IP i dostosuje zasady blokady.
Twoje logowanie przez Pulpit zdalny nagle przestaje działać, a Windows wyświetla mniej więcej taki komunikat: „Ze względów bezpieczeństwa konto użytkownika zostało zablokowane, ponieważ podjęto zbyt wiele prób logowania lub prób zmiany hasła.” Zadziałały wtedy zasady blokady konta systemu Windows. Przyczyna jest prawie zawsze ta sama: ktoś albo coś bombarduje twój dostęp RDP próbami logowania z internetu.
W tym poradniku pokazujemy, jak odblokować konto, jak ustalić, które adresy IP wywołują blokady, oraz jak zmienić albo całkiem wyłączyć zasady blokady. Wszystko to załatwia jeden skrypt PowerShell, bez klikania w edytorze zasad grupy.
Dlaczego konto Windows zostaje zablokowane przy logowaniu RDP?
Windows liczy nieudane próby logowania i blokuje konto, gdy tylko zostanie osiągnięty ustawiony próg. Ta funkcja ochronna ma sens, ale staje się problemem w chwili, gdy port RDP jest wystawiony na internet: zautomatyzowane boty przez całą dobę próbują wtedy kolejnych haseł i blokują przy okazji dokładnie to konto, na którym chcesz pracować.
Zachowanie blokady określają trzy wartości:
- Próg blokady: liczba nieudanych prób, po której konto zostaje zablokowane
- Czas trwania blokady: liczba minut, przez które konto pozostaje zablokowane
- Okno obserwacji: liczba minut, w ciągu których nieudane próby są sumowane
Otwórz PowerShell jako administrator
Otwórz Windows PowerShell jako administrator. Kliknij w menu Start prawym przyciskiem myszy pozycję „Windows PowerShell” i wybierz „Uruchom jako administrator”. Bez podwyższonych uprawnień skrypt nie odblokuje konta ani nie zmieni zasad.
Skrypt: odblokowanie konta i namierzenie atakujących
W sekcji „Ustawienia” dopasuj nazwę konta oraz wybrane wartości, a następnie wklej skrypt do PowerShella:
#Requires -RunAsAdministrator
# KernelHost: odblokowanie zablokowanego konta Windows RDP i znalezienie przyczyny
# Uruchamiaj w Windows PowerShell jako administrator.
# ----------------------------------------------------------------------------
# Ustawienia: dopasuj do swojego środowiska
# ----------------------------------------------------------------------------
$Username = 'Administrator' # konto lokalne, które ma zostać odblokowane
$ApplyPolicy = $true # $false, jeśli zasady blokady mają pozostać bez zmian
$LockoutThreshold = 0 # nieudane próby do blokady (0 = blokada WYŁĄCZONA, patrz tekst)
$LockoutDuration = 15 # minuty, przez które konto pozostaje zablokowane
$LockoutWindow = 15 # minuty, w ciągu których liczone są nieudane próby
# ----------------------------------------------------------------------------
# 1) Pokaż aktualne zasady blokady
Write-Host "`n=== 1) Aktualne zasady blokady ===" -ForegroundColor Cyan
net accounts | Select-String 'Lockout|Sperr'
# 2) Odblokuj konto
Write-Host "`n=== 2) Odblokowanie konta '$Username' ===" -ForegroundColor Cyan
try {
$user = [ADSI]"WinNT://$env:COMPUTERNAME/$Username,user"
if ($user.InvokeGet('IsAccountLocked')) {
$user.InvokeSet('IsAccountLocked', $false)
$user.SetInfo()
Write-Host " Konto '$Username' było zablokowane i jest teraz ODBLOKOWANE." -ForegroundColor Green
} else {
Write-Host " Konto '$Username' nie jest zablokowane." -ForegroundColor Yellow
}
} catch {
Write-Warning " Nie udało się odblokować konta '$Username': $($_.Exception.Message)"
}
# 3) Opcjonalnie: dostosuj lub wyłącz zasady blokady
if ($ApplyPolicy) {
Write-Host "`n=== 3) Ustawianie zasad blokady ===" -ForegroundColor Cyan
if ($LockoutThreshold -eq 0) {
net accounts /lockoutthreshold:0 | Out-Null
Write-Host " Blokada konta WYŁĄCZONA (próg 0)." -ForegroundColor Yellow
Write-Host " Ogranicz teraz RDP na firewallu do własnego adresu IP." -ForegroundColor Yellow
} else {
net accounts /lockoutthreshold:$LockoutThreshold /lockoutduration:$LockoutDuration /lockoutwindow:$LockoutWindow | Out-Null
Write-Host " Próg=$LockoutThreshold Czas=$LockoutDuration min Okno=$LockoutWindow min" -ForegroundColor Green
}
}
# 4) Kto wywołuje blokady? (źródła ataków na RDP)
Write-Host "`n=== 4a) Ostatnie zdarzenia blokady (Security-ID 4740) ===" -ForegroundColor Cyan
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4740} -MaxEvents 10 -ErrorAction SilentlyContinue |
ForEach-Object {
$x = [xml]$_.ToXml()
[pscustomobject]@{
Czas = $_.TimeCreated
ZablokowaneKonto = ($x.Event.EventData.Data | Where-Object { $_.Name -eq 'TargetUserName' }).'#text'
Źródło = ($x.Event.EventData.Data | Where-Object { $_.Name -eq 'TargetDomainName' }).'#text'
}
} | Format-Table -AutoSize
Write-Host "=== 4b) Najczęstsze źródłowe adresy IP nieudanych logowań, ostatnie 24 h (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='IP źródłowe'; E={$_.Name}} -AutoSize
Co dokładnie robi ten skrypt
- Pokazuje poleceniem
net accountsaktualne zasady blokady konta, czyli próg, czas trwania blokady i okno obserwacji. - Odblokowuje konto wpisane w
$Username, korzystając z dostawcy katalogu WinNT. To odpowiednik poleceniaUnlock-ADAccountdla kont lokalnych. - Dostosowuje zasady, o ile
$ApplyPolicyma wartość$true. Przy wartościach domyślnych blokada staje się mniej agresywna, a przy$LockoutThreshold = 0wyłączasz ją całkowicie. - Wypisuje ostatnie zdarzenia blokady (identyfikator zdarzenia 4740) oraz najczęstsze źródłowe adresy IP nieudanych logowań z ostatnich 24 godzin (identyfikator zdarzenia 4625). To adresy, z których atakowany jest twój dostęp RDP.
Uwaga o języku: w zlokalizowanej wersji systemu Windows polecenie net accounts wypisuje wartości pod przetłumaczonymi etykietami. Dlatego skrypt powyżej filtruje zarówno po „Lockout”, jak i po „Sperr”. W polskiej wersji dopisz do wzorca wyszukiwania jeszcze „blokad”.
Konto lokalne czy konto domenowe?
Skrypt obsługuje konto lokalne, czyli typowy przypadek na pojedynczym serwerze VPS albo serwerze root. Jeśli masz do czynienia z kontem domenowym albo pracujesz na kontrolerze domeny, odblokuj je zamiast tego poleceniem:
Unlock-ADAccount -Identity <nazwa_użytkownika>
Dostosowanie lub wyłączenie progu blokady
Skrypt domyślnie ustawia próg na 0 i tym samym wyłącza blokadę konta. Na pierwszy rzut oka brzmi to jak błąd, ale przy dostępie RDP otwartym na internet jest to lepszy wybór. Powód: atakujący wcale nie musi odgadnąć twojego hasła. Wystarczy, że co kilka minut wyśle kilka błędnych prób, a konto pozostanie zablokowane na stałe. Blokada uderza wtedy nie w niego, tylko wyłącznie w ciebie. Z funkcji ochronnej robi się wygodne narzędzie do trzymania cię z dala od własnego serwera.
Ważne: wyłączenie blokady nie zastępuje ochrony, usuwa tylko tę niewłaściwą. Ochrona przed masowym testowaniem haseł należy o poziom niżej, czyli do firewalla: jeśli RDP jest osiągalne wyłącznie z twojego własnego adresu IP, żaden atakujący nie dojdzie już do ekranu logowania i nie będzie czego liczyć. Wykonaj więc kroki z następnego rozdziału, zanim wyłączysz blokadę, a nie po fakcie.
Jeśli ze względów operacyjnych musisz zostawić RDP otwarte dla zmieniających się adresów, ustaw zamiast tego wysoki próg i krótki czas blokady, na przykład $LockoutThreshold = 50 i $LockoutDuration = 5. Zostaje dzięki temu trochę efektu hamującego, a przy każdym skanowaniu nie odcinasz sobie dostępu do serwera. W domenie z wewnętrznym RDP nadal obowiązuje klasyczne zalecenie niskiego progu, bo tam dostęp i tak nie jest osiągalny z internetu.
Usuń przyczynę: trwałe zabezpieczenie RDP
Zablokowane konto to tylko objaw. Właściwą przyczyną jest dostęp RDP otwarty dla całego internetu. Te cztery działania usuwają problem u źródła.
Ogranicz RDP do własnego adresu IP
To zdecydowanie najskuteczniejsze działanie. Jeśli RDP jest osiągalne tylko z twojego adresu, wszystkie zautomatyzowane ataki trafiają w próżnię:
# Zezwól na przychodzące RDP tylko z własnego adresu IP
Set-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' -RemoteAddress '203.0.113.5'
Podana nazwa wyświetlana obowiązuje w anglojęzycznym systemie Windows. W systemie zlokalizowanym, po polsku tak samo jak po niemiecku, brzmi ona inaczej. Istniejące reguły i ich dokładne nazwy wypiszesz poleceniem Get-NetFirewallRule -DisplayGroup 'Pulpit zdalny'.
Zablokuj pojedynczy adres IP atakującego
Dla adresów, które wypisuje krok 4b skryptu, utwórz osobną regułę blokującą:
New-NetFirewallRule -DisplayName 'Block RDP attacker 203.0.113.9' -Direction Inbound -Action Block -RemoteAddress '203.0.113.9'
Pomaga to na pojedyncze, uparte źródła, ale nie zastępuje ograniczenia do własnego adresu IP, bo atakujący cały czas używają nowych adresów.
Zmień port RDP
Jeśli RDP nie nasłuchuje już na domyślnym porcie 3389, typowe masowe skany w ogóle nie znajdą twojej usługi. Jak przestawić port bez restartu serwera, pokazuje nasz poradnik Zmiana portu RDP w systemie Windows bez restartu.
Silne hasło i Network Level Authentication
Używaj długiego, losowego hasła i zostaw włączone Network Level Authentication (NLA). NLA wymaga uwierzytelnienia, zanim w ogóle powstanie sesja, i odsiewa dzięki temu dużą część zautomatyzowanych prób już na wstępie.
Najczęstsze pytania
Dlaczego moje konto Windows zostaje zablokowane przy logowaniu RDP?
Jak długo zablokowane konto pozostaje zablokowane?
Czy powinienem całkiem wyłączyć blokadę konta?
Jak sprawdzić, które adresy IP blokują moje konto?
Skrypt nie odblokowuje mojego konta, z czego to wynika?
2026 KernelHost GmbH. Wszelkie prawa zastrzeżone. Ten poradnik jest chroniony prawem autorskim. Publikowanie go w innych serwisach, w całości, we fragmentach lub w zmienionej formie, wymaga naszej pisemnej zgody. Cytaty z podaniem źródła i z linkiem są jak najbardziej mile widziane.

