So sichern Sie ESXi-VMs ganz einfach mit PowerShell-Skripten

Physische Server sollten nicht auf herkömmliche Weise gesichert werden, um Daten auf der gesamten Maschine zu speichern. Versuchen Sie PowerShell-Skripte, um ESXi-VMs einfach zu sichern.

download-icon
Kostenloser Download
für VM, OS, DB, Datei, NAS usw.
emma

Updated by Emma on 2025/10/11

Inhaltsverzeichnis
  • ESXi-VM-Sicherung vs. Host-Sicherung

  • So sichern Sie ESXi-VMs mit PowerShell-Skripten

  • Wie sichert man ESXi-VMs mit Enterprise-Backup-Software?

  • Sicherung von ESXi-VMs mit Skripten – Häufig gestellte Fragen

  • Zusammenfassung

VMware vSphere wird in Unternehmen weit verbreitet eingesetzt und bietet eine leistungsstarke Virtualisierungsplattform, um die Hardware-Ressourcen physischer Server vollständig zu nutzen, wobei der Hypervisor ESXi von den Anwendern besonders gelobt wird.

Wenn die Virtualisierungstechnologie die Einschränkungen der traditionellen IT-Umgebung aufhebt, bringt sie auch neue Herausforderungen im Bereich der IT-Wartung mit sich. Sollten IT-Administratoren weiterhin den physischen Server sichern oder nach einer neuen Lösung suchen, um die ESXi-VMs zu sichern?

ESXi-VM-Sicherung vs. Host-Sicherung

Bevor die physischen Server virtualisiert wurden, mussten IT-Administratoren diese nur mit herkömmlichen Lösungen sichern. Heute ist es jedoch nicht sinnvoll, den gesamten Server wiederherzustellen, um eine bestimmte VM zu reparieren, da dies die ordnungsgemäß laufenden VMs beeinträchtigen könnte.

Außerdem ist es schwierig, alle Daten auf einem virtualisierten Host zu sichern, da ESXi ein Hypervisor der Typ-1-Kategorie ist, was bedeutet, dass kein Betriebssystem vorhanden ist, auf dem eine herkömmliche Backup-Lösung einen Sicherungsagenten installieren könnte. Einige IT-Administratoren führen eine Sicherung der ESXi-Konfiguration durch, aber mehr Personen halten dies für unnötig.

Die effektivste Methode zum Schutz von Daten und Geschäftsabläufen in einer virtuellen Umgebung besteht weiterhin darin, die VMs auf dem ESXi-Host zu sichern, sodass im Falle eines VM-Ausfalls der IT-Administrator eine einzelne VM wiederherstellen kann, ohne die anderen zu beeinträchtigen.

So sichern Sie ESXi-VMs mit PowerShell-Skripten

Zum Verwalten von virtuellen Maschinen können Sie vCenter in der virtuellen Umgebung bereitstellen und die ESXi-VMs manuell als Datenbackup exportieren.

Mit bereitgestellem vCenter können Sie auch PowerShell-Skripte nach Zeitplan ausführen, um VMs zu sichern.

In diesem Abschnitt wird Ihnen Schritt für Schritt erklärt, wie Sie 3 Skripte erstellen: Starter.ps1, _Configuration.ps1 und Backup-VM.ps1. Danach müssen Sie diese in der folgenden Verzeichnisstruktur ablegen:

│  Backup-VM.ps1
│  Starter.ps1

└─vCenter01
       _Configuration.ps1

Skript-Baumstruktur

Erklärung der Skriptfunktionen:

Starter.ps1 - Invoked by task scheduler, in its path, it will scan all _Configuration.ps1 files, and launch Backup-VM.ps1 asynchronously.
Backup-VM.ps1 - Owns a sole parameter called "-vCenterFolder", pointing to a directory of _Configuration.ps1.
_Configuration.ps1 - Configuration file, any number of it is ok, based on the contents, do different VM backup jobs on different vCenter servers.

Inhalt und Beschreibung des Skripts:

Starter.ps1

# Enter directory of script
Set-Location (Get-Item $MyInvocation.MyCommand.Definition).Directory

