更新时间:2024-09-14 GMT+08:00
分享

配置update_hosts_win.ps1脚本

根据提供的脚本示例,结合实际情况,修改示例中的相关配置。

前提条件

已完成准备工作

操作步骤

  1. 在执行脚本的主机上创建一个名为“update_hosts_lwin.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
     
    # Path to the hosts content file. Must exist before running the script.
    $hostsFile = "C:\Users\Public\hosts_content.txt"  # 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 update 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 update 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 update 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
    }
     
    # Read hosts content from TXT file
    function Read-HostsContentFromTXT {
        param (
            [string]$hostsFile
        )
        if (-not (Test-Path $hostsFile)) {
            Log-Error "Hosts content file '$hostsFile' not found."
            exit 1
        }
        return Get-Content -Path $hostsFile -Raw
    }
     
    # 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
    }
     
    # Verify hosts file
    if (-not (Test-Path $hostsFile)) {
        Log-Error "Hosts content file '$hostsFile' not found."
        exit 1
    }
     
    # Read server information from CSV file
    $servers = Read-ServersFromCSV -csvFile $csvFile
     
    # Read hosts content from TXT file
    $hostsContent = Read-HostsContentFromTXT -hostsFile $hostsFile
     
    # Counters for success and failure
    $successCount = 0
    $failureCount = 0
    $failedServers = @()
     
    # Remote script block
    $remoteScriptBlock = {
        param (
            [string]$hostsContent
        )
        $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
     
        # Append new Migration-proxy section
        Add-Content -Path $hostsFilePath -Value $hostsContent
     
        Write-Output 'Successfully updated 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 update 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 -ArgumentList $hostsContent
     
            Remove-PSSession -Session $session
            Log-Info "Updated hosts on ${ip} successfully"
            $successCount++
        }
        catch {
            Log-Error "Failed to update 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 Update Summary
    ========================================
    Total number of servers: $totalCount
    Number of successful updates: $successCount
    Number of failed updates: $failureCount
    Success rate: $successPercentage%
    Failure rate: $failurePercentage%
    ----------------------------------------
    "@
     
    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文件存放路径,包含源端主机信息。
      • 参数默认值:C:\Users\Public\target_servers.csv
      • 修改建议:使用绝对路径,或确保相对路径是正确的。如果CSV文件路径发生变化,需要更新填写的路径。
      • 修改示例:$csvFile = "C:\Users\username\Documents\servers.csv"
    • $hostsFile = "C:\Users\Public\hosts_content.txt"
      • 描述Hosts文件存放路径,包含要追加到源端主机hosts文件中的内容。
      • 参数默认值:C:\Users\Public\hosts_content.txt
      • 修改建议:使用绝对路径,或确保相对路径是正确的。
      • 修改示例:$hostsFile = "C:\Users\username\Documents\hosts_content.txt"

  3. 配置项参数修改完成并保存后,以管理员身份打开PowerShell窗口,使用以下命令执行脚本:

    .\update_hosts_win.ps1

    脚本会在终端窗口中输出日志信息,并在执行完毕后生成一个执行结果报告,可以在$logDir 指定目录中的 summary.log 文件中查看。

相关文档