VMware ESXi - Skript zum Clonen schreiben

Rubyurek

Commander
Registriert
Sep. 2017
Beiträge
2.476
Momentan arbeite ich mit VMware ESXi (wie man im Titel lesen kann). Die Aufgabe ist, dass ich zwei Virtuelle Maschinen clonen muss. Momentan sind Win10_A und Win10_B vorhanden. Ich möchte gerne ein Skript zusammensetzen womit ich Win10_B Ordner erstelle > Win10_A auf Win10_B zu clonen und dann Win10_A zu löschen, damit es zu keiner fehlermeldung kommt. Problem ist, dass ich bei jedem clonen eine neue ID entsteht bei ESXi, somit ist die möglichkeit nicht gegeben, dass ich mit dem Befehl "power.getstate" arbeiten kann.

Wie ist es möglich, dass ich den Klarnamen nutzen kann im Skript? Wie wäre es am besten vorzugehen? Ich habe zur sicherheit noch ein Struktogramm erstellt als überblick was ich vorhabe.

Den momentan code den ich habe ist hier:

Code:
#!bin/bash

1=WinXP_A
2=WinXP_B

# Ordner erstellen > Klonen von A nach B > Ordner A löschen
if vim-cmd vmsvc/power.getstate 46 | grep 'Powered off'
    then 
    mkdir '/vmfs/volumes/datastore1/$2'
    vmkfstools -i '/vmfs/volumes/datastore1/$1/$1.vmdk' '/vmfs/volumes/datastore1/$2/$2.vmdk' 
    rm -r '/vmfs/volumes/datastore1/$1'
    vim-cmd vmsvc/power.on 44
fi

# Ordner erstellen > Klonen von B nach A > Ordner B löschen
if vim-cmd vmsvc/power.getstate 46 | grep 'Powered off'
    then 
    mkdir '/vmfs/volumes/datastore1/$2'
    vmkfstools -i '/vmfs/volumes/datastore1/$1/$1.vmdk' '/vmfs/volumes/datastore1/$2/$2.vmdk' 
    rm -r '/vmfs/volumes/datastore1/$1'
    vim-cmd vmsvc/power.on 44
fi
 

Anhänge

  • struktogramm.png
    struktogramm.png
    11,1 KB · Aufrufe: 359
Zuletzt bearbeitet:
Sktipt ... Powershell, perl, bash, python, ...
 
Du müsstest dir die ID mit sowas wie "get-vm" holen können solange der Name der VM's gleich bleibt.
Ergänzung ()

Müsste " vim-cmd vmsvc/getallvms " sein, un dann halt rausfiltern.
 
Dies habe ich auch probiert. Problem ist halt, dass bei jedem clonen die ID sich ändert. Somit kann ich keine fixe ID einfügen als Varbiable zb.
 
Vermutlich ESXI free oder? Also nur direkt per SSH auf dem ESXi arbeiten und nicht übers vcenter.

Es gibt fertige Scripte dafür im Netz die über PowerCLI arbeiten.
https://github.com/lamw/ghettoVCB

Aber zu deiner konkreten Frage:

Code:
@echo off
for /f "tokens=*" %%a in (searchresults_vmid.txt) do call :processline %%a
echo Test:%bla%
pause
goto :eof

:processline
echo.%* | findstr /C:"VMNAME" 1>nul
set _line=%*
if errorlevel 1 (
  REM nichts gefunden
) ELSE (
  set bla=%_line:~0,7%
)
set _line=
goto :eof

:eof

Ist ein wenig älterer Codesnipsel aus Bash zeiten. Ich habe ein Backup im ESXi Free inzwischen über ein eigenes PS Script umgsetzt. Funktioniert deutlich eleganter.
 
leider ist der skript echt unverständlich und ich kann daraus nicht viel lernen :S
 
naja, was ich vorgescghlagen habe musst du im Script jedes mal ausführen, sprechend etwa so geschrieben:

gib mir id zu VM mit Namen WIN_a
Tests Status ID-a
...
Ergänzung ()

Und nach dem clonen:

Clone A zu B
gib mir ID zu VM mit Namen Win_b
ID-b start
 
Zuletzt bearbeitet:
Momentan ist die ID für Win10_A 47 und WIn10_B 48
 
Ja Bash ist da sehr unschön. zumindest das was ich mit meinen marginalen Fähigkeiten hinbekommen habe.

Muss es denn Bash sein?

Für PS hätte ich sogar ein Script parat was fast 1zu1 das umsetzt was du möchtest. Auch wenn ich dir das nicht komplett überlassen kann, so kann ich dir doch wesentliche Codefetzen und Hinweise geben ;)

Voraussetzung wäre aber ein Windows PC mit dem du den ESXi im Netz erreichen kannst. Sollte ja nicht so das Problem sein.
 
ich nutze ja putty um auf den vmware zuzugreifen.
 
