# 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