How to copy folders structure between two virtual center servers ?

by Grzegorz Kulikowski

Hello !
It is some time since i posted last time. There was quite a lot happening in my life lately so that’s why 😉 I’ve spent huge amount of time on my first lecture that was given in Poland at PLVMUG,
plvmug.q1.2013-26-700x464 (1)
after that i was back again in Poland to see my family on Easter. But anyway… i am lately having more free time, so i can share some of my thoughts with you again 😉
This time i want to show how we can copy folder structures between different virtual center servers. For example if you have to make a migration between virtual center servers, there is a lot to think of while doing this. You can’t forget about your annotations, folders(structure), location of virtual machines.
If you are migrating 20-50 vms, that’s not a big deal to move that kind of volume between VC, but what if you need to migrate 1000 or 2000 or 10000 vms ? And probably you don’t keep virtual machines inside ‘Discovered virtual machines’ folder, but you already have some structure.
This example was built based on example where cluster vms are attached to 1 folder structure. So if you have a virtual center and datacenter within, i assume here that structure looks like this:
‘blue\vm folders\’
‘\Datacenter X\ Cluster_Omega\Somefolder_with_Structure’

This function is able to move not only folder structures between VC but it also generates list of virtual machines and their folder ids, to which they should be moved. So if all my vms from cluster Omega resides somewhere in folder ‘Somefolder_with_Structure\x\y\z\’ you can grab the output of script to variable :
$mvlist=Copy-VCFolderStructure ….
While copying the folder structure this funtion will also return an array of vms with Name and Folder property, where the Folder property is actually an ID of a folder on the new virtual center server in which this vm should be placed.