Baalthorun schrieb:
Für PS hätte ich sogar ein Script parat was fast 1zu1 das umsetzt was du möchtest. Auch wenn ich dir das nicht komplett überlassen kann, so kann ich dir doch wesentliche Codefetzen und Hinweise geben

Es wäre schön, wenn du mir paar Codefetzen bereitstellen könntest. Wenn ich nicht weite weiss frage ich hier weiter :p
 
Ich habe mal mein Code ergänzt:

Code:
#!bin/bash

1=$(vim-cmd vmsvc/power.getstate /vmfs/volumes/datastore1/WinXP_A/WinXP_A.vmx | grep "Powered off")
2=$(vim-cmd vmsvc/power.getstate /vmfs/volumes/datastore1/WinXP_A/WinXP_B.vmx | grep "Powered off")

A=/vmfs/volumes/datastore1/WinXP_A
AA=WinXP_A.vmdk
AAA=WinXP_A.vmx

B=/vmfs/volumes/datastore1/WinXP_B
BB=WinXP_B.vmdk
BBB=WinXP_B.vmx

# Ordner erstellen > Klonen von A nach B > Ordner A löschen
if [ "$1" == "Powered on" ]
    
    then    vim-cmd vmsvc/power.shutdown $A/$AA
            rm -r $B
            vmkfstools -i '$A/$AA' '$B/$BB'
            vim-cmd vmsvc/power.on $B/$BB
    
    else    vim-cmd vmsvc/power.shutdown $B/$BB
            rm -r $A
            vmkfstools -i $B/$BB $A/$AA
            vim-cmd vmsvc/power.on $A/$AAA
            
fi
 
Hab mal ein wenig rauskopiert und Anpassungen für speziell unsere Umgebung rausgenommen oder durch Variablen ersetzt. Sowie das Ganze ein wenig übersichtlicher gestalltet. Hoffe ich habe alles erwischt und den Code damit nicht komplett zerschossen.

Das wären so die absoluten Basics um nur eine Maschine zu clonen. Alles weitere kann man daraus ja aber erarbeiten.

Prerequisites:
PowerShell 4.0
PS Modul PoshSSH

Evtl kann man das mit dem Modul PowerCLI noch einfacher lösen aber so geht es auch.

Code:
# Einmal Futter fürs Script
$dnsname = "esxi01.contoso.com"
$user = "root"
$volume = "internal_10k_blabla"
$sourcename = "Win10_A"
$clonename = "Win10_B"

# Passwort für den Esxi abfragen
write-host "Input Password for ESXi user: $user"
$pass_input = Read-Host -AsSecureString "Password"
$Script:Credentials = New-Object System.Management.Automation.PSCredential($u, $pass_input)

# SSH Verbindung mit PoshSSH aufbauen
$SSHSession = New-SSHSession -ComputerName $dnsname -Credential $Credentials

# Leere Tabelle für die VMs und die dazugehörigen IDs anlegen
$tab_machines = New-Object system.Data.DataTable “machinelist”
$col1 = New-Object system.Data.DataColumn ID,([string])
$col2 = New-Object system.Data.DataColumn Machine,([string])
$col3 = New-Object system.Data.DataColumn VMID,([string])
$tab_machines.columns.add($col1)
$tab_machines.columns.add($col2)
$tab_machines.columns.add($col3)

# Machinen und IDs auf dem ESXi abfragen
$result_vmid = Invoke-SSHCommand -SSHSession $CurrentSession -Command $com_getallvms
$counter_ls = 0
$resultlsOutputString = $result_vmid.output
$resultlsOutputString |
    Select-String -Pattern "([A-Za-z]+[\d\S A-Za-z]+)" -AllMatches |
        ForEach-Object {$_.matches} |
            ForEach-Object {
                $counter_ls++
                $row = $tab_machines.NewRow()
                $row.ID = $counter_ls
                $row.Machine = $_.value
                $tab_machines.Rows.Add($row)
               }
$counter_ls = 0
$resultlsOutputString |
    Select-String -Pattern "([\d]+)" -AllMatches |
        ForEach-Object {$_.matches} |
            ForEach-Object {
                $counter_ls++
                $vmid = $_.value
                $tab_machines | where {$_.ID -eq $counter_ls} | foreach {$_.VMID = "$vmid"}
                }

# Einmal die Tabelle zum Check ausgeben. Das kannst dir final natürlich sparen.
$tab_machines

# Quellvmid ermitteln
$sourcevmid = $tab_machines  | where {$_.machine -eq $sourcename} | foreach { $_.VMID }

# Zielvmid ermitteln
$targetvmid = $tab_machines | where {$_.machine -eq $clonename} | foreach { $_.VMID }
if ($targetvmid) {write-host "Clone of $vm found - overwrite";$clonefound = "1"}
else {write-host "No clone of $vm found - create new"}



