jonebgood_157
Enthusiast
Enthusiast

need help with scripting export of datacenter and clusters to import into brand new vcenter

Jump to solution

I've successfully created scripts on exporting files/folder, etc. and importing, but I'm having a hard time figuring out how to script the hosts and clusters view.  I have a ROBO vcenter with tons of datacenters and clusters and obviously don't want to create by hand. I don't need all the cluster settings, I simply want the datacenter and clusters "shell".  Any powercli script help for exporting all the datacenters and clusters and then re-importing to populate new vcenter would be greatly appreciated. I went through these boards but no one really seems to be doing exactly this.

0 Kudos
1 Solution

Accepted Solutions
jonebgood_157
Enthusiast
Enthusiast

@luc 

Getting some new errors on the import with these scripts....

 

New-Folder : 10/18/2022 7:35:09 AM New-Folder '10/18/2022 7:35:09 AM Get-Folder Folder with name 'Virtual Machine' was not found using the specified filter(s). ' is invalid or exceeds the maximum number of characters
permitted.
At line:10 char:7
+ New-Folder -Name $_ -Location $location
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-Folder], InvalidName
+ FullyQualifiedErrorId : Client20_InventoryServiceImpl_NewFolder_ViError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewFolder

New-Folder : 10/18/2022 7:35:09 AM New-Folder '10/18/2022 7:35:09 AM Get-Folder Folder with name 'VMkernel' was not found using the specified filter(s). ' is invalid or exceeds the maximum number of characters permitted.
At line:10 char:7
+ New-Folder -Name $_ -Location $location
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-Folder], InvalidName
+ FullyQualifiedErrorId : Client20_InventoryServiceImpl_NewFolder_ViError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewFolder

 

my .csv output

"Path"
"Datacenters\testing2\network\Virtual Machine"
"Datacenters\testing2\network\VMkernel"
"Datacenters\testing2\datastore\System"
"Datacenters\testing2\datastore\Virtual Machine"

View solution in original post

0 Kudos
52 Replies
jonebgood_157
Enthusiast
Enthusiast

I've looked through these and most are out of date. I've tried to reverse engineer but not much luck. FYI, I don't have any resource pools so I really only need the datacenters and clusters. I got separate scripts to export the folders, roles, etc. So I want something independent.

0 Kudos
LucD
Leadership
Leadership

Datacenters shouldn't be a big deal, they are rather flat objects and easy to create.
Just export the name and the path.

For clusters you will have to decide what exactly you want to export/import.

Btw, I'm not sure why you categorise those scripts are oudated.
A Datacenter and a Cluster are still the same.
A Cluster might have new features, but a basic cluster is still the same.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
jonebgood_157
Enthusiast
Enthusiast

So I figured out how to export the datacenter list to .csv which basically looks like:

"Name"
"test.dc.lab"
"prod.dc.general"
"location5.dc.general"

I'm having problem importing so it will look at each line and create a DC from that line. 

##IMPORT DATACENTER
$datacenter = Import-Csv "c:\temp\datacenters.csv"

foreach($line in $datacenter){
New-Datacenter -location (Get-Folder -NoRecursion)
}

0 Kudos
LucD
Leadership
Leadership

If some of your Datacenters are not located in the root of the inventory, you will also have to export the Path.

If all Datacenters are in the root of the inventory you can just do