[sourcecode language=”powershell”]
function Copy-VCFolderStructure {
Copy-VCFolderStructure copies folder and its structure from one VC to another..

Copy-VCFolderStructure can be handy when doing migrations of clusters/hosts between
Virtual Center servers. It takes folder structure from ‘old’ VC and it recreates it on ‘new’
VC. While doing this it will also output virtualmachine name and folderid. Why would you
want to have it ? Let’s say that you have a cluster on old virtual center server
Copy-VCFolderStructure will copy entire folder structure to ‘new’ VC, and while doing this
it will output to screen VMs that resides in those structures. VM name that will be shown on
screen will show also folderid, this ID is the folderid on new VC. After you have migrated
your hosts from old cluster in old VC to new cluster in new VC, and folder structure is there,
you can use move-vm cmdlet with -Location parameter. As location you would have give the
folder object that corresponds to vm that is being moved. Property Name is the name of VM
that was discovered in that folder and Folder is the folderid in which the vm should be moved
into. This folderid has to first changed to folder, for example :
$folderobj=get-view -id $folder|Get-VIObjectByVIView
We can then use $folderobj as parameter to move-vm Location parameter

This should be the extensiondata of folder that you want to copy to new VC.
$folderToRecreate=Get-Folder -Server oldVC.lab.local -Name teststruct
Have in mind that this should be an single folder and not an array.

.PARAMETER ParentOfNewFolder
When invoking the function this is the root folder where you want to attach the copied folder.
Let’s say you are copying folder from \DatacenterA\FolderX\myfolder
If you will have the same structure on the new VC, you would have set ParentOfNew folder
to FolderX. Still it’s not a problem if you have a new structure on new VC. Let’s say that on
new VC you have folder: \DatacenterZ\NewStructure\FolderZ and you want to copy entire
‘myfolder’ beneath the FolderZ. In that case, first create a variable that has desired folder
$anchor=get-folder ‘FolderZ’ -Server newVC
Make sure that $anchor variable will have only 1 element.

This parameter describes virtual center to which we are copying the folder structure.
Copy-VCFolderStructure works only when you are connected to both old and new vc at the
same time. You need to set your configuration of PowerCLI to handle multiple connections.
Set-PowerCLIConfiguration -DefaultVIServerMode ‘Multiple’
You can check if you are connected to both servers using $global:DefaultVIServers variable

This parameter describes virtual center from which we are copying the folder structure.
Copy-VCFolderStructure works only when you are connected to both old and new vc at the
same time. You need to set your configuration of PowerCLI to handle multiple connections.
Set-PowerCLIConfiguration -DefaultVIServerMode ‘Multiple’
You can check if you are connected to both servers using $global:DefaultVIServers variable

PS C:\> Set-PowerCLIConfiguration -DefaultVIServerMode ‘multiple’
PS C:\> $DefaultVIServers
Ensure that you are connected to both VC servers
Establish variables:
This will be the folder that we will be copying from old VC
$folderToRecreate=Get-Folder -Server $OldVC -Name ‘teststruct’
This will be the folder to which we will be copying the folder structure
$anchor=get-folder ‘IWantToPutMyStructureHere’ -Server $NewVC
Copy-VCFolderStructure -OldFolder $folderToRecreate.extensiondata -NewVC $NewVC
-OldVC $OldVC -ParentOfNewFolder $anchor
$OldFolder expects to get extensiondata object from the folder, if you will not provide it, function will
block it.

If you are planning to move vms after hosts/vm/folders were migrated to new VC, you might use it in this way.
By default Copy-VCFolderStructure will output also vms and their folder ids in which they should reside on new
VC. You can grab them like this:
$vmlist=Copy-VCFolderStructure -OldFolder $folderToRecreate.extensiondata -NewVC $NewVC
-OldVC $OldVC -ParentOfNewFolder $anchor
You can now export $vmlist to csv
$vmlist |export-csv -Path ‘c:\migratedvms.csv’ -NoTypeInformation
And once all virtual machines are in new virtual center, you can import this list and do move-vm operation on those
vms. Each vm has name and folder properties. Folder is a folderid value, which has to be converted to Folder object.
move-vm -vm $vmlist[0].name -Location (get-view -id $vmlist[0].folder -Server $newVC|get-viobjectbyviview)
-Server $newVC
This would move vm that was residing in previously on old VC in migrated folder to its equivalent on new VC.

NAME: Copy-VCFolderStructure

AUTHOR: Grzegorz Kulikowski

NOT WORKING ? #powercli @

THANKS: Huge thanks go to Robert van den Nieuwendijk for helping me out with the recursion in this function.



[parameter(Mandatory = $true)]
[parameter(Mandatory = $true)]
[parameter(Mandatory = $true)]
[parameter(Mandatory = $true)]
$NewFolder = New-Folder -Location $ParentOfNewFolder -Name $OldFolder.Name -Server $NewVC
Get-VM -NoRecursion -Location ($OldFolder|Get-VIObjectByVIView) -Server $OldVC|Select-Object Name, @{N=’Folder’;E={$}}
foreach ($childfolder in $OldFolder.ChildEntity|Where-Object {$_.type -eq ‘Folder’})
Copy-VCFolderStructure -OldFolder (Get-View -Id $ChildFolder -Server $OldVC) -ParentOfNewFolder $NewFolder -NewVC $NewVC -OldVC $OldVC
My example:
We have our VcOld: at : vc1.lab.local My cluster is CL_Holandia

Our NewVC before the movement looks like this:
As you can see in dc_new there is a folder that should keep my folder structure called: ‘Some_Holder’


On NewVC we have now structure like this:
We are connected to 2 virtual center servers : vc.lab.local and vc2.lab.local
Our cluster folder is named CL_Holandia where we keep all vms that are inside the cluster.
We are defining folder to be copied from old_VC:
$folderToRecreate=get-folder -Server $oldVC -Name ‘CL_Holandia’
we define to which folder this structure should go:
$anchor=get-folder’CL_Holandia’ -Server $newVC
We store VMs in variable $Vmlist
$vmlist=Copy-VCFolderStructure -OldFolder $folderToRecreate.extensiondata -ParentOfNewFolder $Anchor -NewVC $NewVC
-OldVC $OldVC


When we will add the cluster to new VC we will have structure probably like this. There will be additional ‘Discovered virtual machine’ folder, where all vms will appear and the rest of our copied structure. That means that we should now move vms to their proper folders.

After the last movement we will see proper structure:
It’s time now to move our vms from cluster from old VC, to folder of NEW cluster in NEW NC. So we will use now
$Vmlist variable do to this:
foreach($vm in $vmlist) {move-vm -vm $ -destination (get-view -id $vm.folder|get-viobjectbyviview)}
This should do it. We should see now our structure with vms and folder in proper place.
I do realize that i write this post at 1 am, but this is the only time i guess now that i have it free… So i know there might be some issues/bugs with this code. Please post a comment whenever you see some error. I will try to fix it as soon as possible. Please note that not all of you should have the same setup as me. This solution in regards of moving vms on new VC to proper folders will work only if you have similar folder structure(1 CL x 1 main_folder). I will try to rewrite this function entirely in order to make it as compatible with all structures as it can be.
At the end i would like to thank to Robert van den Nieuwendijk for his time and effort in writing this function. Without him it would take ages for me to write this recursion…
I hope that this function will help some of you with similar setup when you need to do migrations.

*images from PLVMUG session were taken from:

You may also like


Jannie November 5, 2013 - 4:29 pm

It’s remarkable designed for me to have a website, which is helpful for my know-how.
thanks admin

Matt February 19, 2014 - 6:00 pm

I don’t know if you read these comments, but have you ever tried adding code to this script to also copy vcenter folder permissions as well?


psvmware February 19, 2014 - 8:04 pm

Hi Matt, that’s doable, depends on some factors though. For example
1) what if perm is inherited from some parent and on the destination you do not have that parent, so do you want to have it attached on direct basis or would you want to still to point to to parent in higher level ?
2) if you have for example on folderes only permissions that are directly attached to that object that would be simple
3) what if those are mixed perms, inherited and assigned to that folder object, what then ? do you want to break inheritance and attach that perm to the folder directly ?