# evtl vorhandene Snapshots löschen und einen neuen generieren
$void = Invoke-SSHCommandStream -SSHSession $CurrentSession -Command "vim-cmd vmsvc/snapshot.removeall $sourcevmid"
$void = Invoke-SSHCommandStream -SSHSession $CurrentSession -Command "vim-cmd vmsvc/snapshot.create $sourcevmid clone"

# Registrierung einer vorhandene VM aufheben
if($clonefound){$void = Invoke-SSHCommandStream -SSHSession $CurrentSession -Command "vim-cmd vmsvc/unregister $targetvmid"}

# Verzeichnis inkl. Inhalt löschen und neu anlegen
$rmbkpfolder = "rm -r /vmfs/volumes/"+$volume+"/"+$clonename
Invoke-SSHCommandStream -SSHSession $CurrentSession -Command $rmbkpfolder
$mkbkpfolder = "mkdir /vmfs/volumes/"+$volume+"/"+$clonename
Invoke-SSHCommandStream -SSHSession $CurrentSession -Command $mkbkpfolder

# Kopieren der VMDK File
Write-Host -ForegroundColor Yellow "------------------------------------------------------------------"
Write-Host -ForegroundColor Yellow "Cloning virtual machine files - This may take a while to complete!"
Write-Host -ForegroundColor Yellow "------------------------------------------------------------------"
$copyvmdk = "vmkfstools -i /vmfs/volumes/"+$volume+"/"+$sourcename+"/"+$sourcename+".vmdk -d thin /vmfs/volumes/"+$volume+"/"+$clonename+"/"+$clonename+".vmdk"
$void = Invoke-SSHCommandStream -SSHSession $CurrentSession -timeout 600 -Command $copyvmdk

# Erstellten Snapshot entfernen
$void = Invoke-SSHCommandStream -SSHSession $CurrentSession -Command "vim-cmd vmsvc/snapshot.removeall $sourcevmid"

# Kopieren der verbleibenden Files der original VM (Für eine VM mit einer Platte.. ggf. anpassen)
$copynvram = "cp /vmfs/volumes/"+$volume+"/"+$sourcename+"/"+$sourcename+".nvram /vmfs/volumes/"+$volume+"/"+$clonename+"/"+$clonename+".nvram"
Invoke-SSHCommandStream -SSHSession $CurrentSession -Command $copynvram
$copyvmsd = "cp /vmfs/volumes/"+$volume+"/"+$sourcename+"/"+$sourcename+".vmsd /vmfs/volumes/"+$volume+"/"+$clonename+"/"+$clonename+".vmsd"
Invoke-SSHCommandStream -SSHSession $CurrentSession -Command $copyvmsd
$copyvmx = "cp /vmfs/volumes/"+$volume+"/"+$sourcename+"/"+$sourcename+".vmx /vmfs/volumes/"+$volume+"/"+$clonename+"/"+$clonename+".vmx"
Invoke-SSHCommandStream -SSHSession $CurrentSession -Command $copyvmx

# Editieren der VMX File um den Namen und die Zuordnung der Files in der neuen VM anzupassen (auch hier ggf. für weitere Platten anpassen)
$pathvmx = "/vmfs/volumes/"+$volume+"/"+$clonename+"/"+$clonename+".vmx"
$sedvmx1 = "sed -i 's/displayName = `""+$sourcename+"`"/displayName = `""+$clonename+"`"/g' "+$pathvmx
$sedvmx2 = "sed -i 's/nvram = `""+$sourcename+".nvram`"/nvram = `""+$clonename+".nvram`"/g' "+$pathvmx
$sedvmx3 = "sed -i 's/scsi0:0.fileName = `""+$sourcename+".vmdk`"/scsi0:0.fileName = `""+$clonename+".vmdk`"/g' "+$pathvmx
Invoke-SSHCommandStream -SSHSession $CurrentSession -Command $sedvmx1
Invoke-SSHCommandStream -SSHSession $CurrentSession -Command $sedvmx2
Invoke-SSHCommandStream -SSHSession $CurrentSession -Command $sedvmx3

# Den Clone im ESXi registrieren
$registervm = "vim-cmd solo/registervm /vmfs/volumes/"+$volume+"/"+$clonename+"/"+$clonename+".vmx"
$void = Invoke-SSHCommandStream -SSHSession $CurrentSession -Command $registervm


# SSH Verbindung trennen
if($SSHSession){
$result_closessh = Remove-SSHSession -SSHSession $CurrentSession
if ($result_closessh -match "true") {Write-Host -ForegroundColor Cyan "SSH Session to $dnsname_close closed"}
else {Write-Host -ForegroundColor red "ERROR: Cannot close SSH Session to $dnsname "}
}

# Hinterher aufräumen für die Schwiegermutter und wegen der Sicherheit ;)
Clear-Variable $*
pause

ok ist nun doch ein wenig mehr geworden dürfte so aber noch nicht lauffähig sein. Hab ich auch nicht getestet
 
Zuletzt bearbeitet:
Zurück
Oben