How to Export and Import Folders and Permissions to from one vCenter to another vCenter?

Yeah, again back to scripting part after long time. Just because I was working on a migration project which had many tasks which would had taken long time and quite manuall efforts to perform this which was not at all worth. And other thing as to always I keep searching for shortcuts to perform any task with sense of urgency and to make easier.

Let's take a look what actually forced me to go with this way.

Just think about if you are working on migrating 100s of Virtual Machines from one vCenter to another vCenter, definetly you have to perform Role Based Access permissions on vCenter so that authorised users can only perform a specific and focused function on Virtual Machines.

There are different ways to perform this;

- Either you would create roles for particular job functions in new vCenter, and give each role a subset of permissions or privileges needed to do a function.

- or, You will migrate Folders and permissions from Old vCenter to New vCenter.

It's fine if you have have less numbers of Folders and Permission Groups. But what if you have this count in hundreds or thousands. Performing it manually would take longer and anyway repeating tasks will be like harassing yourself by your clicks.

So, you don't have to be panic, just say thanks to PowerCLI experts, specially "Virtually Jason" for this particular PowerShell Script which can save your day or weeks.

Perform below steps in Source Virtual Center;

- Login to Source Virtual Center.

- Open vSphere PowerCLI cmdlet

- Connect Virtual Center Server using below command.

Connect-VIServer SourceVCenterName

There are two parts of this script;

1) Get-SourceConfiguration from Source vCenter,

2) Set-SourceConfiguration in Destination vCenter.

Make sure that vDC(Virtual Datacenter) is with same name in both vCenters, if not then rename it for time being unless you import this configuration in Destination. Please note that renaming vDC won't impact your production. Ensure to rename it back as it was earlier as soon as these tasks get completed.

- Save below highlighted Get-SourceConfiguration script in any location as "Get-SourceConfiguration.ps1". I saved it in C:\Pranay\.

- Go to PowerCLI, and type cd C:\Pranay

- Execute command .\Get-SourceConfiguration.ps1

- It will ask to provide "Local Output Directory" in which *.xml files will get saved. In my case, I entered as, Enter local output directory: C:\Pranay

- It will ask to provide "Source vDC(Virtual DataCenter) name from where it will export or copy the configuration. In my case, I entered as, Enter datacenter: VmwareInsight-DC01

- Once information has been provided, it will generate 4 *xml files as below. Each file has different configuration information, i,e; 1) Folder details; 2) Permissions on that vDC, folders, and machines; 3) Roles on vCenter; 4) VM hierarchy

