VMware Cloud Community
06blade
Enthusiast
Enthusiast

Export and Import of Resource Pools using PowerCLI

I'm faced with a task of rebuilding a fresh vCentre server and bringing across all the ESXi hosts and VMs.

I've got scripts in place to export virtual machine notes and annotations, folders, permissions etc. However, I'm struggling to finding something to handle the nested resource pools.

Problem seems to be the export of the resource pools doesn't show the whole 'path', so when I try and import these back into the vCentre I get a lot of failures due to the resource pool already existing, and everything is created at the top level.

eg.

Client A

     Gold

     Silver

     Bronze

Client B

     Gold

     Silver

     Bronze

etc.

so the script I have actually create 5 resource pools - Client A, Client B, Gold, Silver, Bronze - all created at the top level.   Consequently, I get errors when it tries to create Gold, Silver and Bronze for the second time.

Is this something I'm going to be able to get working, or is it a manual task I'm faced with?

13 Replies
LucD
Leadership
Leadership

The following ae 2 simplified scripts that will export/import resourcepools for a specific cluster.

The export

$clusterName = "MyCluster"
$cluster = Get-Cluster -Name $clusterName
Get-ResourcePool -Location $cluster |
Select Name,@{N="Parent";E={$_.Parent.Name}} |
Export-Csv rp-export.csv -NoTypeInformation -UseCulture

The import

$clusterName = "MyCluster"
$dc = Get-Datacenter -Cluster $clusterName
foreach($rp in (Import-Csv rp-export.csv -UseCulture)){
 
$parent = Get-Inventory -Name $rp.Parent -Location $dc
 
Try {
   
Get-ResourcePool -Name $rp.Name -Location $parent -ErrorAction Stop | Out-Null
  }
 
Catch {
   
New-ResourcePool -Name $rp.Name -Location $parent | Out-Null
  }
}

Note that this will just export/import the resourcepools and their hierarchy, the actual configuration of the resourcepools needs to be added.

You can export/import these via the same CSV file.


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

06blade
Enthusiast
Enthusiast

Thanks, that's helped.  Not sure if there is a concept of Grandparent, as a lot of the 'parents' share the same name.

Reply
0 Kudos
LucD
Leadership
Leadership

No, there is no direct grandparent property, but we could store the complete path, instead of just the parent.

Let me come back to you.


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

Reply
0 Kudos
LucD
Leadership
Leadership

Try these variations, they take into account nested resourcepools with like names.

The export

$clusterName = "MyCluster"
$cluster = Get-Cluster -Name $clusterName
Get-ResourcePool -Location $cluster |
Select Name,@{N="Parent";E={
 
$path = $_.Parent.Name,$_.Name -join '/'
 
$parent = $_.Parent
 
while($parent -isnot [VMware.VimAutomation.ViCore.Impl.V1.Inventory.ClusterIMpl]){
   
$path = $parent.Parent.Name,$path -join '/'
   
$parent = $parent.Parent
  }
 
$path}} |
Export-Csv rp-export.csv -NoTypeInformation -UseCulture

And the import

foreach($row in (Import-Csv rp-export.csv -UseCulture)){
 
$clusterName,$pools = $row.Parent.Split('/')
 
Try {
   
$skip = $false
   
$location = Get-Cluster -Name $clusterName -ErrorAction Stop
  }
 
Catch {
   
"Cluster $clusterName not found"
   
$skip = $true
  }
 
if(!$skip){
   
foreach($rp in $pools){
     
Try {
       
$location = Get-ResourcePool -Name $rp -Location $location -ErrorAction Stop
      }
     
Catch {
       
$location = New-ResourcePool -Name $rp -Location $location
      }
    }
  }
}

Note that for the import you don't need to specify the cluster anymore, the clustername is in the "path".

So you can combine the resourcepools for several clusters in 1 CSV file.


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

Reply
0 Kudos
06blade
Enthusiast
Enthusiast

Thanks, seems to have worked for the majority. However, a few creations are failing with the following.

From what I think I've worked out, these failures occur on the resource pools where 'grandparent' and 'parent' may have the same names somewhere in the overall hierarchy.

New-ResourcePool : Cannot convert 'System.Object[]' to the type 'VMware.VimAutomation.ViCore.Types.V1.Inventory.VIContainer' required by parameter 'Location'. Specified method is not supported.

At P:\Scripts\imp\import-respool.ps1:29 char:58

+         $location = New-ResourcePool -Name $rp -Location $location

+                                                          ~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (:) [New-ResourcePool], ParameterBindingException

    + FullyQualifiedErrorId : CannotConvertArgument,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewResourcePool

Reply
0 Kudos
LucD
Leadership
Leadership

The error message seems to indicate that the value passed on the Location parameter is an array, while the cmdlet expects a scalar.

Could it be that you are running in multiple mode (multiple vCenter connections open) ?

Perhaps you can show me the cluster-resourcepool hierarchy where you encounter this error ?


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

Reply
0 Kudos
FFourniertyco
Contributor
Contributor

I modified it below to copy the setting from the resource pool. Otherwise you get the pool but with default values.

Also as regards the error you are receiving I had the same issue until I realized that my cluster would not accept Resource pools because DRS was not enabled.

Hope the info helps.

Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer Server

#Begin RessourcePool export
Write-Host "Exporting " -NoNewline
Write-Host "Ressource Pool" -ForegroundColor Green
Write-Host
Start-Sleep -Seconds 1

#Export Ressource Pool for folders from the source Cluster.

#
$clusterName = "MCluster"

