👤

重置密码

发送中...
返回登录

自动备份ESXi配置

虚拟化 100 浏览 4 分钟阅读

概述

对于较小的环境,这通常不是一个问题,但如果您的环境较大,例如有10台以上的ESXi主机那么这可能成为一个重复性的问题,或者更现实地说,有一种更简单、更少手动操作的方法来实现,而不是启用SSH、运行命令、下载文件,然后禁用SSH。

有一个拥有22台ESXi主机的客户经常需要备份,但每次手动备份所有这些主机需要几个小时。

所以我将使用PowerCLI,通过简单地将脚本指向vCenter然后将其存储在某个安全的地方来自动化。

安装PowerCLI

从Windows PowerShell 安装 PowerCLI

Install-Module VMware.PowerCLI -Scope CurrentUser

同时可以参考:《VMware PowerCLI 安装使用指南》

如果系统是Ubuntu

#更新系统包
sudo apt-get update

#安装先决条件包
sudo apt-get install -y wget apt-transport-https software-properties-common
#获取带有 Ubuntu 版本
source /etc/os-release

#下载仓库密钥
wget -q https://packages.microsoft.com/config/ubuntu/$VERSION_ID/packages-microsoft-prod.deb

#注册 Microsoft 仓库密钥
sudo dpkg -i packages-microsoft-prod.deb

#再次更新软件包列表
sudo apt-get update

#安装 PowerShell
sudo apt-get install -y powershell

#进入PowerShell
pwsh

#从PowerShell安装PowerCLI
Install-Module VMware.PowerCLI -Scope CurrentUser

Powershell脚本

有几个地方你需替换

$basePath - 定义备份基础路径
$vcUsername - 定义vCenter连接凭据
$vcPassword - 定义vCenter连接密码
$vcServer - 定义VCSA的FQDN

完整脚本

# ESXi主机配置备份脚本
# 描述:连接vCenter备份所有ESXi主机配置,并自动清理历史备份

# 定义备份基础路径
$basePath = "C:\ESXi-Config-Backups"

# 创建日志记录函数(需在调用前定义)
function Write-Log {
    param (
        [string]$Message,
        [string]$LogPath = $script:logFilePath
    )
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logMessage = "[$timestamp] $Message"
    
    # 输出到控制台
    Write-Output $logMessage
    
    # 追加到日志文件
    if ($LogPath) {
        $logMessage | Out-File -FilePath $LogPath -Append -Encoding UTF8
    }
}

# 检查基础路径是否存在,不存在则创建
if (-not (Test-Path -Path $basePath)) {
    try {
        New-Item -ItemType Directory -Path $basePath -Force | Out-Null
        Write-Log "已创建基础备份路径: $basePath"
    }
    catch {
        throw "无法创建基础备份路径: $basePath. 错误: $_"
    }
}

# 获取当前时间(用于文件夹命名)
$currentDateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$backupFolderPath = Join-Path -Path $basePath -ChildPath $currentDateTime

# 创建本次备份文件夹
try {
    New-Item -ItemType Directory -Path $backupFolderPath -Force | Out-Null
    Write-Log "已创建备份文件夹: $backupFolderPath"
}
catch {
    throw "无法创建备份文件夹: $backupFolderPath. 错误: $_"
}

# 创建日志文件路径
$logFilePath = Join-Path -Path $backupFolderPath -ChildPath "BackupLog.txt"

# 记录脚本开始
Write-Log "===== ESXi配置备份脚本开始执行 =====" -LogPath $logFilePath

