Files
powershell/rdp_login_success_script_new.ps1
2026-03-02 17:23:13 +08:00

179 lines
7.9 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 服务器登录监控脚本 - 完整版监控所有RDP相关登录类型
# 监控远程桌面登录并通过钉钉机器人推送通知(支持加签)
param (
[string]$DingTalkWebhookUrl = "https://oapi.dingtalk.com/robot/send?access_token=d28bd09159097d9cc5793a183990927ce637bd8addafb5e4586e2687ca317039",
[string]$DingTalkSecret = "SECd4bf3fb7703bd2826896deefa68d579e9945a67058ee9047ac5f8757ae800729"
)
# 钉钉消息发送函数(支持加签)
function Send-DingTalkMessage {
param(
[string]$消息内容
)
try {
# 计算签名
$timestamp = [DateTimeOffset]::Now.ToUnixTimeMilliseconds()
$stringToSign = "$timestamp`n$DingTalkSecret"
$hmacsha = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha.key = [Text.Encoding]::UTF8.GetBytes($DingTalkSecret)
$signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
$signatureBase64 = [Convert]::ToBase64String($signature)
$encodedSignature = [System.Net.WebUtility]::UrlEncode($signatureBase64)
# 完整的请求URL
$fullUrl = "$DingTalkWebhookUrl&timestamp=$timestamp&sign=$encodedSignature"
$body = @{
msgtype = "text"
text = @{
content = $消息内容
}
} | ConvertTo-Json -Depth 10
$response = Invoke-RestMethod -Uri $fullUrl -Method Post -Body $body -ContentType "application/json; charset=utf-8"
Write-Host "✓ 钉钉消息发送成功: $($response.errmsg)" -ForegroundColor Green
} catch {
Write-Error "✗ 钉钉消息发送失败: $_"
}
}
# 登录类型说明
$登录类型说明 = @{
"2" = "交互式登录(本地控制台)"
"3" = "网络登录含NLA身份验证"
"4" = "批处理(计划任务)"
"5" = "服务登录"
"7" = "会话解锁"
"8" = "网络明文如IIS基本认证"
"9" = "新凭证RunAs"
"10" = "远程交互RDP无NLA"
"11" = "缓存交互(域凭据缓存)"
}
# 程序启动信息
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " 服务器登录监控服务已启动" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "服务器名称: $env:COMPUTERNAME" -ForegroundColor Yellow
Write-Host "启动时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Yellow
Write-Host "监控类型: 所有远程桌面相关登录类型3、7、10" -ForegroundColor Yellow
Write-Host "检查间隔: 5秒" -ForegroundColor Yellow
Write-Host "========================================" -ForegroundColor Cyan
# 记录上次检查的时间
$上次检查时间 = (Get-Date).AddHours(-1)
# 记录已发送过的登录事件,避免重复通知
$已通知事件 = @{}
# 主循环
while ($true) {
try {
# 获取新的登录事件Event ID 4624
$事件列表 = Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4624
StartTime = $上次检查时间
} -ErrorAction SilentlyContinue
foreach ($事件 in $事件列表) {
# 解析事件XML
$事件Xml = [xml]$事件.ToXml()
# 获取登录类型
$登录类型 = ($事件Xml.Event.EventData.Data | Where-Object {$_.Name -eq "LogonType"}).'#text'
# 监控所有可能的远程桌面相关登录类型3(NLA验证)、7(解锁)、10(传统RDP)
if ($登录类型 -eq "3" -or $登录类型 -eq "7" -or $登录类型 -eq "10") {
# 获取登录信息
$用户名 = ($事件Xml.Event.EventData.Data | Where-Object {$_.Name -eq "TargetUserName"}).'#text'
$域名 = ($事件Xml.Event.EventData.Data | Where-Object {$_.Name -eq "TargetDomainName"}).'#text'
$来源IP = ($事件Xml.Event.EventData.Data | Where-Object {$_.Name -eq "IpAddress"}).'#text'
$登录时间 = $事件.TimeCreated
$记录ID = $事件.RecordId
$登录GUID = ($事件Xml.Event.EventData.Data | Where-Object {$_.Name -eq "LogonGuid"}).'#text'
# 过滤本地IP和无效IP
$有效IP = $来源IP -and $来源IP -ne "127.0.0.1" -and $来源IP -ne "::1" -and $来源IP -ne "-"
if ($有效IP) {
# 生成唯一标识,避免重复通知
$事件标识 = "$记录ID-$来源IP-$用户名"
if (-not $已通知事件.ContainsKey($事件标识)) {
# 清理过旧的记录,避免内存溢出
if ($已通知事件.Count -gt 1000) {
$已通知事件.Clear()
}
# 处理空域名
if ([string]::IsNullOrEmpty($域名) -or $域名 -eq "-") {
$域名 = $env:COMPUTERNAME
}
# 获取登录类型说明
$类型说明 = if ($登录类型说明.ContainsKey($登录类型)) {
$登录类型说明[$登录类型]
} else {
"未知类型($登录类型)"
}
# 添加额外说明
$额外说明 = ""
if ($登录类型 -eq "3") {
$额外说明 = "使用NLA验证的RDP连接"
} elseif ($登录类型 -eq "7") {
$额外说明 = "(远程会话解锁)"
} elseif ($登录类型 -eq "10") {
$额外说明 = "传统RDP连接"
}
# 构建钉钉消息
$消息内容 = @"
🏢 $env:COMPUTERNAME
📅 $($登录时间.ToString('yyyy-MM-dd HH:mm:ss'))
👤 $域名\$用户名
🔑 $类型说明 $额外说明
🌐 IP$来源IP
📝 ID$记录ID
"@
# 显示日志
Write-Host "`n[$(Get-Date -Format 'HH:mm:ss')] 检测到新的远程登录" -ForegroundColor Yellow
Write-Host " 用户: $域名\$用户名" -ForegroundColor White
Write-Host " 类型: $类型说明 $额外说明" -ForegroundColor Cyan
Write-Host " 来源IP: $来源IP" -ForegroundColor White
Write-Host " 时间: $($登录时间.ToString('HH:mm:ss'))" -ForegroundColor White
# 发送钉钉通知
Send-DingTalkMessage -消息内容 $消息内容
# 记录已通知
$已通知事件[$事件标识] = $true
}
}
}
}
# 更新上次检查时间
$上次检查时间 = Get-Date
# 显示运行状态每5分钟显示一次
if (((Get-Date).Minute % 5) -eq 0 -and (Get-Date).Second -lt 5) {
Write-Host "[$(Get-Date -Format 'HH:mm:ss')] 监控运行中,已监控到 $($已通知事件.Count) 次登录" -ForegroundColor Gray
}
# 等待5秒后继续检查
Start-Sleep -Seconds 5
} catch {
Write-Error "监控过程发生错误: $_"
Write-Host "等待10秒后重试..." -ForegroundColor Red
Start-Sleep -Seconds 10
}
}