PowerShell 脚本:深度清理 RDP 记录与凭据

复制代码
<#
.SYNOPSIS
    深度清理远程桌面连接(RDP)的历史记录、缓存文件、保存的凭据及系统事件日志。
.DESCRIPTION
    需要以管理员权限运行。将清除以下内容:
    - 注册表中的 MRU 列表和服务器历史记录
    - Default.rdp 配置文件
    - RDP 位图缓存
    - 任务栏跳转列表
    - Windows 凭据管理器中保存的 RDP 账号密码
    - 与 RDP 相关的 Windows 事件日志
.NOTES
    文件名称: Clear-RDPHistory.ps1
    作者: muzihuaner
    运行方式: 右键单击脚本 -> "使用 PowerShell 运行"(若已设置执行策略),或手动以管理员身份运行 PowerShell 并执行脚本。
#>

#Requires -RunAsAdministrator

# 设置控制台标题
$host.UI.RawUI.WindowTitle = "深度清理远程桌面连接记录与凭据"

Write-Host "================================================" -ForegroundColor Cyan
Write-Host "       正在深度清理远程桌面连接记录与凭据...        " -ForegroundColor Cyan
Write-Host "================================================" -ForegroundColor Cyan

$errors = @()
$successCount = 0

# ------------------------------------------------------------
# 辅助函数:输出带颜色的状态信息
# ------------------------------------------------------------
function Write-Status {
    param(
        [Parameter(Mandatory=$true)]
        [string]$Message,
        [ValidateSet("Success","Warning","Error","Info")]
        [string]$Type = "Info"
    )
    switch ($Type) {
        "Success" { Write-Host "[√] $Message" -ForegroundColor Green }
        "Warning" { Write-Host "[!] $Message" -ForegroundColor Yellow }
        "Error"   { Write-Host "[×] $Message" -ForegroundColor Red }
        default   { Write-Host "[i] $Message" -ForegroundColor Gray }
    }
}

# ------------------------------------------------------------
# 1. 清理注册表:删除默认连接 MRU 列表
# ------------------------------------------------------------
Write-Host "`n[1/5] 清理注册表项..." -ForegroundColor Cyan
$regPathDefault = "HKCU:\Software\Microsoft\Terminal Server Client\Default"
if (Test-Path $regPathDefault) {
    try {
        Remove-ItemProperty -Path $regPathDefault -Name "*" -Force -ErrorAction Stop | Out-Null
        Write-Status "已清除 MRU 列表" -Type Success
        $successCount++
    } catch {
        Write-Status "清除 MRU 列表失败: $($_.Exception.Message)" -Type Error
        $errors += "MRU 列表清除失败"
    }
} else {
    Write-Status "MRU 列表不存在或已清理" -Type Warning
}

# ------------------------------------------------------------
# 2. 清理注册表:删除所有服务器历史子键并重建
# ------------------------------------------------------------
$regPathServers = "HKCU:\Software\Microsoft\Terminal Server Client\Servers"
if (Test-Path $regPathServers) {
    try {
        Remove-Item -Path $regPathServers -Recurse -Force -ErrorAction Stop
        Write-Status "已删除服务器历史记录" -Type Success
        $successCount++
    } catch {
        Write-Status "删除服务器历史记录失败: $($_.Exception.Message)" -Type Error
        $errors += "服务器历史记录删除失败"
    }
} else {
    Write-Status "服务器列表不存在或已清理" -Type Warning
}
# 重建空的 Servers 键
try {
    New-Item -Path $regPathServers -Force -ErrorAction Stop | Out-Null
    Write-Status "已重建 Servers 注册表项" -Type Success
    $successCount++
} catch {
    Write-Status "重建 Servers 注册表项失败: $($_.Exception.Message)" -Type Error
    $errors += "重建 Servers 注册表项失败"
}

# ------------------------------------------------------------
# 3. 清理文件残留(Default.rdp、位图缓存、跳转列表)
# ------------------------------------------------------------
Write-Host "`n[2/5] 清理文件残留..." -ForegroundColor Cyan

# 3.1 Default.rdp
$defaultRdp = Join-Path $env:USERPROFILE "Documents\Default.rdp"
if (Test-Path $defaultRdp) {
    try {
        Remove-Item -Path $defaultRdp -Force -ErrorAction Stop
        Write-Status "已删除 Default.rdp" -Type Success
        $successCount++
    } catch {
        Write-Status "删除 Default.rdp 失败: $($_.Exception.Message)" -Type Error
        $errors += "Default.rdp 删除失败"
    }
} else {
    Write-Status "Default.rdp 文件不存在" -Type Warning
}

# 3.2 RDP 位图缓存
$cachePath = Join-Path $env:LOCALAPPDATA "Microsoft\Terminal Server Client\Cache"
if (Test-Path $cachePath) {
    try {
        Remove-Item -Path $cachePath -Recurse -Force -ErrorAction Stop
        Write-Status "已清除 RDP 位图缓存" -Type Success
        $successCount++
    } catch {
        Write-Status "清除位图缓存失败: $($_.Exception.Message)" -Type Error
        $errors += "位图缓存清除失败"
    }
} else {
    Write-Status "位图缓存目录不存在" -Type Warning
}

