diff --git a/certy.ps1 b/certy.ps1 index 44ea542..0ecd1d4 100644 --- a/certy.ps1 +++ b/certy.ps1 @@ -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 $_ } } }