As I promised in a previous post I wanted to migrate from a vCenter to whole new machine
Process was:
- Export folders
- Export VM locations in Folders
- Export Permissions
- Export Custom Attributes
- Create Folders on the new vCenter
- Disable DRS/HA
- Remove ESX hosts from Source vCenter and add to Destination vCenter
- Enable DRS/HA again
- Move all vm’s to correct folders
- Apply the permissions back
- Apply custom attributes and notes
Here is the script
1: #load Vmware Module
2: Add-PSSnapin VMware.VimAutomation.Core 3: 4: #Change to multi-mode vcenter management
5: Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$false
6: 7: #Get vCenter Server Names
8: $sourceVI = Read-Host "Please enter the name of the source Server";
9: $destVI = Read-Host "Please enter the name of the destination Server"
10: 11: $creds = get-credential
12: 13: $datacenter = Read-Host "Please give the name of the datacenter you would like to run against"
14: 15: 16: #Connect to Source vCenter
17: connect-viserver -server $sourceVI -credential $creds18: connect-viserver -server $destVI -credential $creds -NotDefault:$false
19: 20: 21: filter Get-FolderPath {
22: $_ | Get-View | % {
23: $row = "" | select Name, Path
24: $row.Name = $_.Name 25: 26: $current = Get-View $_.Parent
27: $path = $_.Name28: do {
29: $parent = $current30: if($parent.Name -ne "vm"){$path = $parent.Name + "\" + $path}
31: $current = Get-View $current.Parent
32: } while ($current.Parent -ne $null)
33: $row.Path = $path 34: $row 35: } 36: } 37: 38: ## Export all folders 39: $report = @()40: $report = get-datacenter $datacenter -Server $sourceVI| Get-folder vm | get-folder | Get-Folderpath
41: ##Replace the top level with vm
42: foreach ($line in $report) {
43: $line.Path = ($line.Path).Replace($datacenter + "\","vm\")
44: }45: $report | Export-Csv "c:\Folders-with-FolderPath-$($datacenter).csv" -NoTypeInformation
46: 47: ##Export all VM locations 48: $report = @()49: $report = get-datacenter $datacenter -Server $sourceVI| get-vm | Get-Folderpath
50: 51: $report | Export-Csv "c:\vms-with-FolderPath-$($datacenter).csv" -NoTypeInformation
52: 53: 54: #Get the Permissions
55: 56: $folderperms = get-datacenter $datacenter -Server $sourceVI | Get-Folder | Get-VIPermission
57: $vmperms = Get-Datacenter $datacenter -Server $sourceVI | get-vm | Get-VIPermission
58: 59: $permissions = get-datacenter $datacenter -Server $sourceVI | Get-VIpermission
60: 61: $report = @()62: foreach($perm in $permissions){
63: $row = "" | select EntityId, FolderName, Role, Principal, IsGroup, Propagate
64: $row.EntityId = $perm.EntityId65: $Foldername = (Get-View -id $perm.EntityId).Name
66: $row.FolderName = $foldername 67: $row.Principal = $perm.Principal 68: $row.Role = $perm.Role 69: $row.IsGroup = $perm.IsGroup 70: $row.Propagate = $perm.Propagate 71: $report += $row 72: } 73: 74: foreach($perm in $folderperms){
75: $row = "" | select EntityId, FolderName, Role, Principal, IsGroup, Propagate
76: $row.EntityId = $perm.EntityId77: $Foldername = (Get-View -id $perm.EntityId).Name
78: $row.FolderName = $foldername 79: $row.Principal = $perm.Principal 80: $row.Role = $perm.Role 81: $row.IsGroup = $perm.IsGroup 82: $row.Propagate = $perm.Propagate 83: $report += $row 84: } 85: 86: foreach($perm in $vmperms){
87: $row = "" | select EntityId, FolderName, Role, Principal, IsGroup, Propagate
88: $row.EntityId = $perm.EntityId89: $Foldername = (Get-View -id $perm.EntityId).Name
90: $row.FolderName = $foldername 91: $row.Principal = $perm.Principal 92: $row.Role = $perm.Role 93: $row.IsGroup = $perm.IsGroup 94: $row.Propagate = $perm.Propagate 95: $report += $row 96: } 97: 98: $report | export-csv "c:\perms-$($datacenter).csv" -NoTypeInformation
99: 100: ##Export VM Custom Attributes and notes
101: 102: $vmlist = get-datacenter $datacenter -Server $sourceVI| get-vm
103: $Report =@()104: foreach ($vm in $vmlist) {
105: $row = "" | Select Name, Notes, Key, Value, Key1, Value1
106: $row.name = $vm.Name107: $row.Notes = $vm | select -ExpandProperty Notes
108: $customattribs = $vm | select -ExpandProperty CustomFields
109: $row.Key = $customattribs[0].Key 110: $row.Value = $customattribs[0].value 111: $row.Key1 = $customattribs[1].Key 112: $row.Value1 = $customattribs[1].value 113: $Report += $row 114: } 115: 116: $report | Export-Csv "c:\vms-with-notes-and-attributes-$($datacenter).csv" -NoTypeInformation
117: 118: 119: ##Disconnect-VIServer -Server $sourceVI -force -confirm:$false
120: 121: 122: #connect to Destination Server
123: ##connect-viserver -server $destVI -credential $creds -confirm:$false
124: 125: 126: ##IMPORT FOLDERS127: $vmfolder = Import-Csv "c:\Folders-with-FolderPath-$($datacenter).csv" | Sort-Object -Property Path
128: 129: foreach($folder in $VMfolder){
130: $key = @()131: $key = ($folder.Path -split "\\")[-2]
132: if ($key -eq "vm") {
133: get-datacenter $datacenter -Server $destVI | get-folder vm | New-Folder -Name $folder.Name
134: } else {
135: get-datacenter $datacenter -Server $destVI | get-folder vm | get-folder $key | New-Folder -Name $folder.Name
136: } 137: } 138: 139: ##ESX host migration 140: 141: #Switch off HA142: Get-Cluster $datacenter -Server $sourceVI | Set-Cluster -HAEnabled:$false -DrsEnabled:$false -Confirm:$false
143: 144: #Remove ESX hosts from old vcenter145: $Myvmhosts = get-datacenter $datacenter -Server $sourceVI | Get-VMHost
146: foreach ($line in $Myvmhosts) {
147: Get-vmhost -Server $sourceVI -Name $line.Name | Set-VMHost -State "Disconnected" -Confirm:$false
148: Get-VMHost -server $sourceVI -Name $line.Name | Remove-VMHost -Confirm:$false
149: }150: #add ESX hosts into new vcenter
151: foreach ($line in $Myvmhosts) {
152: Add-VMHost -Name $line.name -Location (Get-Datacenter $datacenter -server $destVI) -user root -Password trunk@1 -Force
153: } 154: 155: #Turn on HA and DRS on
156: Set-Cluster -Server $destVI Cluster1 -DrsEnabled:$true -HAEnabled:$true -Confirm:$false
157: 158: Disconnect-VIServer $sourceVI -Confirm:$false
159: 160: ##workaround for non working new-vipermissions
161: 162: function New-VIAccount($principal) {
163: $flags = [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Public -bor [System.Reflection.BindingFlags]::DeclaredOnly -bor [System.Reflection.BindingFlags]::Instance
164: 165: $method = $defaultviserver.GetType().GetMethods($flags) | where { $_.Name -eq "VMware.VimAutomation.Types.VIObjectCore.get_Client" }
166: $client = $method.Invoke($global:DefaultVIServer, $null)
167: Write-Output (New-Object VMware.VimAutomation.Client20.PermissionManagement.VCUserAccountImpl -ArgumentList $principal, "", $client)
168: } 169: 170: ##move the vm's to correct location
171: $VMfolder = @()172: $VMfolder = import-csv "c:\VMs-with-FolderPath-$($datacenter).csv" | Sort-Object -Property Path
173: foreach($guest in $VMfolder){
174: $key = @() 175: $key = Split-Path $guest.Path | split-path -leaf176: Move-VM (get-datacenter $datacenter -Server $destVI | Get-VM $guest.Name) -Destination (get-datacenter $datacenter -Server $destVI | Get-folder $key)
177: } 178: 179: 180: ##Import VM Custom Attributes and Notes
181: $NewAttribs = Import-Csv "C:\vms-with-notes-and-attributes-$($datacenter).csv"
182: 183: foreach ($line in $NewAttribs) {
184: set-vm -vm $line.Name -Description $line.Notes -Confirm:$false
185: Set-CustomField -Entity (get-vm $line.Name) -Name $line.Key -Value $line.Value -confirm:$false
186: Set-CustomField -Entity (get-vm $line.Name) -Name $line.Key1 -Value $line.Value1 -confirm:$false
187: 188: } 189: 190: 191: ##Import Permissions 192: $permissions = @()193: $permissions = Import-Csv "c:\perms-$($datacenter).csv"
194: 195: foreach ($perm in $permissions) {
196: $entity = ""
197: $entity = New-Object VMware.Vim.ManagedObjectReference
198: 199: switch -wildcard ($perm.EntityId) 200: { 201: Folder* { 202: $entity.type = "Folder"
203: $entity.value = ((get-datacenter $datacenter | get-folder $perm.Foldername).ID).Trimstart("Folder-")
204: } 205: VirtualMachine* { 206: $entity.Type = "VirtualMachine"
207: $entity.value = ((get-datacenter $datacenter | Get-vm $perm.Foldername).Id).Trimstart("VirtualMachine-")
208: } 209: }210: $setperm = New-Object VMware.Vim.Permission
211: $setperm.principal = $perm.Principal212: if ($perm.isgroup -eq "True") {
213: $setperm.group = $true
214: } else {
215: $setperm.group = $false
216: }217: $setperm.roleId = (Get-virole $perm.Role).id
218: if ($perm.propagate -eq "True") {
219: $setperm.propagate = $true
220: } else {
221: $setperm.propagate = $false
222: } 223: 224: $doactual = Get-View -Id 'AuthorizationManager-AuthorizationManager'
225: $doactual.SetEntityPermissions($entity, $setperm) 226: } 227: 228: ##Error Checking
229: ################ 230: 231: ##Gather all info for New Vcenter
232: ##Export all folders 233: $report = @()234: $report = Get-folder vm -server $destVI | get-folder | Get-Folderpath
235: ##Replace the top level with vm
236: foreach ($line in $report) {
237: $line.Path = ($line.Path).Replace("DC1\","vm\")
238: }239: $report | Export-Csv "c:\Folders-with-FolderPath_dest.csv" -NoTypeInformation
240: 241: ##Export all VM locations 242: $report = @()243: $report = get-vm -server $destVI | Get-Folderpath
244: 245: $report | Export-Csv "c:\vms-with-FolderPath_dest.csv" -NoTypeInformation
246: 247: 248: #Get the Permissions
249: $permissions = Get-VIpermission -Server $destVI
250: 251: $report = @()252: foreach($perm in $permissions){
253: $row = "" | select EntityId, FolderName, Role, Principal, IsGroup, Propopgate
254: $row.EntityId = $perm.EntityId255: $Foldername = (Get-View -id $perm.EntityId).Name
256: $row.FolderName = $foldername 257: $row.Principal = $perm.Principal 258: $row.Role = $perm.Role 259: $report += $row 260: }261: $report | export-csv "c:\perms_dest.csv" -NoTypeInformation
262: 263: ##Export VM Custom Attributes and notes
264: 265: $vmlist = get-vm -Server $destVI
266: $Report =@()267: foreach ($vm in $vmlist) {
268: $row = "" | Select Name, Notes, Key, Value, Key1, Value1
269: $row.name = $vm.Name270: $row.Notes = $vm | select -ExpandProperty Notes
271: $customattribs = $vm | select -ExpandProperty CustomFields
272: $row.Key = $customattribs[0].Key 273: $row.Value = $customattribs[0].value 274: $row.Key1 = $customattribs[1].Key 275: $row.Value1 = $customattribs[1].value 276: $Report += $row 277: } 278: 279: $report | Export-Csv "c:\vms-with-notes-and attributes_dest.csv" -NoTypeInformation
280: 281: ##compare the source and destination - this part is not yet finished
282: write-output "Folder-paths"
283: Compare-Object -ReferenceObject (import-csv C:\vms-with-FolderPath.csv) (import-csv C:\vms-with-FolderPath_dest.csv) -IncludeEqual
284: 285: 286: write-output "Notes & Attributes"
287: Compare-Object -ReferenceObject (import-csv "C:\vms-with-notes-and attributes.csv") (import-csv "C:\vms-with-notes-and attributes_dest.csv") -IncludeEqual
288: 289: write-output "Permissions"
290: Compare-Object -ReferenceObject (import-csv C:\perms.csv | select * -ExcludeProperty EntityId) (import-csv C:\perms_dest.csv | select * -ExcludeProperty EntityId) -IncludeEqual
291: Disconnect-VIServer -Server $destVI -Force -confirm:$false
292: The script is commented pretty well throughout the script, I will update with more and a walkthrough of the script later.
Give me a shout if you have any questions with the script
The script can also be downloaded below