Menu

Virtual Geek

Tales from real IT system administrators world and non-production environment

Automating Linux VM Cloning and IP Configuration on Nutanix with PowerShell

This simple PowerShell script clones Nutanix Linux virtual machines. To use this script, first download and install the PowerShell cmdlets from Nutanix Prism Central. You can find the installed plugin folder under C:\Program Files(x86)\Nutanix folder. From there you can load plugins.

A screenshot of the Nutanix Prism Central web interface dropdown menu under the help icon. The menu highlights options for 'Download Cmdlets' and 'Download nCLI' in a red box, along with links for Update Profile, REST API Explorer powershell, and Sign Out.

After installation, import the NutanixCmdletsPSPlugin in PowerShell v5.1. Note that the PsPlugin is not compatible with latest PowerShell version 6 and above.
The script output will display the cloning progress, IP configuration, and other details. Since cloud-init wasn't working, the script uses a custom technique to configure the Linux IP. 

PowerShell terminal showing the execution of a Nutanix AHV cloning script, displaying progress for VM creation, IP configuration, and a list of available Nutanix cmdlets clone virtual machine vm linux

Make sure template VM is shutdown but after clone IP is reachable. Fill up the CSV file with the template VM IP and new cloned VM IP details, and the script will take care of the rest 😊.

Related Article: Automating Windows VM Cloning and sysprep on Nutanix with PowerShell

Download this script Nunanix_Linux_VM_Clone_Complete.zip here | It is also available on github.com.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#Import-Module Nutanix.Cli -Prefix Ntnx
#Import-Module Nutanix.Prism.Common -Prefix Ntnx
#Import-Module Nutanix.Prism.PS.Cmds -Prefix Ntnx

$prism = '192.168.34.101'
$userName = 'admin'
$password = 'Computer@123'
$csvFile = 'Clone_Linux_VMs.csv'

$sourceVMUsername = 'linuxadmin'
$sourceVMPassword = 'Computer@123'

$secureString = ConvertTo-SecureString -String $password -Force -AsPlainText
#$credntial = [System.Management.Automation.PSCredential]::new($username,$secureString)

$ntnxConnection = Connect-NTNXCluster -Server $prism -UserName $userName -Password $secureString -AcceptInvalidSSLCerts -ForcedConnection
#Connect-NutanixV3PrismServer #Disconnect-NutanixV3PrismServer Connect-NtnxPrismCentral 
Write-Host "$((Get-Date).DateTime) | Server: $($ntnxConnection.Server) | IsConnected: $($ntnxConnection.IsConnected) | UserName: $($ntnxConnection.UserName)"

$currentPath = $PSScriptRoot
$csvInfo = Import-Csv -Path $currentPath\$csvFile

foreach ($row in $csvInfo)
{
    $sourceVMName = $row.SourceVMName
    $sourceVM = Get-NTNXVM | Where-Object {$_.vmName -eq $sourceVMName }
    $newVMName = $row.NewVMName
    Write-Host "$((Get-Date).DateTime) | SourceVM: $sourceVMName | isFound: Yes"

    $cloneSpec = New-NTNXObject -Name VMCloneSpecDTO 
    $cloneSpec.name = $newVMName

    Write-Host "$((Get-Date).DateTime) | NewVM: $newVMName | isCloning: Yes"
    Clone-NTNXVirtualMachine -vmId $sourceVM.VmId -SpecList $cloneSpec | Out-Null

    $cloneTask = Get-NTNXTask | Where-Object {($_.operationType -match 'VmClone|SnapshotCreate') -or ($_.progressStatus -eq 'VmClone')}
    While ($cloneTask)
    {
        Write-Host "$((Get-Date).DateTime) | NewVM: $newVMName | OperationType: $($cloneTask.operationType[0]) | ProgressStatus: $($cloneTask.progressStatus[0])"
        $cloneTask = Get-NTNXTask | Where-Object {($_.operationType -match 'VmClone|SnapshotCreate') -or ($_.progressStatus -eq 'VmClone')}
        #$cloneTask | Select-Object operationType, progressStatus
        Start-Sleep -Seconds 10
    }
    Write-Host "$((Get-Date).DateTime) | NewVM: $newVMName | isCloned: Yes"
    
    #Write-Host "PowerOn VM: $newVMName"
    $createdVM = Get-NTNXVM | Where-Object {$_.vmName -eq $newVMName }
    $powerOnTask = Set-NTNXVMPowerOn -VmId $createdVM.vmId
    While (Test-Connection -ComputerName $row.SourceVMIP -Count 1 -Quiet )
    {
        #$powerOnTask
        Write-Host "$((Get-Date).DateTime) | NewVM: $newVMName | isPoweredOn: Running"
        Start-Sleep -Seconds 15
    }
    Start-Sleep -Seconds 10
    Write-Host "$((Get-Date).DateTime) | NewVM: $newVMName | isPoweredOn: Completed"
    #Get-NTNXTask
    if (Test-Path $currentPath\suppliments\set-newip.sh)
    {
        Remove-Item $currentPath\suppliments\set-newip.sh -Force
    }

$newIpConfig = @"
#!/bin/bash
sudo nmcli con mod "$($row.SourceVMEthName)" ipv4.method manual
sudo nmcli con mod "$($row.SourceVMEthName)" ipv4.addresses $($row.NewVMIP)/$($row.NewVMSubnet)
sudo nmcli con mod "$($row.SourceVMEthName)" ipv4.gateway $($row.NewVMGateway)
sudo nmcli con mod "$($row.SourceVMEthName)" ipv4.dns "192.168.34.11,192.168.34.12"
sudo nmcli con down "$($row.SourceVMEthName)"
sudo nmcli con up "$($row.SourceVMEthName)"
exit
"@

    $newIpConfig | Out-File -FilePath "$currentPath\suppliments\set-newip.sh" -Force #-Encoding utf8
    Write-Host "$((Get-Date).DateTime) | NewVM: $newVMName | isCopyShScriptIP: Running"
    sshpass -p "$sourceVMPassword" scp -o StrictHostKeyChecking=no "$currentPath\suppliments\set-newip.sh" "unixsupport@$($row.SourceVMIP):/tmp"
    Write-Host "$((Get-Date).DateTime) | NewVM: $newVMName | isCopyShScriptIP: Completed | isShScriptSetx: Running"
    #dos2unix required utf8
    sshpass -p "$sourceVMPassword" ssh -o StrictHostKeyChecking=no unixsupport@$($row.SourceVMIP) 'dos2unix /tmp/set-newip.sh; chmod +x /tmp/set-newip.sh'
    Write-Host "$((Get-Date).DateTime) | NewVM: $newVMName | isShScriptSetx: Completed | isNewIpSet: Running"
    #sshpass -p "$sourceVMPassword" ssh -o StrictHostKeyChecking=no unixsupport@$($row.SourceVMIP) 'chmod +x /tmp/set-newip.sh'
    sshpass -p "$sourceVMPassword" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -o ServerAliveInterval=5 [email protected] "sudo /tmp/set-newip.sh"
    Start-Sleep -Seconds 2
    if (Test-Connection -ComputerName $($row.NewVMIP) -Count 2 -Quiet)
    {
        Write-Host "$((Get-Date).DateTime) | NewVM: $newVMName | isNewIpSet: Completed" -BackgroundColor DarkGreen
    }
    else {
        Write-Host "$((Get-Date).DateTime) | NewVM: $newVMName | isNewIpSet: Failed" -BackgroundColor DarkRed
    }
        
}

Useful Articles
Esxi Registration unregistration of third-party IO filter storage providers fails on a host
VMware LifeCycle Manager There are conflicts from the patches selected for staging or remediation
How to update a patch on an ESXi host via command line
Resetting root password in VMware vCenter Server Appliance
How to reset vCenter Server SSO [email protected] password
vCenter Server SSH received disconnect Too many authentication failures
vCenter Server Public Key Authentication configuration SSH error received disconnect Too many authentication failures
VMware vCenter server vcsa Setting IP IPv6 configuration failed, IP configuration not allowed
PowerCLI The SSL connection could not be established see inner exception
PowerCLi Connect-VIServer could not connect using the requested protocol
VMware vCenter Server Management Exception in invoking authentication handler user password expired
vCenter ui sorry this website doesn't exist 404 not found
Unable to save IP settings Install Stage 2 Set up vCenter Server configuration
VMware vCenter server Error no healthy upstream

Go Back

Comment

Protected by Mathcha

Blog Search

Page Views

1 4 6 7 6 7 8 9

Archive

Follow me on Blogarama