# 3.3 任务栏跳转列表(RDP 固定图标的历史记录)
$jumpListPath = Join-Path $env:APPDATA "Microsoft\Windows\Recent\AutomaticDestinations"
$rdpJumpFile = "1b4dd67f29cb1962.automaticDestinations-ms"
$fullJumpFile = Join-Path $jumpListPath $rdpJumpFile
if (Test-Path $fullJumpFile) {
    try {
        Remove-Item -Path $fullJumpFile -Force -ErrorAction Stop
        Write-Status "已清除 RDP 跳转列表" -Type Success
        $successCount++
    } catch {
        Write-Status "清除跳转列表失败: $($_.Exception.Message)" -Type Error
        $errors += "跳转列表清除失败"
    }
} else {
    Write-Status "RDP 跳转列表文件不存在" -Type Warning
}

# ------------------------------------------------------------
# 4. 清理保存的凭据(cmdkey)
# ------------------------------------------------------------
Write-Host "`n[3/5] 清理保存的远程桌面凭据..." -ForegroundColor Cyan
$credentialCount = 0
try {
    $cmdkeyOutput = cmdkey /list 2>$null | Select-String -Pattern "TERMSRV/" -SimpleMatch
    foreach ($line in $cmdkeyOutput) {
        # 目标格式: "    Target: TERMSRV/192.168.1.100"
        if ($line -match 'Target:\s+(TERMSRV\/\S+)') {
            $target = $matches[1]
            cmdkey /delete:$target 2>&1 | Out-Null
            if ($LASTEXITCODE -eq 0) {
                Write-Status "已删除凭据: $target" -Type Success
                $credentialCount++
                $successCount++
            } else {
                Write-Status "删除凭据失败: $target" -Type Error
                $errors += "凭据删除失败: $target"
            }
        }
    }
    if ($credentialCount -eq 0) {
        Write-Status "未找到任何 RDP 保存的凭据" -Type Warning
    } else {
        Write-Status "共清理 $credentialCount 条凭据" -Type Success
    }
} catch {
    Write-Status "凭据清理过程出错: $($_.Exception.Message)" -Type Error
    $errors += "凭据清理异常"
}

# ------------------------------------------------------------
# 5. 清除 Windows 事件日志(高权限)
# ------------------------------------------------------------
Write-Host "`n[4/5] 清除远程桌面相关的系统日志..." -ForegroundColor Cyan
$logNames = @(
    "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational",
    "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational",
    "Security"
)
foreach ($logName in $logNames) {
    try {
        # 使用 -ErrorAction Stop 捕获清除失败的情况
        wevtutil cl $logName 2>&1 | Out-Null
        if ($LASTEXITCODE -eq 0) {
            Write-Status "已清除事件日志: $logName" -Type Success
            $successCount++
        } else {
            Write-Status "清除日志失败 (可能正在被其他进程使用): $logName" -Type Error
            $errors += "日志清除失败: $logName"
        }
    } catch {
        Write-Status "清除日志时发生异常: $($_.Exception.Message)" -Type Error
        $errors += "日志清除异常: $logName"
    }
}

# ------------------------------------------------------------
# 总结
# ------------------------------------------------------------
Write-Host "`n================================================" -ForegroundColor Cyan
if ($errors.Count -eq 0) {
    Write-Host "      深度清理完成!所有操作均已成功。       " -ForegroundColor Green
} else {
    Write-Host "      清理已完成,但出现以下警告/错误:       " -ForegroundColor Yellow
    foreach ($err in $errors) {
        Write-Host "  - $err" -ForegroundColor Red
    }
}
Write-Host "  成功操作: $successCount 项" -ForegroundColor Green
Write-Host "  建议立即注销或重启计算机以使更改完全生效。" -ForegroundColor Cyan
Write-Host "================================================" -ForegroundColor Cyan

# 暂停等待用户确认(若双击运行)
if ($host.Name -match 'ConsoleHost') {
    Write-Host "按任意键退出..." -ForegroundColor Gray
    $null = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}

如何使用

  1. 保存脚本

    将以上代码保存为 .ps1 文件,例如 Clear-RDPHistory.ps1

  2. 以管理员身份运行 PowerShell

    • 右键点击 Windows 开始菜单,选择"Windows PowerShell (管理员) "或"终端 (管理员)"。

    • 导航到脚本所在目录,执行:

      复制代码
      Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
      .\Clear-RDPHistory.ps1
    • 或者直接右键单击脚本文件,选择"使用 PowerShell 运行"(若已调整过执行策略)。

  3. 确认清理结果

    脚本会实时输出每项操作的状态,最后给出总结。若提示部分日志清除失败,属于正常现象(系统正在占用安全日志),重启后相关记录仍会消失。