fix: Thumbprint при одном cert после нативного сброса (PS 5.1 unwrap)
Добавлены Get-RdpRepairCertificateArray/FirstCertificate, самотесты на вложенные массивы; Fix-RdpTls больше не использует Select-Object -First 1 на cert. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -71,7 +71,7 @@ try {
|
||||
Write-RdpRepairLog 'No cert in Remote Desktop store - run full repair or repair install first' 'ERROR' $logPath
|
||||
exit 2
|
||||
}
|
||||
$valid = $certs | Where-Object { $_.NotAfter -gt (Get-Date) } | Select-Object -First 1
|
||||
$valid = @(Get-RdpRepairCertificateArray $certs | Where-Object { $_.NotAfter -gt (Get-Date) })[0]
|
||||
if (-not $valid) {
|
||||
Write-RdpRepairLog 'Все cert просрочены' 'ERROR' $logPath
|
||||
exit 2
|
||||
@@ -98,7 +98,7 @@ try {
|
||||
$snap = Get-RdpRepairDiagnosticSnapshot
|
||||
$snap | Format-List ComputerName, OsCaption, SecurityLayer, SslHash, CertCount, Events1057_24h, GpoLicenseSrv
|
||||
|
||||
$expired = @($snap.Certificates | Where-Object { $_.NotAfter -lt (Get-Date) })
|
||||
$expired = @(Get-RdpRepairCertificateArray $snap.Certificates | Where-Object { $_.NotAfter -lt (Get-Date) })
|
||||
if ($expired.Count -gt 0) {
|
||||
Write-RdpRepairLog "Найдено просроченных cert: $($expired.Count)" 'WARN' $logPath
|
||||
}
|
||||
@@ -111,7 +111,8 @@ try {
|
||||
$native = Invoke-RdpRepairNativeReset -LogPath $logPath
|
||||
if ($native.CertCount -gt 0) {
|
||||
Write-RdpRepairLog "После сброса без reboot: нативный cert найден ($($native.CertCount))" 'OK' $logPath
|
||||
$nativeCert = $native.Certificates | Select-Object -First 1
|
||||
$nativeCert = Get-RdpRepairFirstCertificate -Certificates $native.Certificates
|
||||
if (-not $nativeCert) { throw 'Native cert list empty after reset' }
|
||||
$bindNative = Test-RdpRepairCertificateBindingPersisted -ExpectedThumbprint $nativeCert.Thumbprint -LogPath $logPath
|
||||
if ($bindNative.Persisted) {
|
||||
Write-RdpRepairLog 'Native cert accepted - you can use RestoreTls' 'OK' $logPath
|
||||
|
||||
@@ -76,6 +76,30 @@ Assert-Test 'Get-RdpRepairRemoteDesktopCertificates exposes Count' {
|
||||
$null = $certs.Count
|
||||
}
|
||||
|
||||
Assert-Test 'single cert in PSCustomObject keeps Thumbprint' {
|
||||
$mock = [PSCustomObject]@{
|
||||
Thumbprint = 'DEADBEEF'
|
||||
Subject = 'CN=test'
|
||||
NotAfter = (Get-Date).AddDays(30)
|
||||
HasKey = $true
|
||||
}
|
||||
$box = [PSCustomObject]@{ Certificates = @($mock) }
|
||||
$first = Get-RdpRepairFirstCertificate -Certificates $box.Certificates
|
||||
if ($first.Thumbprint -ne 'DEADBEEF') { throw 'Thumbprint lost via property unwrap' }
|
||||
}
|
||||
|
||||
Assert-Test 'Get-RdpRepairCertificateArray flattens nested Object[]' {
|
||||
$mock = [PSCustomObject]@{
|
||||
Thumbprint = 'NESTED01'
|
||||
Subject = 'CN=nested'
|
||||
NotAfter = (Get-Date).AddDays(1)
|
||||
HasKey = $true
|
||||
}
|
||||
$box = [PSCustomObject]@{ Certificates = ,[object[]]@(,[object[]]@($mock)) }
|
||||
$first = Get-RdpRepairFirstCertificate -Certificates $box.Certificates
|
||||
if ($first.Thumbprint -ne 'NESTED01') { throw "expected NESTED01 got $($first.Thumbprint)" }
|
||||
}
|
||||
|
||||
Assert-Test 'Get-RdpRepairDiagnosticSnapshot object shape' {
|
||||
if (-not (Test-RdpRepairIsAdministrator)) {
|
||||
Write-Host ' (skip snapshot fields - not admin)' -ForegroundColor DarkYellow
|
||||
@@ -85,6 +109,10 @@ Assert-Test 'Get-RdpRepairDiagnosticSnapshot object shape' {
|
||||
foreach ($prop in @('ComputerName', 'SecurityLayer', 'CertCount', 'TermService')) {
|
||||
if (-not $s.PSObject.Properties[$prop]) { throw "missing property $prop" }
|
||||
}
|
||||
if ($s.CertCount -gt 0) {
|
||||
$first = Get-RdpRepairFirstCertificate -Certificates $s.Certificates
|
||||
if (-not $first.Thumbprint) { throw 'snapshot cert missing Thumbprint' }
|
||||
}
|
||||
}
|
||||
|
||||
Assert-Test 'Registry path constants well-formed' {
|
||||
|
||||
@@ -86,8 +86,30 @@ function Get-RdpRepairRemoteDesktopCertificates {
|
||||
} finally {
|
||||
$store.Close()
|
||||
}
|
||||
# Запятая перед return: иначе PS 5.1 разворачивает массив из одного cert и ломает .Count
|
||||
return ,[object[]]$list.ToArray()
|
||||
return [object[]]$list.ToArray()
|
||||
}
|
||||
|
||||
function Get-RdpRepairCertificateArray {
|
||||
param([object]$Certificates)
|
||||
if ($null -eq $Certificates) { return @() }
|
||||
$flat = New-Object System.Collections.Generic.List[object]
|
||||
foreach ($item in @($Certificates)) {
|
||||
if ($item -is [object[]]) {
|
||||
foreach ($inner in @($item)) {
|
||||
if ($null -ne $inner) { [void]$flat.Add($inner) }
|
||||
}
|
||||
} elseif ($null -ne $item) {
|
||||
[void]$flat.Add($item)
|
||||
}
|
||||
}
|
||||
return [object[]]$flat.ToArray()
|
||||
}
|
||||
|
||||
function Get-RdpRepairFirstCertificate {
|
||||
param([object]$Certificates)
|
||||
$arr = @(Get-RdpRepairCertificateArray -Certificates $Certificates)
|
||||
if ($arr.Count -lt 1) { return $null }
|
||||
return $arr[0]
|
||||
}
|
||||
|
||||
function Clear-RdpRepairCertificateStores {
|
||||
@@ -258,7 +280,7 @@ function Invoke-RdpRepairNativeReset {
|
||||
return [PSCustomObject]@{
|
||||
RebootScheduled = $false
|
||||
CertCount = $certs.Count
|
||||
Certificates = $certs
|
||||
Certificates = ,[object[]]$certs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +305,7 @@ function Get-RdpRepairDiagnosticSnapshot {
|
||||
TermService = (Get-Service TermService).Status
|
||||
RdpAllowed = -not (Get-ItemProperty $script:RdpRepairTsKey).fDenyTSConnections
|
||||
CertCount = $certs.Count
|
||||
Certificates = $certs
|
||||
Certificates = ,[object[]]$certs
|
||||
GpoLicenseSrv = $pol.LicenseServers
|
||||
GpoLicMode = $pol.LicensingMode
|
||||
Events1057_24h = $ev1057
|
||||
@@ -302,7 +324,7 @@ function Export-RdpRepairDiagnosticReport {
|
||||
$snap.PSObject.Properties | ForEach-Object {
|
||||
if ($_.Name -eq 'Certificates') {
|
||||
$lines += 'Certificates:'
|
||||
foreach ($c in $_.Value) {
|
||||
foreach ($c in (Get-RdpRepairCertificateArray $_.Value)) {
|
||||
$lines += (' - {0}; Thumb={1}; NotAfter={2}; Key={3}' -f $c.Subject, $c.Thumbprint, $c.NotAfter, $c.HasKey)
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user