$cluster = Get-Cluster -Name $clusterName
Get-ResourcePool -Location $cluster | Export-Csv rp-export.csv -NoTypeInformation -UseCulture
#End Ressource Pool export


Disconnect-VIServer * -force

Connect-VIServer server

#Begin ResourcePool Import
Write-Host "Importing " -NoNewline
Write-Host "Ressource Pool" -ForegroundColor Green
Write-Host
Start-Sleep -Seconds 1
#Imrt Ressource Pool for folders from the source Cluster.

foreach($row in (Import-Csv rp-export.csv -UseCulture)){
  $pools = $row.Name
  Try {
    $skip = $false
    $location = Get-Cluster -Name $cluster -ErrorAction Stop
  }
  Catch {
    "Cluster $clusterName not found"
    $skip = $true
  }
  if(!$skip){
    foreach($rp in $pools){
      Try {
        $location = Get-ResourcePool -Name $row.name -Location $location -ErrorAction Stop
      }
      Catch {
                $location =New-ResourcePool -Location $Location -Name $rp -NumCpuShares $row.NumCpuShares -CpuReservationMHz $row.CpuReservationMHz -CpuExpandableReservation ([System.Convert]::ToBoolean($row.CpuExpandableReservation)) -CpuLimitMHz $row.CpuLimitMHz -MemSharesLevel $row.MemSharesLevel -NumMemShares $row.NumMemShares -MemReservationMB $row.MemReservationMB -MemExpandableReservation ([System.Convert]::ToBoolean($row.MemExpandableReservation)) -MemLimitMB $row.MemLimitMB

      }
    }
  }
}

Disconnect-VIServer * -Force

#End Ressource Pool export

pgalatage
Contributor
Contributor

Error:

New-ResourcePool : 08-02-2019 07:49:12  New-ResourcePool                When specifying custom CPU shares, number of CPU shares must be specified.

slavonac
Enthusiast
Enthusiast

did you ever get solution for this problem I am trying the same thing but it is not working

Reply
0 Kudos
slavonac
Enthusiast
Enthusiast

requires shares to be set manually first portion of script export works good but then import cannot continue requires shares to be set manually

Reply
0 Kudos
LucD
Leadership
Leadership

There are a couple of issues with the last code in this thread.

The name of the ResourcePool is not in the variable $rp, but is in $row.Name.
It seems some parameters require the correct type of value to be passed.
Since with an Import-Csv all columns are provided as String values, there needs to be some casting done.

I also wrote the New-ResourcePool parameter with splatting.
This makes the code easier to read.

Import-Csv -Path rp-export.csv -UseCulture -PipelineVariable row |
ForEach-Object -Process {
foreach($row in (Import-Csv rp-export.csv -UseCulture)){
    $skip = $false
    $location = Get-Cluster -Name $cluster -ErrorAction SilentlyContinue
    if(-not $location){
      "Cluster $clusterName not found"
      $skip = $true
    }
    if(!$skip){
        Try {
          $location = Get-ResourcePool -Name $row.name -Location $location -ErrorAction Stop
        }
        Catch {
            $sPool = @{
              Location = $Location
              Name = $row.name
              NumCpuShares = [int]($row.NumCpuShares)
              CpuReservationMHz = [long]($row.CpuReservationMHz)
              CpuExpandableReservation = ([System.Convert]::ToBoolean($row.CpuExpandableReservation))
              CpuLimitMHz = [long]($row.CpuLimitMHz)
              MemSharesLevel = $row.MemSharesLevel
              NumMemShares = [int]($row.NumMemShares)
              MemReservationMB = [long]($row.MemReservationMB)
              MemExpandableReservation = ([System.Convert]::ToBoolean($row.MemExpandableReservation))
              MemLimitMB = [long]($row.MemLimitMB)
            }
            $rp = New-ResourcePool @spool
        }
      }
    }
}  


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

Reply
0 Kudos
EvgeniyL
Contributor
Contributor

Hi @LucD , when i running your script i have error

New-ResourcePool When specifying custom CPU shares, number of CPU shares must be specified.

when i add CpuSharesLevel = $row.CpuSharesLevel

New-ResourcePool When specifying custom number of CPU shares, SharesLevel.Custom must be specified.

maybe you now how resolve this?

ParentId,Parent,CpuSharesLevel,NumCpuShares,CpuReservationMHz,CpuExpandableReservation,CpuLimitMHz,MemSharesLevel,NumMemShares,MemReservationMB,MemReservationGB,MemExpandableReservation,MemLimitMB,MemLimitGB,Name,CustomFields,ExtensionData,Id
ResourcePool-resgroup-250394,Resources,Normal,4000,0,True,-1,Normal,163840,0,0,True,-1,-1,PROD,"VMware.VimAutomation.ViCore.Impl.V1.Util.ReadOnlyDictionary`2[System.String,System.String]",VMware.Vim.ResourcePool,ResourcePool-resgroup-256030
ResourcePool-resgroup-250394,Resources,Normal,4000,0,True,-1,Normal,163840,0,0,True,774144,756,k8s,"VMware.VimAutomation.ViCore.Impl.V1.Util.ReadOnlyDictionary`2[System.String,System.String]",VMware.Vim.ResourcePool,ResourcePool-resgroup-256031

Reply
0 Kudos
LucD
Leadership
Leadership

I assume that you set CpuSharesLevel to "Custom".
In that case, you also have to use the NumCpuShares parameter and use an Int32 value.

Note that this value is "used in relative allocation between resource consumers", meaning it is compared to the CPU shares in other resourcepools.


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