# Scan all _Configuration.ps1 files
Get-ChildItem -Filter '_Configuration.ps1' -Recurse | %{
    # Launch Backup-VM.ps1 and pass _Configuration.ps1's path in
    Start-Process -FilePath 'powershell.exe' -ArgumentList @('-File', 'Backup-VM.ps1', '-vCenterFolder', "`"$($_.DirectoryName)`"")
}

_Configuration.ps1

$Enable = $true

# Below is a sample to backup VMs
# VM - the VM name in vCenter
# Host - VMHost name in vCenter
# Datastore - Datastore name in vCenter in Host
<#
Sample:
$Entries = @(
@{VM = 'VMName01'; Host = 'TargetESXiServerName02'; Datastore = 'TargetESXiServerName02:storage1'; Reserve = 1;},
@{VM = 'VMName02'; Host = 'TargetESXiServerName01'; Datastore = 'TargetESXiServerName01:storage2'; Reserve = 1;}
)
#>

# Actual data filled in
$Entries = @(

)

# vCenter server name or IP address
$vCenter = 'vCenter01'

# Mail setting part, only there are errors needs manual work will be triggered. normal backup job will not trigger the alert.
$From =  "$($env:COMPUTERNAME)@test.com"
$To = "AlertNeedsToSend@test.com"
$Subject = "VMs backup completed with errors - $vCenter"
$SmtpServer = 'mailgateway'

Backup-VM.ps1 - Entscheidet automatisch, welche Sicherungsmethode verwendet wird: Wenn die VM VDS (vSphere Distributed Switch) nutzt, wählt das Skript die API-Sicherung; wenn die VM einen normalen vSphere Standard Switch verwendet, kann das Skript New-VM verwenden, um die VM zu klonen. (Nach Verwendung von VDS schlägt New-VM fehl, es sei denn, sowohl der ursprüngliche als auch der Ziel-ESXi-Server verfügen über identische VDS-Einstellungen)

PARAM(
    [parameter(Mandatory=$true)]
    [string]$vCenterFolder
)

# Enter directory of _Configuration.ps1
Set-Location -Path $vCenterFolder

$Date = Get-Date
$strDate = $Date.ToString("yyyy-MM-dd")
$strLogFile = "${strDate}.log"

# Import _Configuration.ps1 variables
. '.\_Configuration.ps1'

# Define a logging function
function Add-Log
{
    PARAM(
        [String]$Path,
        [String]$Value,
        [String]$Type = 'Info'
    )
    $Type = $Type.ToUpper()
    $Date = Get-Date
    Write-Host "$($Date.ToString('[HH:mm:ss] '))[$Type] $Value" -ForegroundColor $(
        switch($Type)
        {
            'WARNING' {'Yellow'}
            'Error' {'Red'}
            default {'White'}
        }
    )
    if($Path){
        Add-Content -LiteralPath $Path -Value "$($Date.ToString('[HH:mm:ss] '))[$Type] $Value" -ErrorAction:SilentlyContinue
    }
}

Add-Log -Path $strLogFile -Value 'New backup started'
# Whether the configuration is enabled or not
if(!$Enable)
{
    Add-Log -Path $strLogFile -Value 'Repository disabled'
    exit
}

# $vCenter is necessary, without it, script doesn't know where to connect to
if(!$vCenter)
{
    Add-Log -Path $strLogFile -Value 'vCenter variable is null, can not continue' -Type Error
    $Alert = $true
}
else
{
    Add-Log -Path $strLogFile -Value "vCenter: [$vCenter]"
}

# Looking for necessary snapin, early version of PowerCli has no snapin for VDS, output some information to ensure the environment of the script
if(!(Get-PSSnapin -Name '*VMware.VimAutomation.Vds*' -Registered -ErrorAction:SilentlyContinue))
{
    Add-Log -Path $strLogFile -Value 'This script is built from [VMware vSphere PowerCLI 5.5], suggest to run on the version' -Type Error
    Add-Log -Path $strLogFile -Value 'PSSnapin [VMware.VimAutomation.Vds] is not found, which could cause backup failure' -Type Error
    Add-Log -Path $strLogFile -Value 'Installer path: [ServerVMwarevSphereVMware-PowerCLI-5.5.0-1295336.exe]' -Type Info
    exit
}

# Add snapin
if(!(Get-PSSnapin '*vmware*' -ErrorAction:SilentlyContinue))
{
    Add-PSSnapin *vmware*
    if(!$?)
    {
        Add-Log -Path $strLogFile -Value 'Failed to add vmware pssnapin' -Type Error
        Add-Log -Path $strLogFile -Value $Error[0] -Type Error
        exit
    }
}

# Connect to vCenter,if error, set $Alert to $true to trigger alert at last
Connect-VIServer -Server $vCenter -Force
if(!$?)
{
    Add-Log -Path $strLogFile -Value 'Failed to connect to vCenter, cause:' -Type Error
    Add-Log -Path $strLogFile -Value $Error[0] -Type Error
    $Alert = $true
}

$Tasks = @()
# Loop every VM backup item
foreach($e in $Entries)
{
    Add-Log -Path $strLogFile -Value "Start doing backup for: [$($e.VM)]"
    # Add a new VM name as "%OLDVMName%_ScriptBackup_%CurrentDate%"
    $VMNew = "$($e.VM)_ScriptBackup_$strDate"
    $e.NewVM = $VMNew
    $VM = $null
    $VM = @(Get-VM -Name $e.VM -ErrorAction:SilentlyContinue)
    if(!$VM)
    {
        Add-Log -Path $strLogFile -Value 'Capture none VM, does the VM exists?' -Type Warning
        continue
    }
    if($VM.Count -ge 2)
    {
        Add-Log -Path $strLogFile -Value "Capture [$($VM.Count)] VM, duplicated VMs?: [$(($VM | %{$_.Id}) -join '], [')]" -Type Warning
        continue
    }
    $VM = $VM[0]

    # only one VM captured, no confuse to script
    $VMHost = $null
    $VMHost = @(Get-VMHost -Name $e.Host -ErrorAction:SilentlyContinue)
    if(!$VMHost)
    {
        Add-Log -Path $strLogFile -Value "Capture none VMHost, does the VMHost exists?: [$($e.Host)]" -Type Warning
        continue
    }
    if($VMHost.Count -ge 2)
    {
        Add-Log -Path $strLogFile -Value "Capture [$($VMHost.Count)] VMHost, duplicated VMHosts?: [$(($VMHost | %{$_.Id}) -join '], [')]" -Type Warning
        continue
    }
    $VMHost = $VMHost[0]

    # only one VMHost captured, no confuse to script
    $Datastore = $null
    $Datastore = @($VMHost | Get-Datastore -Name $e.Datastore -ErrorAction:SilentlyContinue)
    if(!$Datastore)
    {
        Add-Log -Path $strLogFile -Value "Capture none Datastore, does the Datastore exists on VMHost?: [$($e.Datastore)]" -Type Warning
        continue
    }
    if($Datastore.Count -ge 2)
    {
        Add-Log -Path $strLogFile -Value "Capture [$($Datastore.Count)] Datastore, duplicated Datastores?: [$(($Datastore | %{$_.Id}) -join '], [')]" -Type Warning
        continue
    }
    $Datastore = $Datastore[0]

    # only one Datastore captured, no confuse to script
    Add-Log -Path $strLogFile -Value "INFO[OLDName][NewName][Host][Datastore]: [$($VM.Name)][$VMNew][$($VMHost.Name)][$($Datastore.Name)]"

    # Whether the VM is using VDS
    $VDS = $null
    $VDS = $VM | Get-VDSwitch -ErrorAction:SilentlyContinue
    if(!$VDS)
    {
        # if VDS is not placed, use New-VM to clone
        Add-Log -Path $strLogFile -Value 'VDSwitch not found on the VM, use commandlet [New-VM] to clone'
        $Task = $null
        $Task = New-VM -Name $VMNew -VM $VM -VMHost $VMHost -Datastore $Datastore -RunAsync -ErrorAction:SilentlyContinue
        if(!$?)
        {
            Add-Log -Path $strLogFile -Value 'New-VM failed, cause:' -Type Warning
            Add-Log -Path $strLogFile -Value $Error[0] -Type Warning
            continue
        }
        Add-Log -Path $strLogFile -Value "Task launched: [$($Task.Id)]"
        $Tasks += $Task.Id
    }
    else
    {
        # using VDS, use API to clone
        Add-Log -Path $strLogFile -Value 'VDSwitch found on the VM, need to use 2nd way to clone VM'
        Add-Log -Path $strLogFile -Value "VDS [Name][KEY]: [$(($VDS | %{$_.Name}) -join ';')][$(($VDS | %{$_.Key}) -join ';')]"
        $TargetVDS = $null
        $TargetVDS = @($VMHost | Get-VDSwitch -ErrorAction:SilentlyContinue)
        # on target VMHost search VDS, if target ESXi has no VDS, clone will fail
        if(!$TargetVDS)
        {
            Add-Log -Path $strLogFile -Value 'Target VMHost server has no VDSwitch, VM which uses a VDS is unable to clone to the VMHost' -Type Warning
            continue
        }
        $TargetVDS = $TargetVDS[-1]
        # capture VDS and pick the one owns most number of ports
        $TargetVDSGroup = @($TargetVDS | Get-VDPortgroup | Sort-Object NumPorts)[-1]
        Add-Log -Path $strLogFile -Value "Target VDS randomly picked [Name][Key]: [$($TargetVDS.Name)][$($TargetVDS.Key)]"

        # API nesessary, use default resource pool of ESXi server is fine
        $Pool = $null
        $Pool = @($VMHost | Get-ResourcePool)[0]
        if(!$Pool)
        {
            Add-Log -Path $strLogFile -Value 'No resource pool found from VMHost, please use Get-ResourcePool to find resource pool on the VMhost' -Type Warning
            continue
        }

        # Capture VM's network adapter, change it to use VDS on target ESXi
        $VMNic = $null
        $VMNic = $VM.ExtensionData.Config.Hardware.Device | ?{$_.DeviceInfo.Label -imatch 'Network adapter'}
        if($VMNic.Count -ge 2)
        {
            Add-Log -Path $strLogFile -Value 'The VM has more than 2 network adapters, not supported' -Type Warning
            continue
        }
        $VMNicBacking = $VMNic.Backing
        $VMNicBacking.Port.SwitchUuid = $TargetVDS.Key
        $VMNicBacking.Port.PortgroupKey = $TargetVDSGroup.Key
        $VMNicBacking.Port.PortKey = ''
        $VMNicBacking.Port.ConnectionCookie = ''
        
        # API necessary
        $spec = New-Object VMware.Vim.VirtualMachineCloneSpec
        $spec.Config = New-Object VMware.Vim.VirtualMachineConfigSpec
        $nicDev = New-Object VMware.Vim.VirtualDeviceConfigSpec
        $nicDev.Operation = 'edit'
        $nicDev.Device = $VMNic
        $nicDev.Device.Backing = $VMNicBacking
        $spec.Config.DeviceChange = $nicDev
        $spec.Config.DeviceChange[0].Device.Backing.Port.PortKey = ''
        $spec.Location = New-Object VMware.Vim.VirtualMachineRelocateSpec
        $spec.Location.Host = $VMHost.ExtensionData.MoRef
        $spec.Location.Datastore = $Datastore.ExtensionData.MoRef
        $spec.Location.Pool = $Pool.ExtensionData.MoRef
        $spec.PowerOn = $false
        $spec.Template = $false

        Add-Log -Path $strLogFile -Value 'Trying to get datacenter object, this could potentially cause a dead loop!'
        # to get the $Folder for API, must get datacenter of ESXi first
        $Datacenter = $VMHost.Parent
        while($Datacenter.Id -notmatch 'Datacenter')
        {
            $Datacenter = $Datacenter.Parent
        }
        # API necessary
        $Folder = $Datacenter | Get-Folder -Name 'Discovered virtual machine'
        Add-Log -Path $strLogFile -Value 'Did not fail into a dead loop!'

        # use API to launch clone task
        $Task = $null
        $Task = $VM.ExtensionData.CloneVM_Task($Folder.ExtensionData.MoRef, $VMNew, $spec)
        if(!$?)
        {
            Add-Log -Path $strLogFile -Value 'CloneVM_Task failed, cause:' -Type Warning
            Add-Log -Path $strLogFile -Value $Error[0] -Type Warning
            continue
        }
        Add-Log -Path $strLogFile -Value "Task launched: [$($Task.Type)-$($Task.Value)]"
        $Tasks += "$($Task.Type)-$($Task.Value)"
    }
}

$Tasks = @($Tasks | ?{$_})
Add-Log -Path $strLogFile -Value "Waiting for tasks to complete, count: [$($Tasks.Count)]"
while($Tasks)
{
    # clone is running asynchronously, so script needs to trace all tasks every 5 minutes
    # The sleep time better not exceed 15 minutes, due to vCenter will clean completed tasks after 15 minutes
    # when debugging, change the time to 10 seconds is fine
    Start-Sleep -Seconds 300
    $Tasks = Get-Task -Id $Tasks -ErrorAction:SilentlyContinue
    if(!$?)
    {
        Add-Log -Path $strLogFile -Value 'Failed to refresh Task states, cause:' -Type Warning
        Add-Log -Path $strLogFile -Value $Error[0] -Type Warning
    }
    $Tasks = @(
        $Tasks | %{
            if($_.State -ne 'Running')
            {
                Add-Log -Path $strLogFile -Value "Task completed [ID][State]: [$($_.Id)][$($_.State)]"
                if($_.State -eq 'Error')
                {
                    Add-Log -Path $strLogFile -Value $_.ExtensionData.Info.Error.LocalizedMessage -Type Warning
                }
            }
            else
            {
                Add-Log -Path $strLogFile -Value "Task running [ID][% Complete]: [$($_.Id)][$($_.PercentComplete)%]"
                $_.Id
            }
        }
    )
}

# script will start verification for VM backups after all Tasks done
Add-Log -Path $strLogFile -Value 'Verification start'
foreach($e in $Entries)
{
    if((Get-VM -Name $e.NewVM -ErrorAction:SilentlyContinue) -and $?)
    {
        # Backup VM found in vCenter, suggest the backup was succeed
        Add-Log -Path $strLogFile -Value "[VM][NewVM]: [$($e.VM)][$($e.NewVM)] -- New VM found in vCenter"
        if($e.Reserve)
        {
            # If Reserve's valud is set, script will find all backups for the VM, and remove addtionals
            $VMBackups = $null
            $VMBackupsRemoval = $null
            $VMBackups = Get-VM -Name "$($e.VM)_ScriptBackup_*" | ?{$_.Name -imatch '_ScriptBackup_d{4}-d{2}-d{2}$'} -ErrorAction:SilentlyContinue
            $VMBackups = @($VMBackups | Sort-Object 'Name')
            Add-Log -Path $strLogFile -Value "Old VM backups captured: [$($VMBackups.Count)][$(($VMBackups | %{$_.Name}) -join ';')]"
            $i = $VMBackups.Count - $e.Reserve
            if($i -le 0)
            {
                $i = 0
                Add-Log -Path $strLogFile -Value 'No old backups available to be removeds'
            }
            if($i -gt 0)
            {
                Add-Log -Path $strLogFile -Value "VM old backups can be removed count: [$i]"
                $VMBackupsRemoval = $VMBackups[0..(--$i)]
                Remove-VM -VM $VMBackupsRemoval -DeletePermanently -Confirm:$false
            }
        }
    }
    else
    {
        # backup VM not found in vCenter which means backup failed, better do nothing
        Add-Log -Path $strLogFile -Value "[VM][NewVM]: [$($e.VM)][$($e.NewVM)] -- New VM not found in vCenter, backup failure?" -Type Warning
        $Alert = $true
    }
}

Add-Log -Path $strLogFile -Value 'All done!'

# If there is error needs manual work, email will be triggered
if($Alert)
{
    Send-MailMessage -To $To -From $From -SmtpServer $SmtpServer -Subject $Subject -Attachments $strLogFile
    if(!$?)
    {
        Add-Log -Path $strLogFile -Value 'Failed to send email, cause:' -Type Warning
        Add-Log -Path $strLogFile -Value $Error[0] -Type Warning
    }
}

Wie sichert man ESXi-VMs mit Enterprise-Backup-Software?

Das Skript bietet eine kostenlose Lösung zur Sicherung von ESXi-VMs, eignet sich jedoch nicht gut für die Unternehmens-Disaster-Recovery-Lösung, da es keine umfassende Backup-Lösung ist und keine schnelle VM-Wiederherstellung ermöglicht. Unternehmen sollten über eine professionellere Lösung verfügen.

Vinchin Backup & Recovery ist eine von VMware verifizierte professionelle Enterprise-Backup-Lösung, die ein Backup auf Gastebene für VMware vSphere unterstützt.

Die Bereitstellung in der virtuellen Umgebung dauert nur wenige Minuten, danach hilft Ihnen eine benutzerfreundliche Webkonsole dabei, einfach einen Sicherungsauftrag mit den erforderlichen Strategien zu erstellen.

1. Fügen Sie den ESXi-Host mit seinen Anmeldedaten hinzu, um VMs darauf agentenlos zu sichern

VMware-Host hinzufügen

2. Wählen Sie den ESXi-Host aus und anschließend die darauf befindlichen VMs

VMware-VMs auswählen

3. Wählen Sie den Sicherungsspeicher aus

Sicherungsspeicher auswählen

4. Wählen Sie die Sicherungsstrategien aus. Beispielsweise stehen Ihnen Inkrementelle Sicherung, Datenkomprimierung, BitDetector usw. zur Verringerung des Sicherungsumfangs, Datenverschlüsselung für die Datensicherheit sowie LAN-freie Übertragung zur Minderung der Auswirkungen auf die Produktionsumgebung zur Verfügung.

Sicherungsstrategien auswählen

5. Überprüfen Sie einfach den Sicherungsauftrag und senden Sie ihn ab

VMware-Sicherungsauftrag einreichen

Um die Wiederherstellung nach einer Katastrophe zu erleichtern, ermöglicht Vinchin Instant Recovery, eine ausgefallene VM innerhalb von 15 Sekunden aus der Sicherung sofort wiederherzustellen. Zur besseren Verwaltung einer Multi-Hypervisor-Umgebung können Sie eine ESXi-VM auf einem anderen Host wie XenServer und RHV wiederherstellen und umgekehrt.

Vinchin Backup & Recovery wurde bereits von Tausenden von Unternehmen ausgewählt, und Sie können hier eine 60-tägige kostenlose Testversion mit vollem Funktionsumfang starten. Außerdem können Sie uns kontaktieren, Ihre Anforderungen hinterlassen und anschließend Ihre individuelle Lösung erhalten. Wir haben Partnerschaften mit renommierten Unternehmen auf der ganzen Welt aufgebaut. Wenn Sie daher ein lokales Geschäft tätigen möchten, können Sie hier einen lokalen Partner auswählen.

Sicherung von ESXi-VMs mit Skripten – Häufig gestellte Fragen

F1: Benötige ich spezielle Berechtigungen, um ESXi-Sicherungsskripte auszuführen?

A1: Ja, Sie benötigen ein ESXi-Konto mit ausreichenden Berechtigungen, um auf VMs zuzugreifen und diese zu exportieren.

F2: Kann das Skript mehrere VMs gleichzeitig sichern?

A2: Ja, Sie können im Skript durch VM-Namen schleifen, um mehrere VMs automatisch zu sichern.

F3: Verarbeitet das Skript VM-Snapshots?

A3: Die meisten Skripte verwenden Snapshots, um vor dem Exportieren von VM-Dateien konsistente Sicherungen sicherzustellen.

Zusammenfassung

ESXi kann einen Bare-Metal-Physischen Server virtualisieren, sodass Unternehmen die darauf verfügbaren Hardware-Ressourcen besser nutzen können. Um Daten auf dem Server zu sichern, können Unternehmen jede VM einzeln sichern, sodass beim Wiederherstellen einer ausgefallenen VM die anderen VMs nicht beeinträchtigt werden.

Außer der manuellen Exportierung einer VM aus vCenter gibt es auch die Möglichkeit, Skripte auszuführen, um die ESXi-VM mit weiteren Optionen zu sichern.

Es gibt auch eine Lösung, die besser ist als Skripte. Vinchin Backup & Recovery ist eine professionelle Enterprise-Backup-Lösung für VMware ESXi-VMs und bietet mit einfachen Bedienung einen umfassenderen Schutz für die virtuelle Umgebung. Verpassen Sie nicht die kostenlose Testversion.

Teilen auf:

Categories: VM Backup