Get-SourceConfiguration Script (Source#Virtually Jason)



#Get Data from Source vCenter

#Built to be used with Set-SourceSettings.ps1 to recreate those same settings in another vCenter.

#Does not support vApps or multiple datacenters in the same vCenter.

param

(

$directory = $ ( read - host "Enter local output directory" ),

$datacenter = $ ( read - host "Enter datacenter" ),

[ switch ] $getTemplates

)

#Takes a VI Folder object and returns an array of strings that represents that folder's absolute path in the inventory

function get - folderpath

{

param

(

$thisFolder

)

#Creates an array of folders back to the root folder

if ( $thisFolder . id - like "Folder*" )

{

$folderArray = @()

$folderArray += $thisFolder

while ( $folderArray [- 1 ]. parent . parent . id - match "Folder" )

{

$folderArray += $folderArray [- 1 ]. parent

}

[ array ]:: Reverse ( $folderArray )

#convert the array of folders to an array of strings with just the folder names

$folderStrArray = @()

$folderArray | %{ $folderStrArray += $_ . name }

$folderStrArray

}

else

{

write - error "Unexpected input provided; does not appear to be a Folder."

}

}



$directory = $directory . trim ( "\") #" This comment is to fix the gistit syntax highlighting .

new - item $directory - type directory - erroraction silentlycontinue



if (( get - datacenter ). count - gt 1 ){ write - error "These scripts do not support multiple Datacenters in a single inventory" }



#Get Roles

get - virole | ? { $_ . issystem - eq $false } | export - clixml $directory \ $ ( $datacenter )- roles . xml



#Get Permissions

$allPermissions = @()

$foundPermissions = get - vipermission

$i = 0

foreach ( $thisPermission in $foundPermissions )

{

write - progress - Activity "Getting permissions" - percentComplete ( $i / $foundPermissions . count * 100 )

$objPerm = "" | select entity , type , Role , Principal , Propagate , folderType

$objPerm . type = $thisPermission . entity . id . split ( "-" )[ 0 ]

$objPerm . Role = $thisPermission . role

$objPerm . Principal = $thisPermission . Principal

$objPerm . Propagate = $thisPermission . propagate

#Create an absolute path for a folder, otherwise store the name of the entity

if ( $objPerm . type - eq "Folder" )

{

$objPerm . entity = get - folderpath $thisPermission . entity

$objPerm . folderType = $thisPermission . entity . type

}

else

{

$objPerm . entity = $thisPermission . entity . name

$objPerm . folderType = ""

}

$allPermissions += $objPerm

$i ++

}

$allPermissions | export - clixml $directory \ $ ( $datacenter )- permissions . xml





#Get VM Folder Structure

$outFolders = @()

$i = 0

$foundFolders = get - datacenter $datacenter | get - folder | ? { $_ . type . tostring () - eq "VM" - and $_ . parent . id - notLike "Datacenter*" }

foreach ( $thisFolder in $foundFolders )

{

write - progress - Activity "Getting VM folder structure" - percentComplete ( $i / $foundFolders . count * 100 )

$myFolder = "" | select path

$myFolder . path = get - folderpath $thisFolder

$outFolders += $myFolder

$i ++

}

$outFolders | export - clixml $directory \ $ ( $datacenter )- folders . xml



#Convert Templates to VMs (so that they can transition vCenters)

get - template | select name | export - clixml $directory \ $ ( $datacenter )- Templates . xml

if ( $getTemplates ){ get - datacenter $datacenter | get - template | set - template - ToVM - confirm : $false }



#Get VM Locations

$outVMs = @()

$allVApps = get - datacenter $datacenter | get - vapp

$vAppVMs = $allVApps | get - vm

if ( $vAppVMs )

{

$allVMs = Get - VM | ? {!( $vAppVMs . contains ( $_ ))}

#Deal with vApps... maybe try this guy's technique to capture settings and make a best effort at recreating the vApp?

# http://www.lukaslundell.com/2013/06/modifying-vapp-properties-with-powershell-and-powercli/

$outVApps = @()

foreach ( $thisVApp in $allVApps )

{

write - error "Discovered VAPP: $($thisVApp.name) - vAPPs must be recreated manually."

$myVApp = "" | select name , VMs

$myVApp . name = $thisVApp . name

$myVApp . VMs = ( $thisVApp | get - vm ). name

$outVApps += $myVApp

}

$outVApps | export - clixml $directory \ $ ( $datacenter )- vApps . xml

}

else

{

$allVMs = get - datacenter $datacenter | get - VM

}

$i = 0

foreach ( $thisVM in $allVMs )

{

write - progress - Activity "Getting VM locations" - percentComplete ( $i / $allVMs . count * 100 )

$myVM = "" | select name , folderPath

$myVM . name = $thisVM . name

if ( $thisVM . folder . name - eq "VM" )

{

$myVM . folderPath = $NULL

}

else

{

$myVM . folderPath = get - folderpath $thisVM . folder

}

$outVMs += $myVM

$i ++

}

$outVMs | export - clixml $directory \ $ ( $datacenter )- VMs . xml

Perform below steps in Destination Virtual Center;

- Login to destination Virtual Center or connect vSphere PowerCLI from any other server.

- Open vSphere PowerCLI cmdlet

- Connect Virtual Center Server using below command.

Connect-VIServer DestinationVCenterName

- Save below highlightedscript in any location as "". I saved it in C:\Pranay\.

- Go to PowerCLI, and type cd C:\Pranay

- Execute below commands and switches as per requirment.

.\Set-SourceConfiguration.ps1 -Folders (If Folders Export/Import is required)



.\Set-SourceConfiguration.ps1 -Permissions (If Permissions Export/Import is required)

.\Set-SourceConfiguration.ps1 -Roles (If Roles Export/Import is required)

.\Set-SourceConfiguration.ps1 -VMs (If VMs hierarchy Export/Import is required)

- It will ask to provide "Local Input Directory" in which *.xml files will get saved. In my case, I entered as, Enter local input directory: C:\Pranay

- It will ask to provide "Destination vDC(Virtual DataCenter) name in which it will copy the configuaration as Source vCenter. Ensure that Destination vDC is also having same name as Source vDC. In my case, I entered as, Enter datacenter: VmwareInsight-DC01

- Once information has been provided, it will execute configuration or copying old vCenter configuration to new vCenter.

Set-SourceConfiguration Script (Source#Virtually Jason)



param

(

$directory = $ ( read - host "Enter local input directory" ),

$datacenter = $ ( read - host "Enter datacenter" ),

[ switch ] $roles ,

[ switch ] $permissions ,

[ switch ] $folders ,

[ switch ] $vms

)



function make - ParentFolder

{

Param

(

$inFolderArray

)

$parentFolder = get - datacenter $datacenter | get - folder "VM"

foreach ( $thisSubFolder in $inFolderArray )

{

if (!( $parentFolder | get - folder $thisSubFolder - noRecursion - erroraction silentlycontinue ))

{

$ParentFolder = $parentFolder | new - folder $thisSubFolder

}

else

{

$ParentFolder = $ParentFolder | get - folder $thisSubFolder - noRecursion

}

}

$ParentFolder

}



$directory = $directory . trim ( "\") #" fix the gistit syntax highlighting



#Rebuild Folder Structure

if ( $folders )

{

$folderArray = import - clixml $directory \ $ ( $datacenter )- folders . xml

$i = 0

foreach ( $thisFolder in $folderArray )

{

write - progress - Activity "Creating Folders" - percentComplete ( $i / $folderArray . count * 100 )

make - ParentFolder - inFolderArray $thisFolder . path

$i ++

}

}



#Rebuild Roles

if ( $roles )

{

$allRoles = import - clixml $directory \ $ ( $datacenter )- roles . xml

$i = 0

foreach ( $thisRole in $allRoles )

{

write - progress - Activity "Creating Roles" - percentComplete ( $i / $allRoles . count * 100 )

if (!( get - virole $thisRole . name - erroraction silentlycontinue ))

{

new - virole - name $thisRole . name - privilege ( get - viprivilege - id $thisRole . PrivilegeList ) - erroraction silentlycontinue

}

$i ++

}

}



#Rebuild Permissions

if ( $permissions )

{

$allPermissions = import - clixml $directory \ $ ( $datacenter )- permissions . xml

$i = 0

foreach ( $thisPermission in $allPermissions )

{

write - progress - Activity "Creating Permissions" - percentComplete ( $i / $allPermissions . count * 100 )

$target = ""

if ( $thisPermission . type - eq "Folder" )

{

#permission is assigned to a folder, use make-folder to get the precise folder

$target = make - Parentfolder - inFolderArray $thisPermission . entity

}

elseif ( $thisPermission . type - eq "VirtualMachine" )

{

#permission is assigned to VM

$target = get - datacenter $datacenter | get - vm $thisPermission . entity

}

elseif ( $thisPermission . type - eq "Datacenter" )

{

#permission is assigned to Datacenter

$target = get - datacenter $thisPermission . entity

}

else

{

write - error "Unexpected permission target, $($thisPermission.type)"

}



if ( $target )

{

$target | new - vipermission - role $thisPermission . role - principal $thisPermission . principal - propagate $thisPermission . propagate

}

else

{

write - error "Unable to find permission object $($thisPermission.entity)"

}

$i ++

}

}



#Replace VMs

if ( $VMs )

{

$allVMs = import - clixml $directory \ $ ( $datacenter )- VMs . xml

$allVApps = $NULL

$i = 0

if ( test - path $directory \ vApps . xml ){ $allVApps = import - clixml $directory \ $ ( $datacenter )- vApps . xml }

foreach ( $thisVM in $allVMs )

{

write - progress - Activity "Placing VMs" - percentComplete ( $i / $allVMs . count * 100 )

if ( $foundVM = get - vm $thisVM . name )

{

$ParentFolder = make - ParentFolder - inFolderArray $thisVM . folderPath

$foundVM | move - vm - destination $ParentFolder

}

$i ++

}

foreach ( $thisVApp in $allVApps )

{

echo "===$($thisVApp.name)==="

$thisvApp . VMs

}

#Convert Template VMs back to Templates

}



if (!( $VMs - or $folders - or $permissions - or $roles ))

{

echo "Please use one or more of the -VMs, -Folders, -Permissions, or -Roles switches to do something"

}

-----------------------------------------------------------------

Be social and share if you liked this article.

Join my Facebook group https://www.facebook.com/groups/VMwareInsight/

Like my Facebook page https://www.facebook.com/VMwareInsight