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?
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
Thanks, that's helped. Not sure if there is a concept of Grandparent, as a lot of the 'parents' share the same name.
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
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
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
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
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
Error:
New-ResourcePool : 08-02-2019 07:49:12 New-ResourcePool When specifying custom CPU shares, number of CPU shares must be specified.
did you ever get solution for this problem I am trying the same thing but it is not working
requires shares to be set manually first portion of script export works good but then import cannot continue requires shares to be set manually
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
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
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