Tools · Windows security and Event Logs · 11 / 27
How to investigate Remote Desktop logons: Event IDs 1149, 4624 type 10, 21, 24, and 25
Reconstruct RDP sessions across the Security and TerminalServices logs: connection, authentication, logon, disconnect, and reconnect.
Three logs tell the story
Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational Event 1149 records a network connection that passed authentication, with the user and source address. The Security log records 4624 with Logon Type 10 for a new RDP session, or Type 7 when reconnecting to an existing one, plus 4778 for reconnect and 4779 for disconnect. Microsoft-Windows-TerminalServices-LocalSessionManager/Operational records 21 (session logon), 22 (shell start), 24 (disconnected), and 25 (reconnected).
Using all three gives you the source, the account, the session ID, and the session’s lifetime even if one log has rolled over.
Network Level Authentication and failures
With Network Level Authentication enabled, credentials are checked before a desktop session is built, and failures appear as 4625 with Logon Type 3 rather than 10, because NLA uses a network logon first. That surprises many analysts who search for type 10 failures and find none.
RDP guessing therefore shows as many 4625 type 3 events on a host with 3389 exposed, often from internet addresses.
Lab: reconstruct a session
Connect to a Windows lab VM with RDP from another VM, disconnect without logging off, reconnect, then log off. Query all three logs for the last hour and merge them into one timeline sorted by time.
You should see 1149, 4624 type 10, 21, 22, then 24 and 4779 for the disconnect, 25 and 4778 for the reconnect, and 23 for logoff.
$s=(Get-Date).AddHours(-1)
$a = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational'; Id=1149; StartTime=$s}
$b = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'; Id=21,22,23,24,25; StartTime=$s}
$c = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624,4778,4779; StartTime=$s} | Where-Object { $_.Id -ne 4624 -or $_.Properties[8].Value -in 7,10 }
$a+$b+$c | Sort-Object TimeCreated | Select TimeCreated, Id, LogName | Format-Table -AutoSizeDefending RDP
Do not expose RDP directly to the internet. Use a VPN or Remote Desktop Gateway with MFA, enable NLA, restrict RDP with firewall scope to admin hosts, and add users to Remote Desktop Users deliberately rather than granting it to Domain Users.
Alert on 1149 from addresses outside your management ranges and on type 10 logons by accounts that do not normally use RDP.
Diagram
One RDP session across three logs
- 1149
RemoteConnectionManager: user authenticated from a source address.
- 4624 type 10
Security: a new remote interactive session.
- 21 / 22
LocalSessionManager: session logon and shell start.
- 24 / 25 / 23
Disconnect, reconnect, and logoff.
Check yourself
1. Which event records an RDP connection that passed authentication, with the source address?
2. With NLA enabled, failed RDP passwords appear as which event and type?
3. Which LocalSessionManager event marks a disconnect?