Use persistent PSSession for replication

This commit is contained in:
2026-01-29 11:54:46 +13:00
parent e7a118f661
commit d728765206

View File

@@ -248,32 +248,59 @@ function Invoke-Replication {
return
}
foreach ($server in $targets) {
$usesToken = $Command -match "\{server\}"
$cmd = if ($usesToken) { $Command.Replace("{server}", $server) } else { $Command }
$cmd = $cmd.Trim()
if ($cmd -match "^(?i)\s*/repadmin\b") {
$cmd = $cmd -replace "^(?i)\s*/repadmin\b", "repadmin"
}
if ($UseRemote -and $cmd -match "(?i)\brepadmin\b" -and $cmd -match "(?i)\bsyncall\b") {
$remoteCmd = [regex]::Replace($cmd, "(?i)\\brepadmin\\s+/syncall\\s+\\S+", "repadmin /syncall")
& $Log "Replication (remote): $server -> $remoteCmd"
try {
Invoke-Command -ComputerName $server -ScriptBlock { param($c) & $env:ComSpec /c $c } -ArgumentList $remoteCmd |
ForEach-Object { & $Log $_ }
} catch {
& $Log ("Replication error on {0}: {1}" -f $server, $_.Exception.Message)
$sessions = @{}
try {
foreach ($server in $targets) {
$usesToken = $Command -match "\{server\}"
$cmd = if ($usesToken) { $Command.Replace("{server}", $server) } else { $Command }
$cmd = $cmd.Trim()
if ($cmd -match "^(?i)\s*/repadmin\b") {
$cmd = $cmd -replace "^(?i)\s*/repadmin\b", "repadmin"
}
continue
}
if (-not $usesToken -and $server -and $cmd -match "(?i)\brepadmin\b" -and $cmd -match "(?i)\bsyncall\b") {
if ($cmd -notmatch "(?i)\\bsyncall\\s+\\S+") {
$cmd = $cmd -replace "(?i)\\bsyncall\\b", "syncall $server"
if ($UseRemote) {
if (-not $sessions.ContainsKey($server)) {
try {
$sessions[$server] = New-PSSession -ComputerName $server -ErrorAction Stop
& $Log "Replication session opened: $server"
} catch {
& $Log ("Replication session error on {0}: {1}" -f $server, $_.Exception.Message)
continue
}
}
$remoteCmd = $cmd.Replace("{server}", "").Trim()
$remoteCmd = [regex]::Replace($remoteCmd, "\s{2,}", " ")
if ($remoteCmd -match "(?i)\brepadmin\b" -and $remoteCmd -match "(?i)\bsyncall\b") {
$remoteCmd = [regex]::Replace($remoteCmd, "(?i)\brepadmin\s+/syncall\s+\S+", "repadmin /syncall")
}
if ([string]::IsNullOrWhiteSpace($remoteCmd)) {
& $Log "Replication skipped: empty command for $server."
continue
}
& $Log "Replication (remote): $server -> $remoteCmd"
try {
Invoke-Command -Session $sessions[$server] -ScriptBlock { param($c) & $env:ComSpec /c $c } -ArgumentList $remoteCmd |
ForEach-Object { & $Log $_ }
} catch {
& $Log ("Replication error on {0}: {1}" -f $server, $_.Exception.Message)
}
continue
}
if (-not $usesToken -and $server -and $cmd -match "(?i)\brepadmin\b" -and $cmd -match "(?i)\bsyncall\b") {
if ($cmd -notmatch "(?i)\\bsyncall\\s+\\S+") {
$cmd = $cmd -replace "(?i)\\bsyncall\\b", "syncall $server"
}
}
if ([string]::IsNullOrWhiteSpace($cmd)) { continue }
& $Log "Replication: $cmd"
& $env:ComSpec /c $cmd | ForEach-Object { & $Log $_ }
}
} finally {
foreach ($session in $sessions.Values) {
try { Remove-PSSession -Session $session } catch {}
}
if ([string]::IsNullOrWhiteSpace($cmd)) { continue }
& $Log "Replication: $cmd"
& $env:ComSpec /c $cmd | ForEach-Object { & $Log $_ }
}
}