Please enable Javascript for better experience...
 
Powershell - Export/Import Folders and Permissions to another vCenter
By Pranay Jha | Jul 2, 2016 | In Tips | Update: Jul 2, 2016 | Total Views [ 35346 ]
(10 Like)
Rate

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 highlighted Set-SourceConfiguration script in any location as "Set-SourceConfiguration.ps1". 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


Thanks for visiting here. Share this article if you found it useful.
Like Facebook Page https://www.facebook.com/VMwareInsight/
Connect to twitter https://twitter.com/imPranayK
Subscribe my Channel https://www.youtube.com/vmwareinsight
Connect over Linkedin https://in.linkedin.com/in/impranayk
Share this on Social Media

About the Author

Pranay Jha
Pranay Jha
Founder, Contributer VMwareInsight.com

Public profile: user/profile/99900000


Follow me

facebook linkedin twitter G+ VMTN youtube

Thank you for visiting my profile. I am Pranay Jha, bring along a total of 11+ years of extensive experience with me in Information Technology sector for organizations from small business to large enterprises, wherein my current assignment I am associated with IBM as a Technical Solution Architect for Virtualization platform. I am vExpert x 3 (16/17/18), VCIX-DCV, VCAP5/6-DCD, VCAP5-DCA, VCP7-CMA, VCP5/6-DCV, VCA-DCV, VCA-Cloud, VSP, VCE-CIA, MCITP, MCSE, MCSA(Messaging). I am also an Independent blogger and founder of http://vmwareinsight.com and https://cloudpathshala.com. I can be reached via email at pranay1988jha@gmail.com or Direct Message via Contact Us form.

 
Please SignUp/Login to comment...

Or comment as anonymous...
* Name
* Email ID
Comment
 
Sponsors
 
 
 
 
 
Facebook Likes