Let me know how do you see it, and i will try to add that functionality for you.

Matt February 19, 2014 - 8:26 pm

Thanks. I would be in scenario 3, Ideally copying both inherited and explicit folder permissions, but likely 99% of my inherited perms are set at the DC or Vcenter level. I’m currently configuring a 2nd vcenter in linked mode(brand new) and want an exact duplication of the vc1 folder structure on vc2. We can take this discussion offline to email if that’s preferred.

psvmware February 19, 2014 - 8:33 pm

Just sent you an e-mail.

mark “mkop” kopenski March 7, 2014 - 5:11 pm

Hi I am using this to migrate to another vcenter, it makes the new folders in the destination just fine, the issue is when I try to move the vm’s into the folders the folder ID is different and the vm’s do not go to the correct folder.

Is there another step that matches the folder id’s old = new ?

iArno June 5, 2014 - 4:32 pm


Thanks for the script.

I’m trying to copy from root folder to root folder, but it appear that the function always create the folder defined in $Anchor (which is creating a vm folder for my environment).

How can I avoid this issue ?

Best regards.

Alex October 7, 2014 - 11:25 am

The command “Copy-VCFolderStructure” is not OK.
Are there any other command to replace this ?

psvmware October 7, 2014 - 8:16 pm

It’s OK for me, don’t know really what do you mean by ‘not OK’.

sultan December 10, 2014 - 9:02 pm

Hi psvmware, Thanks for a great script. I am working on almost identical situation and could use some pointers. can we chat via email for a few minutes?

psvmware December 11, 2014 - 3:52 pm

sure, why not, we can also talk on irc #powercli on server if you want

soulblade64 June 4, 2015 - 3:24 am

I am looking at using this script to migrate my ESX hosts from my an old VC to a new VC… What I can’t figure out from your post is did you re-create the folder structure in the before ( and after ( images manually or did you use your function to do it? If you used your function, what’s the correct syntax?

soulblade64 June 4, 2015 - 3:51 am

PowerCLI C:\> Copy-VCFolderStructure

cmdlet Copy-VCFolderStructure at command pipeline position 1
Supply values for the following parameters:
OldFolder: MIS
ParentOfNewFolder: MIS
Copy-VCFolderStructure : Cannot process argument transformation on parameter ‘OldFolder’. Cannot convert the “MIS” value of type “System.String” to
type “VMware.Vim.Folder”.
At line:1 char:1
+ Copy-VCFolderStructure
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Copy-VCFolderStructure], ParameterBindingArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Copy-VCFolderStructure

psvmware June 4, 2015 - 9:31 am

Please read the post again, it’s all explained how to get the folders. take a look on:
It shows you how to fetch folders, you can’t just give a ‘name’ like you are doing, as that does not identify anything in particular. I hope you will get it from looking at that picture.

soulblade64 June 5, 2015 - 1:28 am

I did all those steps yesterday and it kept failing with the error above… I did it again this morning and it just worked… I’m not sure what happened!

Is there any way to get it so it the folder imports directly under the datacenter rather than into a folder I have to initially create? Right now I have to create a duplicate and unnecessary folder to do the import… I guess worst case scenario, I’ll just move the whole folder structure after the migration.

psvmware June 5, 2015 - 10:26 am

Yes, there is , you just need to move anchor 1 level up. That’s the “vm” folder of datacenter.
(get-view -id (get-datacenter ‘your datacenter for example’).Extensiondata.VmFolder).moref -> that’s the root one (vm folder) of Datacenter object.

Pranay Jha July 1, 2016 - 5:24 pm

While running these commands, I am getting below error:-
PowerCLI C:\> $vmlist=Copy-VCFolderStructure -OldFolder $folderToRecreate.extens
iondata -ParentOfNewFolder $Anchor -NewVC $NewVC -OldVC $OldVC
Copy-VCFolderStructure : The term ‘Copy-VCFolderStructure’ is not recognized
as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is
correct and try again.
At line:1 char:9
+ $vmlist=Copy-VCFolderStructure -OldFolder $folderToRecreate.extensiondata
-Paren …
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Copy-VCFolderStructure:String)
[], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Robert van den Nieuwendijk September 7, 2016 - 3:14 pm

Hi Greg, there is a typo in your function. On three places, it says exensiondata where it should say extensiondata.

psvmware September 9, 2016 - 3:00 pm

Many thanks Robert ! updated.


Leave a Reply

Chinese (Simplified)EnglishFrenchGermanHindiPolishSpanish
Streaming live on Twitch right now.