Import-Csv "c:\temp\datacenters.csv" -PipelineVariable row |
Foreach-Object -Process {
   New-Datacenter -Name $row.Name -Confirm:$false
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

jonebgood_157
Enthusiast
Enthusiast

Thanks @LucD I'll try that. Luckily all the DCs are in the root. However you got me thinking about the cluster portion. I will have to get the path since each cluster resides under its respective DC. Do you think its easier to write a separate cluster export/import script or try to incorporate it into the same script with the DC export/import?  I'm thinking separate right; because then I have the DC's created in the new vcenter and it has a path to look at it?

0 Kudos
LucD
Leadership
Leadership

I would definitely go for separate scripts, just make sure to keep the order in mind, i.e. Datacenters before Clusters.

You might want to have a look at my Get-InventoryPlus function (Get-InventoryPlus – Inventory of all vSphere objects), it will give you the path of all inventory objects.
 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
jonebgood_157
Enthusiast
Enthusiast

its yelling at  me that I don't have the mandatory -location on New-Datacenter. if each one is created at the root what do I put for that?

0 Kudos
LucD
Leadership
Leadership

The hidden folder Datacenters



New-Datacenter -Name $row.Name -Location (Get-Folder -Name Datacenters)




Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
jonebgood_157
Enthusiast
Enthusiast

@LucD Okay, I figured out how to export the clusters list in the format I wanted. but i need some assistance on the cluster creation part where I import the .csv.

The format of my output.csv looks like this, but I'm not sure how to loop it thru the file so it creates the cluster under that datacenter path (also not sure why my path has 'host' in it; wondering if that is a hidden folder too)

"Name","Path"
"robo.cl.1","robo.dc.1\host\robo.cl.1"
"robo.cl.2","robo.dc.2\host\robo.cl.2"
"robo.cl.3","robo.dc.3\host\robo.cl.3"
"robo.cl.4","robo.dc.4\host\robo.cl.4"
"robo.cl.4","robo.dc.5\host\robo.cl.5"

 

 

0 Kudos
LucD
Leadership
Leadership

Yes, that 'host' is another hidden folder.

With that CSV (I assume it is named cluster-export.csv) you could do something like this

Import-Csv -Path .\cluster-export.csv -UseCulture -PipelineVariable row |
ForEach-Object -Process {
    $dcName,$dummy,$clusterName = $row.Path.Split('\')
    New-Cluster -Name $clusterName -Location $dcName
}

  


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

jonebgood_157
Enthusiast
Enthusiast

@LucD Thank you, this worked. The last piece im working on is the VM folder structure. I pretty much used the previous scripts you gave me and tried to alter for New-folder. But my import folder keeps creating them in th Hosts and Clusters View but I want in VM and folders View. How would I designate which view to create in?

##IMPORT FOLDERS
Import-Csv -Path c:\temp\clusters.csv -UseCulture -PipelineVariable row |
ForEach-Object -Process {
$dcName,$dummy,$folderName = $row.Path.Split('\')
New-Folder -Name $folderName -Location $dcName }

My input file is structured like:

"Name","Path"
"Linux","testing1vm\vmvm\Linux"
"Windows","testing1vm\vmvm\Windows"

 

Tags (1)
0 Kudos
LucD
Leadership
Leadership

You will have to use another hidden folder for the VM&Template folders.
Under the Datacenter there is a hidden folder named 'vm'.
Use that one as the Location on the New-Folder cmdlet.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
jonebgood_157
Enthusiast
Enthusiast

So I was able to get Hosts and Clusters view and VM and folders view, but struggling with our folders in the Network and Datastores view. For example, using similar scripts, I was able to export our datastores view and the .csv format is something like this:

"Name","Path","Type"
"System","testing\datastore\System","blue"
"Virtual Machine","testing\datastore\Virtual Machine","blue"

 

However, when I use this to import, it creates it on the Hosts and Clusters view; i have a feeling i can't use the 'New-Folder' command, right to create on Datastores view(and eventually network)

 

##IMPORT FOLDERS
Import-Csv -Path c:\temp\datastoresfolders.csv -UseCulture -PipelineVariable row |
ForEach-Object -Process {
$dcName,$dummy,$folderName = $row.Path.Split('\')
New-Folder -Name $folderName -Location $dcName }

0 Kudos
LucD
Leadership
Leadership

You have to follow the full path, datacenter and hidden folder (in this case 'datastore') to find the Location for the New-FOlder cmdlet.

Something like this

$dcName = 'DC'
$hiddenFolder = 'datastore'
$newFolder = 'TestFolder'

$location = Get-Datacenter -Name $dcName | Get-Folder -Name $hiddenFolder
New-Folder -Name $newFolder -Location $location


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
jonebgood_157
Enthusiast
Enthusiast

@LucD Ah, I was missing the full path; you are awesome. thank you. I got the loop working and its now rolling through all my vcenters and populating correctly. I can use this for my network ones too; just a different csv file. I think I finally understand the 'hiddenfolder' concept with each view.

##IMPORT FOLDERS
Import-Csv -Path c:\temp\datastorefolders.csv -UseCulture -PipelineVariable row |
ForEach-Object -Process {
$dcName,$dummy,$folderName = $row.Path.Split('\')
New-Folder -Name $folderName -Location (Get-Datacenter -Name $dcName | Get-Folder $dummy) }

So, here is my last conundrum....I've been looking at everyone's permissions scripts and it seems that all of them can only handle one datacenter as input.  How can I get the permissions from old vcenter exported with datacenter path for VM and Folder view(and eventually network and datastore) but also be able to loop through multiple datacenters? The ones i've come across can only create the folder and subfolder for one datacenter but then error out because they think its a duplicate name; not knowing how to iterate to new datacenter and so on.

0 Kudos
LucD
Leadership
Leadership

In which format did you export the permissions?
What is included in that file?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
jonebgood_157
Enthusiast
Enthusiast

The one I used exports it in 2 formats; one is .csv and the other is .xml

#TYPE Selected.VMware.VimAutomation.ViCore.Impl.V1.PermissionManagement.PermissionImpl
"vCenter","Principal","Role","Propagate","Entity","Entity Type"

 

The problem with the export though, is it only declares the datacenter for the "cluster compute resource" and not "Virtual Machine". for virtual machine it looks like:

"testvcenter","DOMAIN\Role-Linux","Role.Vm.VmSupport","True","Linux","Folder"

 

The problem is that every datacenter has a folder called "Linux" under it, so this script can distinguish the next DC; just applies on the first one and then complains about folder already created.

 

full export script i'm using. FYI, I commented out role stuff because I already created those in new vcenter

$PermissionXML = Get-VIPermission
$PermissionXML | Export-Clixml -Path "C:\Temp\$vCenterHost-Permission.xml"


#Roles
#$Role = Get-VIRole | Select-Object @{N='vCenter';E={$_.Uid.Split('@:')[1]}},
#Name,
#@{N='PrivilegeList';E={[string]::Join([char]10,$_.PrivilegeList)}}


#Export to CSV
#$Role | Export-Csv -Path "C:\Temp\$vCenterHost-Roles.csv"

#Export to XML
#$RoleXML = Get-VIRole
#$RoleXML | Export-Clixml -Path "C:\Temp\$vCenterHost-Roles.xml"

Write-Verbose "`tRole & Permission Data Exported Successfully from $vCenterHost" -Verbose

Write-Verbose "Disconnecting from $vCenterHost" -Verbose
Disconnect-VIServer -Server

}

catch {

Write-Verbose "`tError Encountered! Error:$_" -Verbose
$ErrorObject = New-Object -TypeName PSObject -Property @{
vCenterName = $vCenterHost
Error = $_

}

}

0 Kudos
LucD
Leadership
Leadership

I tested the following to export/import permissions.
And it seems to work for me.

One note, the vCLS VMs and Folders use a builtin account (like vsphere.local/vCLSAdmin) that can apparently not be used as a Principal.
Which shouldn't be a problem since these Folders, VMs and Permissions are generated automatically by the vCenter.

To export I used this

Get-VIPermission |
where{$_.Principal -notmatch 'vCLSAdmin$'} |
Select-Object Entity,
@{N='Path';E={
    $hidden = @('Datacenters')
    $script:object = Get-View -Id $_.EntityId
    $path = @($script:object.Name)
    $parent = $script:object.Parent

    while ($parent) {
      $pObject = Get-View -Id $Parent -Property Name, Parent
      $parent = $pObject.Parent
      if ($pObject -and $hidden -notcontains $pObject.Name) {
        $path += $pObject.Name
      }
    }
    [array]::Reverse($path)
    "$($path -join '/')"
}},
Principal, Role, Propagate |
Export-Csv -Path .\permissions.csv -NoTypeInformation -UseCulture


To import I used this

$root = Get-Folder -Name Datacenters

Import-Csv -Path .\permissions.csv -UseCulture -PipelineVariable row |
ForEach-Object -Process {
  if($row.Path -ne 'Datacenters'){
    $dcName, $nodes = $row.Path.Split('/')
    $entity = Get-Datacenter -Name $dcName
    $nodes[0..($nodes.Count - 1)] | ForEach-Object -Process {
      $entity = Get-Inventory -Name $_ -Location $entity
    }
  }
  else{
    $entity = $root
  }
  $sPerm = @{
    Entity = $entity
    Role = $row.Role
    Principal = $row.Principal
    Propagate = [Boolean]$row.Propagate
    WhatIf = $true
  }
  New-VIPermission @Sperm
}

 

Note that I used to WhatIf switch for testing.
Once you are sure the correct permissions are applied, remove that WhatIf entry from the hash table, or set it to $false


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos