My company is currently moving the datacenter to a Co-Location facility. The way the migration is being performed, there are ESXi hosts and shared storage at the colo already. Datastores are being replicated to the storage at the colo to datastores with the same name. The plan was to shutdown the VMs at the datacenter, remove them from inventory, browse the datastore from one of the ESXi hosts at the colo and add the VM back to inventory... rince & repeat.
The problem that we ran into had to do with the fact that each VM has VMDKs on multiple datastores. This process only acknowledged the change of the primary VMDK, the VMX file was still looking for the other 2 volumes on the old datastores, which could not be accessed from the colo.
I have to think that there is a way to script this to avoid this from occuring. If we know the identifier for the new storage volume, we should be able to script it, yes?
I'd like the script to read VM names from a txt file, remove the VM from inventory on host1, browse the datastore from host2 (which is at the colo) and add the VM back to inventory, and then remove & re-add the other volumes based on the name of the datastore (if hard disk 2 is on datastore2 then use 9d0fac87-....)
Any help would be grately appreciated!
Thanks in advance!
- Ben
Hello, BenLiebowitz-
I looked through your script. You had a fair amount of it right on. There were a couple of things to tweak, and a couple of things to correct. Here is the updated script from what I saw could/should change (and, below the code is the explanation of the things that I changed).
# export list of Staging VMs
Get-Folder -Name "Staging" | Get-VM | select Name | Sort Name | Export-CSV "c:\staging.csv" -NoTypeInformation
# Get Staging VMs
$stg = Get-Folder -Name "Staging"
# Shutdown VMs (cleanly)
$stg | Get-VM | Shutdown-VMGuest -Confirm:$false
# Remove Hard Disk 2 and 3
$stg = $null
$stg = Get-Folder -Name "Staging" ## getting Staging folder again
$hdName2 = "Hard disk 2"
$hdName3 = "Hard disk 3"
$stg | Get-VM | Get-HardDisk -Name $hdName2,$hdName3 | Remove-HardDisk -Confirm:$false
# Remove VMs from Inventory
Get-Folder -Name "Staging" | Get-Inventory | Remove-Inventory -Confirm:$false
## then, disconnect from the vCenter to which you were connected
## then, when connected to the vCenter server in the co-location facility:
# Add VMs to Inventory
$esxhost = "prpp6-vmwhst23.i3global.net"
$datastore1 = "someDatastoreName" ## need to set this value!
## and, add hard disks back to VMs
foreach ($row in (Import-Csv c:\staging.csv)) {
$vmName = $row.Name
$vmxfile = "[$datastore1] $vmName/$vmName.vmx"
$vmNewVM = New-VM -VMFilePath $vmxfile -VMhost $esxhost
# Add hard Disks 2 and 3
New-HardDisk -VM $vmNewVM -DiskPath "[transient_deviceid] $vm/$vm.vmdk"
New-HardDisk -VM $vmNewVM -DiskPath "[data_deviceid] $vm/$vm.vmdk"
} ## end foreach
Comments about what I updated/changed:
I would give that a shot with just one machine, and see how things go. Let us know the result.
Hi BenLiebowitz
Welcome to the forums.
Could you please go through below link ,it may help you through GUI instead of script.
Sorry, I am not looking to export a list of VMs to a spreadsheet or anything like that. I am looking for a script that will remove a VM from inventory on one datastore and then re-add it on another. Then, remove Hard Disk 2 and Hard Disk 3 and re-add them on different datastores.
Ok, i wrote a script pieced together from different things I found online.. can someone double check it for me?
# export list of Staging VMs
get-folder -Name "Staging" | get-vm | select Name | Sort Name | Export-CSV "c:\staging.csv" -NoTypeInformation
# Get Staging VMs
$stg = get-folder -Name "Staging"
# Shutdown VMs
Foreach ($VM in ($stg | Get-VM)){
# Shutdown the guest cleanly
$VM | Shutdown-VMGuest -Confirm:$false
}
# Remove Hard Disk 2 and 3
$stg = $null
$stg = get-folder -name "Staging"
Foreach ($VM in ($stg | Get-VM)){
# Remove Transient and Data disks
$hdName2 = “Hard disk 2"
$hdName3 = “Hard disk 3"
$vm = Get-VM $stg| Get-View
$tgtdev = $vm.Config.Hardware.Device | where {$_.DeviceInfo.Label -eq $hdName2}
$dev = New-Object VMware.Vim.VirtualDeviceConfigSpec
$dev.operation = “remove”
$dev.device = $tgtdev
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.DeviceChange += $dev
$vm.ReconfigVM($spec)
$tgtdev = $vm.Config.Hardware.Device | where {$_.DeviceInfo.Label -eq $hdName3}
$dev = New-Object VMware.Vim.VirtualDeviceConfigSpec
$dev.operation = “remove”
$dev.device = $tgtdev
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.DeviceChange += $dev
$vm.ReconfigVM($spec)
}
# Remove VMs from Inventory
get-folder -Name "Staging" | get-inventory | remove-inventory
# Add VMs to Inventory
$esxhost = prpp6-vmwhst23.i3global.net
$vm = $null
$fields = "01.Field 1"
foreach ($add in (import-csv staging.csv)) {
$vm = $vms | Where {$.Name -eq $add."01.Field 1"
$vmxfile = $datastore1 $vm/$vm.vmx
new-vm -VMfilepath $vmxfile -VMhost $esxhost
# Add hard Disk 2 and 3
New-harddisk -VM $vm -DiskPath [transient_deviceid] $vm/$vm.vmdk
new-harddisk -VM $vm -DiskPath [data_deviceid] $vm/$vm.vmdk
}
}
Hello, BenLiebowitz-
I looked through your script. You had a fair amount of it right on. There were a couple of things to tweak, and a couple of things to correct. Here is the updated script from what I saw could/should change (and, below the code is the explanation of the things that I changed).
# export list of Staging VMs
Get-Folder -Name "Staging" | Get-VM | select Name | Sort Name | Export-CSV "c:\staging.csv" -NoTypeInformation
# Get Staging VMs
$stg = Get-Folder -Name "Staging"
# Shutdown VMs (cleanly)
$stg | Get-VM | Shutdown-VMGuest -Confirm:$false
# Remove Hard Disk 2 and 3
$stg = $null
$stg = Get-Folder -Name "Staging" ## getting Staging folder again
$hdName2 = "Hard disk 2"
$hdName3 = "Hard disk 3"
$stg | Get-VM | Get-HardDisk -Name $hdName2,$hdName3 | Remove-HardDisk -Confirm:$false
# Remove VMs from Inventory
Get-Folder -Name "Staging" | Get-Inventory | Remove-Inventory -Confirm:$false
## then, disconnect from the vCenter to which you were connected
## then, when connected to the vCenter server in the co-location facility:
# Add VMs to Inventory
$esxhost = "prpp6-vmwhst23.i3global.net"
$datastore1 = "someDatastoreName" ## need to set this value!
## and, add hard disks back to VMs
foreach ($row in (Import-Csv c:\staging.csv)) {
$vmName = $row.Name
$vmxfile = "[$datastore1] $vmName/$vmName.vmx"
$vmNewVM = New-VM -VMFilePath $vmxfile -VMhost $esxhost
# Add hard Disks 2 and 3
New-HardDisk -VM $vmNewVM -DiskPath "[transient_deviceid] $vm/$vm.vmdk"
New-HardDisk -VM $vmNewVM -DiskPath "[data_deviceid] $vm/$vm.vmdk"
} ## end foreach
Comments about what I updated/changed:
I would give that a shot with just one machine, and see how things go. Let us know the result.
Oh, and I just realized that in the New-HardDisk calls, you will likely need to add some "_1" and "_2" in the VMDK names for hard disk 2 and 3. If you know that all of the VMDKs are uniformly named, that would work, or you could change up the Export-Csv part to include the VMs' VMDK names.
Then, you could use those saved VMDK names when going through the New-HardDisk portion.
Matt - Thank you so much for cleaning up my script! I will give it a test and let you know!