云服务器内容精选

  • 操作步骤 在执行脚本的主机上创建一个名为“update_hosts_lwin.ps1”的文件,然后将以下脚本示例的内容复制到文件中。 # Configuration # Path to the CS V 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." 根据实际情况,修改脚本中的以下配置项参数: $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" 配置项参数修改完成并保存后,以管理员身份打开PowerShell窗口,使用以下命令执行脚本: .\update_hosts_win.ps1 脚本会在终端窗口中输出日志信息,并在执行完毕后生成一个执行结果报告,可以在$logDir 指定目录中的 summary.log 文件中查看。