Загрузка данных
# Run in PowerShell as Administrator.
& {
$ErrorActionPreference = 'Stop'
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
throw 'Open PowerShell as Administrator and run this code again.'
}
$backup = Join-Path $env:USERPROFILE ('rdp-backup-' + (Get-Date -Format 'yyyyMMdd-HHmmss-fff') + '.reg')
& reg.exe export 'HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server' $backup /y
if ($LASTEXITCODE -ne 0) { throw 'Registry backup failed; no changes made.' }
$root = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server'
$listener = Join-Path $root 'WinStations\RDP-Tcp'
$protocol = '{5828227c-20cf-4408-b73f-73ab70b8849f}'
if (-not (Test-Path "Registry::HKEY_CLASSES_ROOT\CLSID\$protocol\InprocServer32")) {
throw 'The Windows RDP protocol component is missing; repair Windows first.'
}
New-Item -Path $listener -Force | Out-Null
New-ItemProperty -Path $root -Name fDenyTSConnections -PropertyType DWord -Value 0 -Force | Out-Null
$policy = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services'
if (Test-Path $policy) {
$policyDeny = Get-ItemPropertyValue -Path $policy -Name fDenyTSConnections -ErrorAction SilentlyContinue
if ($policyDeny -eq 1) {
throw 'Group Policy prohibits RDP. Enable it in the governing policy, then rerun this code.'
}
}
$values = @{
PortNumber = 3389
fEnableWinStation = 1
LanAdapter = 0
MinEncryptionLevel = 3
WdFlag = 0
PdFlag = 0
WdPrefix = 0
PdPrefix = 0
WdClass = 0
PdClass = 2
MaxInstanceCount = [uint32]::MaxValue
fAllowSecProtocolNegotiation = 1
}
foreach ($name in $values.Keys) {
New-ItemProperty -Path $listener -Name $name -PropertyType DWord -Value $values[$name] -Force | Out-Null
}
foreach ($entry in @{
WdName = 'Microsoft RDP 8.0'
PdName = 'tcp'
LoadableProtocol_Object = $protocol
}.GetEnumerator()) {
New-ItemProperty -Path $listener -Name $entry.Key -PropertyType String -Value $entry.Value -Force | Out-Null
}
# Preserve existing authentication/security settings; supply secure defaults if absent.
foreach ($entry in @{UserAuthentication = 1; SecurityLayer = 1}.GetEnumerator()) {
if ($null -eq (Get-ItemProperty -Path $listener).PSObject.Properties[$entry.Key]) {
New-ItemProperty -Path $listener -Name $entry.Key -PropertyType DWord -Value $entry.Value | Out-Null
}
}
Enable-NetFirewallRule -Name 'RemoteDesktop-UserMode-In-TCP','RemoteDesktop-UserMode-In-UDP'
Set-Service -Name TermService -StartupType Automatic
# Restart disconnects any active RDP sessions.
Restart-Service -Name TermService -Force
Start-Service -Name UmRdpService
$ready = $false
for ($attempt = 0; $attempt -lt 15; $attempt++) {
if (Get-NetTCPConnection -State Listen -LocalPort 3389 -ErrorAction SilentlyContinue) {
$ready = $true
break
}
Start-Sleep -Seconds 1
}
if (-not $ready) { throw "RDP is not listening. Registry backup: $backup" }
$client = [Net.Sockets.TcpClient]::new()
try { $client.Connect('127.0.0.1', 3389) } finally { $client.Dispose() }
Write-Host 'RDP repaired: TCP 3389 is listening and local connection succeeded.' -ForegroundColor Green
Write-Host "Registry backup: $backup"
}