I'm having an issue with a migration script I've written to migrate VMs between 2 VCs. The first part of the script works as designed (checks tools, right-sizes, and removes VM from inventory on the source VC). The second part fails.on the destination VC when setting the folder:
#The CSV should be in the following format
#VMNAME,$MEM,$CPU,$VMHOST,$VMXFILE,$CLUSTER,$VMFOLDER,$RESPOOL,$VMNETWORK
#Even if there's not going to be a change, the
#cells cannot be blank use "" for blank
#Import the CSV
$vmlist = Import-CSV d:\scripts\naotest-UCSmigration.csv
#Prompts user for the source and destination vCenter servers
$SourceVC = Read-Host -Prompt 'What is the source vCenter?'
$DestVC= Read-Host -Prompt 'What is the destination vCenter?'
#connects to the source vCenter for right-sizing
connect-viserver $SourceVC
#check tools status first
write-host ""
write-host "Checking VMware Tools Status before proceeding." -foreground green
write-host ""
foreach ($item in $vmlist) {
$vmname=$item.vmname
$ToolsStatus = (Get-VM $vmname).extensiondata.Guest.ToolsStatus -eq "toolsNotRunning"
IF ($ToolsStatus -eq $true){
write-host ""
write-host "Tools is not installed or running on $vmname. Remediate on guest and restart the script" -foreground Yellow
write-host "Script will exit" -foreground yellow
write-host ""
Exit}
Else {
write-host ""
write-host "Tools running, script will continue" -foreground green
write-host ""}
}
#Power down all the VMs in the list
write-host ""
write-host "Powering down all VMs in the list. Script will sleep for 2 minutes before continuing" -foreground green
write-host ""
foreach ($item in $vmlist) {
$vmname = $item.vmname
Shutdown-VMGuest -VM $vmname -Confirm:$false
}
#sleep for 2 minutes before continuing
#may need to adjust depending upon time for
#servers to shut down
Start-sleep -s 120
#stop VMs that haven't shut down
write-host ""
write-host "Stopping VMs that have hung on power-down" -foreground green
write-host ""
foreach ($item in $vmlist) {
$vmname = $item.vmname
Stop-VM -VM $vmname -RunAsync -Confirm:$false
}
#Right-size CPU and memory
write-host ""
write-host "Right-sizing CPU and Memory" -foreground green
write-host ""
foreach ($item in $vmlist) {
$vmname = $item.vmname
$cpu = $item.cpu
$mem = $item.mem
Set-VM -VM $vmname -NumCpu $cpu -MemoryGB $mem -RunAsync -Confirm:$false}
#start the VMs after the vCPU/Memorychange
write-host ""
write-host "Restarting the VMs to enact the vCPU/Memory change" -foreground green
write-host ""
foreach ($item in $vmlist) {
$vmname = $item.vmname
Start-VM -VM $vmname -RunAsync
}
#Wait 5 minutes for the VMs to completely Power Up
write-host ""
Write-host "Sleeping for 5 minutes to wait for all VMs to power up" -foreground green
write-host ""
Start-sleep -s 300
#Power down the VMs in preparation for migration
#NOTE: It's necessary to power them up after the right-sizing
write-host "Power down and sleep for 2 minutes"
foreach ($item in $vmlist) {
$vmname = $item.vmname
Shutdown-VMGuest -VM $vmname -Confirm:$false
}
#Wait 2 minutes for the VMs to completely Power down
Start-sleep -s 120
#stop VMs that haven't shut down
write-host ""
write-host "Stop VMs that haven't shut down normally." -foreground green
write-host ""
foreach ($item in $vmlist) {
$vmname = $item.vmname
Stop-VM -VM $vmname -RunAsync -Confirm:$false
}
#disconnect CD-ROM
write-host ""
write-host "Disconnect any connected CD-ROM drives."
write-host ""
get-vm $vmname|Get-CDDrive | Set-CDDrive -nomedia -Confirm:$false
#remove VMs in list from inventory on the source vCenter
write-host ""
write-host "Remove VMs from inventory on the source vCenter."
write-host ""
foreach ($item in $vmlist) {
$vmname = $item.vmname
Remove-VM -VM $vmname -Confirm:$false
}
#disconnect from the source vCenter
disconnect-viserver -Confirm:$false
#Connect to the destination vCenter server
connect-viserver $DestVC
#Add VMs to the new vCenter server
write-host ""
Write-host "Add VMs to the Destination vCenter"
write-host ""
foreach ($item in $vmlist) {
$VMXFILE = $item.VMXFILE
$CLUSTER = $item.CLUSTER
$VMHOST = Get-VMHost -location $Cluster | Sort $_.CPuUsageMhz -Descending | Select -First 1
$VMFOLDER = $item.VMFOLDER
$RESPOOL = $item.RESPOOL
$VMNETWORK = $item.VMNETWORK
New-VM -VMFilePath "`"$VMXFILE`"" -VMHost $VMHOST -Location $VMFOLDER -ResourcePool $RESPOOL}
#change the network for the new vCenter
foreach ($item in $vmlist) {
$vmname = $item.vmname
get-vm $vmname | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $vmnetwork -confirm:$false
}
#Power up the VMs on the new vCenter server
write-host ""
write-host "Powering up VMs on the destination vCenter." -foreground green
write-host ""
foreach ($item in $vmlist) {
$vmname = $item.vmname
Start-VM -VM $vmname -RunAsync
}
The CSV looks like this:
vmname,cpu,mem,vmxfile,cluster,vmfolder,respool,vmnetwork
ATEST-VM002,1,4,[DEV-DATASTORE] ATEST-VM002/ATEST-VM002.vmdk,DEV-STND1,DEV\Dev\Infrastructure,DEV-root,VLAN-123
The error is as follows:
New-VM : 12/16/2015 2:46:49 PM New-VM Could not find Folder with
name 'DEV\Dev\Infrastructure'.
At D:\scripts\vm-uscmigration.ps1:144 char:5
+ New-VM -VMFilePath "`"$VMXFILE`"" -VMHost $VMHOST -Location $VMFOLDER
-Resou ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~
+ CategoryInfo : ObjectNotFound: (SAT1-DEV\Dev-NAOTEST\Infrastruc
ture:String) [New-VM], VimException
+ FullyQualifiedErrorId : Core_ObnSelector_SelectObjectByNameCore_ObjectNo
tFound,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewVM
I pulled the path information from RVTOOLS (along with most of the other relevant info). Is the path info incorrect, or is it a problem in my script? Any assistance would be appreciated.
P.S. I don't know that setting the network will work or not, I haven't gotten that far!
Thanks!
That is because the screenshot in my post was taken in an older PowerCLI release.
The current release shows other properties by default.
Pipe the result to Select -Property *, then you will see all properties of the Folder object.
You can try to use the function and use the returned Folder object on the Location parameter.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The New-VM cmdlet can't interpret a folderpath like you are giving it, it needs a Folder object on the Location parameter.
You can use the function in my Folder by Path post to "translate" a path to an actual Folder object.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Not sure if you have looked into below post by William Lam on relocate VMs from one VC to another (even to VC completely different SSO domain)
PowerCLI
Did you know of an additional cool vMotion capability in vSphere 6.0? | virtuallyGhetto
Below is my post on the same but using Java vSphere SDK.
You can refer these posts for your use case. Let me know if you need any more help.
LucD, thanks for your response. I've added the function to my powershell profile and it appears to run successfully but I'm not getting the expected response.
PowerCLI D:\scripts> get-folderbypath -path "DC1/Folder1/Infrastructure"
Name Type
---- ----
Infrastructure VM
Powershell and PowerCLI version info:
PowerCLI D:\scripts> $psversiontable
Name Value
---- -----
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.18444
BuildVersion 6.3.9600.16406
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2
PowerCLI D:\scripts> get-vitoolkitversion
PowerCLI Version
----------------
VMware vSphere PowerCLI 5.5 Release 2 Patch 1 build 1931983
---------------
Snapin Versions
---------------
VMWare AutoDeploy PowerCLI Component 5.5 build 1890764
VMWare ImageBuilder PowerCLI Component 5.5 build 1890764
VMware License PowerCLI Component 5.5 build 1265954
VMware VDS PowerCLI Component 5.5 build 1926677
VMware vSphere PowerCLI Component 5.5 Patch 1 build 1926677
Unfortunately we're stuck on 5.5 until Q1 of next year. I couldn't get 6.0 certified internally until then. 😞
How did you adapt the script ?
Any error messages ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
No error messages. Copied and pasted your function...didn't make any changes. Added it to my Powershell Profile.
But how you use the function in your script ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I didn't add it to the migration script, I was just trying to get the output first before I added it to the script.
I just ran the get-folderpath -path against one of the folders I had in my csv.
And what is not working as expected then ?
The function returns a Folder object, which you can use on the Location parameter.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD, It resulted with
Name Type
---- ----
Infrastructure VM
But I was expecting something along the lines of what was presented in your post.
Name Id
---- --
Servers Folder-group-blah
That is because the screenshot in my post was taken in an older PowerCLI release.
The current release shows other properties by default.
Pipe the result to Select -Property *, then you will see all properties of the Folder object.
You can try to use the function and use the returned Folder object on the Location parameter.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks LucD, I'll try that before the end of the day.
Thanks, that did it. Piped it to Select -property ParentId and I have the results. Thanks again!