
# 配置rollback_hosts_win.ps1脚本
根据提供的脚本示例，结合实际情况，修改示例中的相关配置。
#### 前提条件
已完成[准备工作](https://support.huaweicloud.com/bestpractice-mgc/mgc_05_0066.html)。
#### 操作步骤
1. 在执行脚本的主机上创建一个名为"**rollback_hosts_win.ps1** "的文件，然后将以下脚本示例的内容复制到文件中。
   
   ```
   # 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."
   ```
   
   
2. 根据实际情况，修改脚本中的以下配置项参数： 
   - **$logDir = "C:\\Users\\Public\\Hosts_Script_Logs"**
     - **描述**：日志目录路径，用于存放运行日志、错误日志和总结日志的文件夹路径。
     
     - **参数默认值**： C:\\Users\\Public\\Hosts_Script_Logs
     
     - **修改建议**：修改为当前用户具有写入权限的目录路径。
     
     
     
     - **修改示例**：$logDir ="C:\\Users\\username\\Documents\\Hosts_Script_Logs"
      
   
   - **$csvFile = "C:\\Users\\Public\\target_servers.csv"**
     - **描述** ：[CSV文件](https://support.huaweicloud.com/bestpractice-mgc/mgc_05_0066.html#mgc_05_0066__section1757292914583)存放路径，包含源端主机信息。
     
     - **参数默认值**：C:\\Users\\Public\\target_servers.csv
     
     - **修改建议**：使用绝对路径，或确保相对路径是正确的。如果CSV文件路径发生变化，需要更新填写的路径。
     
     - **修改示例**：$csvFile = "C:\\Users\\username\\Documents\\servers.csv"
      
   
   
   
   
3. 配置项参数修改完成并保存后，以管理员身份打开PowerShell窗口，使用以下命令执行脚本： 
   ```
   .\rollback_hosts_win.ps1
   ```
   脚本会在终端窗口中输出日志信息，并在执行完毕后生成一个执行结果报告，可以在**$logDir** 指定目录中的 summary.log 文件中查看。
   
   
 
