Configuring the rollback_hosts_win.ps1 Script
Modify the configuration in the example script to meet your specific requirements.
Prerequisites
You have completed all preparations.
Procedure
- Create a file named rollback_hosts_win.ps1 on the server where the script is executed, and copy the following script content to the file.
# Configuration # Path to the CSV file with server information. Must exist before running the script. $csvFile = "C:\Users\Public\target_servers.csv" # Manually configure # Directory for storing log files. Will be created if it doesn't exist. $logDir = "C:\Users\Public\Hosts_Script_Logs" # Automatically created # Log file for general run information. $runLog = Join-Path $logDir "run.log" # Automatically created # Log file for error messages. $errorLog = Join-Path $logDir "error.log" # Automatically created # Log file for summary information. $summaryLog = Join-Path $logDir "summary.log" # Automatically created # Initialize log directory and files function Initialize-Logs { if (-not (Test-Path $logDir)) { New-Item -Path $logDir -ItemType Directory } Add-Content -Path $runLog -Value "========================================" Add-Content -Path $runLog -Value "[INFO] $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Starting new restore execution" Add-Content -Path $runLog -Value "========================================" Add-Content -Path $errorLog -Value "========================================" Add-Content -Path $errorLog -Value "[INFO] $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Starting new restore execution" Add-Content -Path $errorLog -Value "========================================" Add-Content -Path $summaryLog -Value "========================================" Add-Content -Path $summaryLog -Value "[INFO] $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Starting new restore execution" Add-Content -Path $summaryLog -Value "========================================" } # Log info function function Log-Info { param ( [string]$message ) $logMessage = "[INFO] $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $message" Add-Content -Path $runLog -Value $logMessage Write-Output $logMessage } # Log error function function Log-Error { param ( [string]$message ) $logMessage = "[ERROR] $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $message" Add-Content -Path $runLog -Value $logMessage Add-Content -Path $errorLog -Value $logMessage Write-Output $logMessage } # Read server information from CSV file function Read-ServersFromCSV { param ( [string]$csvFile ) if (-not (Test-Path $csvFile)) { Log-Error "CSV file '$csvFile' not found." exit 1 } return Import-Csv -Path $csvFile } # Add to TrustedHosts function Add-ToTrustedHosts { param ( [string]$ip ) # Check current TrustedHosts list $trustedHostsPath = "WSMan:\localhost\Client\TrustedHosts" $trustedHosts = (Get-Item $trustedHostsPath).Value if ($trustedHosts -eq $null -or $trustedHosts -eq "") { # Set the initial trusted host Set-Item $trustedHostsPath -Value $IP -Force Log-Info "Set initial TrustedHosts value to $IP" } elseif ($trustedHosts -notlike "*$ip*") { # Add new IP to TrustedHosts if not already present $updatedTrustedHosts = if ($trustedHosts -eq "*") { $ip } else { "$trustedHosts,$ip" } try { Set-Item $trustedHostsPath -Value $updatedTrustedHosts -Force Log-Info "Added $ip to TrustedHosts" } catch { Log-Error "Failed to add $ip to TrustedHosts: $_" } } else { Write-Host "TrustedHosts list already contains IP $ip." } } # Initialize log files Initialize-Logs # Verify CSV file if (-not (Test-Path $csvFile)) { Log-Error "CSV file '$csvFile' not found." exit 1 } # Read server information from CSV file $servers = Read-ServersFromCSV -csvFile $csvFile # Counters for success and failure $successCount = 0 $failureCount = 0 $failedServers = @() # Remote script block $remoteScriptBlock = { param () $hostsFilePath = 'C:\Windows\System32\drivers\etc\hosts' # Read the file content $content = Get-Content -Path $hostsFilePath # Initialize flag $inBlock = $false $newContent = @() # Traverse file content foreach ($line in $content) { if ($line -match '#Migration-proxy-start') { $inBlock = $true } if (-not $inBlock) { $newContent += $line } if ($line -match '#Migration-proxy-end') { $inBlock = $false continue } } # Remove trailing empty lines while ($newContent[-1] -eq '') { $newContent = $newContent[0..($newContent.Count - 2)] } # Write the new content back to the file $newContent | Set-Content -Path $hostsFilePath Write-Output 'Successfully restored hosts file on remote server.' } # Main script logic Log-Info "Script execution started." foreach ($server in $servers) { $username = $server.username $ip = $server.ip $password = $server.password if (-not $username -or -not ${ip} -or -not $password) { Log-Error "Invalid server entry: $username, ${ip}, $password. Skipping." continue } Log-Info "Starting restore for $username@${ip}" $securePassword = ConvertTo-SecureString $password -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential ($username, $securePassword) Add-ToTrustedHosts -ip $ip try { $session = New-PSSession -ComputerName ${ip} -Credential $credential -ErrorAction Stop Invoke-Command -Session $session -ScriptBlock $remoteScriptBlock Remove-PSSession -Session $session Log-Info "Restored hosts on ${ip} successfully" $successCount++ } catch { Log-Error "Failed to restore hosts on ${ip}: $_" $failedServers += "$username@${ip}" $failureCount++ } } # Calculate failure and success percentages $totalCount = $servers.Count if ($totalCount -gt 0) { $failurePercentage = [math]::Round(($failureCount / $totalCount) * 100, 2) $successPercentage = [math]::Round(($successCount / $totalCount) * 100, 2) } else { $failurePercentage = 0 $successPercentage = 100 } # Output summary result and log to file $summaryContent = @" ======================================== [SUMMARY] $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Execution Rollback Summary ======================================== Total number of servers: $totalCount Number of successful restores: $successCount Number of failed restores: $failureCount Failure rate: $failurePercentage% Success rate: $successPercentage% ---------------------------------------- "@ if ($failedServers.Count -gt 0) { $summaryContent += "Failed servers:`n" foreach ($server in $failedServers) { $summaryContent += " - $server`n" } } $summaryContent += "========================================" # Output summary result to log file and terminal $summaryContent | Add-Content -Path $summaryLog Write-Output $summaryContent Log-Info "Script execution completed. Check $summaryLog for summary."
- Modify the following parameters in the script to meet your needs:
- $logDir = "C:\Users\Public\Hosts_Script_Logs"
- Description: log directory, which is used to store run, error, and summary logs.
- Default value: C:\Users\Public\Hosts_Script_Logs
- Suggestion: Change the value to a directory for which the current user has the write permission.
- Example: $logDir ="C:\Users\username\Documents\Hosts_Script_Logs"
- $csvFile = "C:\Users\Public\target_servers.csv"
- Description: CSV file path. The file contains the source server information.
- Default value: C:\Users\Public\target_servers.csv
- Suggestion: Use an absolute path or a correct relative path. If the CSV file path changes, you need to update the path here.
- Example: $csvFile = "C:\Users\username\Documents\servers.csv"
- $logDir = "C:\Users\Public\Hosts_Script_Logs"
- After the configuration items are modified and saved, run PowerShell as administrator and execute the script.
.\rollback_hosts_win.ps1
The script will output log information in the terminal window and generate a result report upon completion. You can view this report in the summary.log file in the directory specified by $logDir.
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.