try {
    # 1. 临时禁用SSL证书验证
    Write-Log "正在临时禁用SSL证书验证..." -LogPath $logFilePath
    Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false -Scope Session | Out-Null
    Write-Log "SSL证书验证已临时禁用" -LogPath $logFilePath

    # 2. 断开所有现有vCenter连接
    $existingConnections = @(Get-VIServer -ErrorAction SilentlyContinue)
    if ($existingConnections.Count -gt 0) {
        Write-Log "发现现有连接,正在断开..." -LogPath $logFilePath
        Disconnect-VIServer -Server * -Force -Confirm:$false -ErrorAction SilentlyContinue | Out-Null
        Write-Log "已断开所有现有vCenter连接" -LogPath $logFilePath
    }

    # 3. 定义vCenter连接凭据(建议从安全存储或加密文件读取)
    $vcUsername = "<service-account>"
    $vcPassword = "<password>"
    $vcServer = "<vCenter-fqdn>"
    
    # 创建安全凭据对象
    $securePassword = ConvertTo-SecureString $vcPassword -AsPlainText -Force
    $vcCredential = New-Object System.Management.Automation.PSCredential ($vcUsername, $securePassword)

    # 4. 连接到vCenter服务器
    Write-Log "正在连接到vCenter服务器: $vcServer" -LogPath $logFilePath
    try {
        $connection = Connect-VIServer -Server $vcServer -Credential $vcCredential -ErrorAction Stop
        Write-Log "成功连接到vCenter: $($connection.Name)" -LogPath $logFilePath
    }
    catch {
        throw "连接vCenter失败: $_"
    }

    # 5. 获取所有ESXi主机
    Write-Log "正在获取ESXi主机列表..." -LogPath $logFilePath
    try {
        $esxiHosts = Get-VMHost -ErrorAction Stop
        Write-Log "找到 $($esxiHosts.Count) 台ESXi主机" -LogPath $logFilePath
    }
    catch {
        throw "获取ESXi主机列表失败: $_"
    }

    # 6. 遍历每台主机执行备份
    $successCount = 0
    $failedCount = 0
    
    foreach ($esxiHost in $esxiHosts) {
        $hostName = $esxiHost.Name
        Write-Log "正在备份主机: $hostName" -LogPath $logFilePath
        
        try {
            # 执行固件配置备份
            $backupResult = Get-VMHostFirmware -VMHost $esxiHost -BackupConfiguration -DestinationPath $backupFolderPath -ErrorAction Stop
            $successCount++
            Write-Log "✓ 主机 $hostName 备份完成" -LogPath $logFilePath
        }
        catch {
            $failedCount++
            Write-Log "✗ 主机 $hostName 备份失败: $_" -LogPath $logFilePath
            continue
        }
    }

    # 7. 备份完成统计
    Write-Log "备份完成统计: 成功 $successCount 台, 失败 $failedCount 台" -LogPath $logFilePath

    # 8. 清理旧备份(保留30天内的备份)
    $retentionDays = 30
    Write-Log "正在清理 $retentionDays 天前的旧备份..." -LogPath $logFilePath
    
    $oldFolders = Get-ChildItem -Path $basePath -Directory | 
                  Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$retentionDays) }
    
    if ($oldFolders.Count -gt 0) {
        $deletedCount = 0
        foreach ($folder in $oldFolders) {
            try {
                Remove-Item -Path $folder.FullName -Recurse -Force -ErrorAction Stop
                $deletedCount++
                Write-Log "已删除旧备份文件夹: $($folder.Name)" -LogPath $logFilePath
            }
            catch {
                Write-Log "删除文件夹失败: $($folder.Name). 错误: $_" -LogPath $logFilePath
            }
        }
        Write-Log "已清理 $deletedCount 个旧备份文件夹" -LogPath $logFilePath
    }
    else {
        Write-Log "没有需要清理的旧备份文件夹" -LogPath $logFilePath
    }

    # 9. 断开vCenter连接
    Write-Log "正在断开vCenter连接..." -LogPath $logFilePath
    Disconnect-VIServer -Server $vcServer -Confirm:$false -ErrorAction SilentlyContinue
    Write-Log "已断开vCenter连接" -LogPath $logFilePath

    # 10. 恢复SSL证书验证设置
    Write-Log "正在恢复SSL证书验证设置..." -LogPath $logFilePath
    Set-PowerCLIConfiguration -InvalidCertificateAction Prompt -Confirm:$false -Scope Session | Out-Null
    Write-Log "SSL证书验证设置已恢复" -LogPath $logFilePath

    # 最终总结
    Write-Log "所有备份操作已完成" -LogPath $logFilePath
    Write-Log "备份文件保存在: $backupFolderPath" -LogPath $logFilePath
    Write-Log "日志文件位置: $logFilePath" -LogPath $logFilePath
    Write-Log "===== 脚本执行完成 =====" -LogPath $logFilePath

}
catch {
    # 异常处理
    $errorMessage = "脚本执行失败: $_"
    Write-Log $errorMessage -LogPath $logFilePath
    Write-Error $errorMessage
    
    # 尝试恢复SSL设置
    try {
        Set-PowerCLIConfiguration -InvalidCertificateAction Prompt -Confirm:$false -Scope Session | Out-Null
        Write-Log "已恢复SSL证书验证设置" -LogPath $logFilePath
    }
    catch {
        Write-Log "恢复SSL设置失败: $_" -LogPath $logFilePath
    }
    
    throw $errorMessage
}

执行脚本后将得到一个像这样的文件夹

任务计划

通过创建任务计划来实现自动化。

Windows系统

点击任务计划程序库,然后右键点击并点击创建任务
给它命名,勾选单选按钮只在用户登录时运行,设置每天运行的时间,设置程序为:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
在添加参数中添加
-ExecutionPolicy Bypass -File “脚本文件路径

点击条件并取消仅在交流电供电时运行的选项,

点击设置并取消勾选框以停止任务运行超过3天。

Ubuntu系统

使用 crontab

crontab -e

在底部添加

0 17 * * * pwsh /home/rpzm/Scripts/ESXi-Config-Backup.ps1 #替换为实际路径

1

  1. ymz316
    ymz316

    管理多台主机,是要有些批处理的手段才行😃 博主的feed订阅不上不知道什么原因。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注