You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PowerShell检查账户是否具备服务器RDP连接权限

RDP预认证阶段连通性校验脚本实现

你的需求本质是校验RDP连接流程走到服务端等待凭据输入的节点即可,不需要提交账号密码、不需要完成完整登录,核心判断逻辑不需要依赖完整RDP客户端,轻量脚本就能实现。

校验逻辑原理

标准RDP连接在提交凭据前的固定流程为:

  • TCP三次握手连接目标端口(默认3389)
  • 完成TLS协商(现代RDP默认强制TLS加密,兼容自签证书场景)
  • 客户端发送固定格式的RDP初始连接请求
  • 服务端返回合法RDP响应,等待客户端提交认证信息
    走到最后一步时,就已经满足“返回凭据输入提示、连接正常建立”的校验要求,此时直接断开连接即可,不会触发账户登录成功/失败的审计日志,只会产生基础连接记录。

方案1:PowerShell原生脚本(Windows环境无依赖)

不需要安装任何第三方组件,直接在Windows系统上运行,支持超时控制、自定义端口、自动跳过RDP证书校验:

function Test-RdpCredentialPrompt {
    param(
        [Parameter(Mandatory=$true)]
        [string]$TargetHost,
        [int]$Port = 3389,
        [int]$TimeoutMs = 3000
    )
    $tcpClient = $null
    $tlsStream = $null
    try {
        $tcpClient = New-Object System.Net.Sockets.TcpClient
        $connectTask = $tcpClient.ConnectAsync($TargetHost, $Port)
        if (-not $connectTask.Wait($TimeoutMs)) {
            return @{ Success = $false; Reason = "TCP连接超时,目标端口不可达" }
        }

        $tlsStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream(), $false, { $true })
        $tlsTask = $tlsStream.AuthenticateAsClientAsync($TargetHost)
        if (-not $tlsTask.Wait($TimeoutMs)) {
            return @{ Success = $false; Reason = "TLS协商失败,RDP服务运行异常" }
        }

        # 发送固定格式的RDP初始连接请求,无任何凭据信息
        $rdpConnReq = [byte[]]@(0x03,0x00,0x00,0x13,0x0E,0xE0,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x03,0x00,0x00,0x00)
        $tlsStream.Write($rdpConnReq, 0, $rdpConnReq.Length)

        $buffer = New-Object byte[] 1024
        $readTask = $tlsStream.ReadAsync($buffer, 0, 1024)
        if (-not $readTask.Wait($TimeoutMs)) {
            return @{ Success = $false; Reason = "未收到RDP凭据请求响应,连接被拦截" }
        }

        # 校验RDP协议头:合法RDP包前两字节固定为0x03 0x00
        if ($buffer[0] -eq 0x03 -and $buffer[1] -eq 0x00) {
            return @{ Success = $true; Reason = "RDP连接正常,已返回凭据输入提示" }
        } else {
            return @{ Success = $false; Reason = "端口响应非RDP协议,服务不匹配" }
        }
    } catch {
        return @{ Success = $false; Reason = "连接异常:$($_.Exception.Message)" }
    } finally {
        if ($tlsStream) { $tlsStream.Close() }
        if ($tcpClient) { $tcpClient.Close() }
    }
}

# 调用示例
Test-RdpCredentialPrompt -TargetHost "192.168.1.100"

方案2:Python跨平台脚本(兼容Linux/macOS/Windows)

仅依赖Python原生标准库,不需要安装第三方包,适合批量探测场景:

import socket
import ssl

def test_rdp_credential_prompt(host: str, port: int = 3389, timeout: int = 3) -> tuple[bool, str]:
    sock = None
    tls_sock = None
    try {
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        sock.connect((host, port))

        # 跳过证书校验,兼容自签证书、私有CA签发的证书
        ctx = ssl._create_unverified_context()
        tls_sock = ctx.wrap_socket(sock, server_hostname=host)

        # 发送固定RDP初始连接请求
        rdp_initial_req = bytes([
            0x03, 0x00, 0x00, 0x13, 0x0E, 0xE0, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03,
            0x00, 0x00, 0x00
        ])
        tls_sock.sendall(rdp_initial_req)

        resp = tls_sock.recv(1024)
        if len(resp) >= 2 and resp[0] == 0x03 and resp[1] == 0x00:
            return (True, "RDP连接正常,已返回凭据输入提示")
        else:
            return (False, "端口响应非RDP协议,服务不匹配")
    } catch Exception as e:
        return (False, f"连接失败:{str(e)}")
    finally:
        if tls_sock:
            tls_sock.close()
        if sock:
            sock.close()

# 调用示例
if __name__ == "__main__":
    print(test_rdp_credential_prompt("192.168.1.100"))

注意事项

  • 不要用单纯的TCP端口探测代替RDP校验:很多场景下3389端口能通,但RDP服务崩溃、组策略拦截、NLA配置异常时,根本到不了凭据输入界面,上述脚本覆盖了TLS协商、RDP协议握手流程,能准确识别这类假连通情况
  • 兼容NLA场景:默认开启的网络级别身份验证(NLA)不会影响校验结果,NLA校验本身就处于凭据提交前的阶段,服务端依然会返回合法RDP响应等待认证信息
  • 不需要依赖重型RDP库:不需要引入FreeRDP、rdpy等完整RDP实现库,初始连接请求是固定格式的19字节数据包,不需要实现完整RDP协议栈就能完成校验

内容的提问来源于stack exchange,提问作者P.J. Some

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 05:33:28