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 $creds
18: 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 = $_.Name
28: do {
29: $parent = $current
30: 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.EntityId
65: $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.EntityId
77: $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.EntityId
89: $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.Name
107: $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 FOLDERS
127: $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 HA
142: Get-Cluster $datacenter -Server $sourceVI | Set-Cluster -HAEnabled:$false -DrsEnabled:$false -Confirm:$false
143:
144: #Remove ESX hosts from old vcenter
145: $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 -leaf
176: 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.Principal
212: 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.EntityId
255: $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.Name
270: $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