Hello,
I have a situation where I have to configure HA, monitoring, etc. for a specific set of VMs in a cluster. These VMs must have VM overrides configured differently compared to the rest of the cluster. I know how to perform it manually, but I have to re-create the same procedure in PowerCLI and I'm not exactly sure on how to apply the VM overrides to the VMs and not to the whole cluster.
For now i have written the following:
$vms = Get-VM -name <name>
ForEach ($vm in $vms){
$spec = New-Object WMware.Vim.ClusterConfigSpecEx
$spec.dasVmConfigSpec = New-Object VMware.Vim.ClusterDasVmConfigSpec[] (1)
$spec.dasVmConfigSpec[0] = New-Object VMware.Vim.ClusterDasVmConfigSpec
$spec.dasVmConfigSpec[0].operation = "add"
$spec.dasVmConfigSpec[0].info = New-Object VMware.Vim.ClusterDasVmConfigInfo
$spec.dasVmConfigSpec[0].info.key = New-Object VMware.Vim.ManagedObjectReference
$spec.dasVmConfigSpec[0].info.key.type = "VirtualMachine"
$spec.dasVmConfigSpec[0].info.key.value = $vm.ExtensionData.MoRef.Value
$spec.dasVmConfigSpec[0].info.RestartPriority = "medium"
$spec.dasVmConfigSpec[0].info.PowerOffOnIsolation = $True"
$spec.dasVmConfigSpec[0].info.dasSettings = New-Object VMware.Vim.ClusterDasVmSettings
$spec.dasVmConfigSpec[0].info.dasSettings.vmToolsMonitoringSettings = New-Object VMware.Vim.ClusterVmToolsMonitoringSettings
$spec.dasVmConfigSpec[0].info.dasSettings.vmComponentProtectionSettings = New-Object VMware.Vim.ClusterVmComponentProtectionSettings
... Setting all the values for Component Protection and VM Monitorig ...
Now, near the end of the ForEach loop, I'm not sure on how to apply the created $spec configuration object to the $vm. Can it be done by something like this:
$_this = Get-View -Id $vm.VMHost.Parent.Id
$_this.ReconfigureComputeResource_Task($spec, $true)
And for ReconfigureComputeResource_Task, there are two parameters, but what does the 2nd parameter ($true) do?
If anyone could help, it would be much appreciated.
That is one of the drawbacks of using Code Capture.
You really need to consult the API Reference to know what the captured code is actually doing/calling.
In this case the ReconfigureComputeResource method is called to make the changes you did in the Web Client.
From the description of the method you'll see that the 2nd parameter is the modify parameter.
From the description: "Flag to specify whether the specification ("spec") should be applied incrementally. If "modify" is false and the operation succeeds, then the configuration of the cluster matches the specification exactly; in this case any unset portions of the specification will result in unset or default portions of the configuration."
The $_.this notation is to indicate that the method is called on the object, a cluster.
But in this case the vSphere object for a cluster.
This is not the same object as the .NET object for a cluster, which is returned by Get-Cluster.
There are 2 ways to go from the .NET object to the vSphere object.
One point to understand, the PowerCli framework offers 2 ways for all API methods.
One with the _Task suffix, where the call will return immediately and the task will run in the background.
The call without the _Task suffix, where the call will come back when the task is completed.
Something like the RunAsync switch on PowerCli cmdlets.
Your code would be something like this
$cluster = Get-Cluster -Name <name>
$vms = Get-VM -Name <name> -Location $cluster
ForEach ($vm in $vms){
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$spec.dasVmConfigSpec = New-Object VMware.Vim.ClusterDasVmConfigSpec[] (1)
$spec.dasVmConfigSpec[0] = New-Object VMware.Vim.ClusterDasVmConfigSpec
$spec.dasVmConfigSpec[0].operation = "add"
$spec.dasVmConfigSpec[0].info = New-Object VMware.Vim.ClusterDasVmConfigInfo
$spec.dasVmConfigSpec[0].info.key = New-Object VMware.Vim.ManagedObjectReference
$spec.dasVmConfigSpec[0].info.key.type = "VirtualMachine"
$spec.dasVmConfigSpec[0].info.key.value = $vm.ExtensionData.MoRef.Value
$spec.dasVmConfigSpec[0].info.RestartPriority = "medium"
$spec.dasVmConfigSpec[0].info.PowerOffOnIsolation = $True
$spec.dasVmConfigSpec[0].info.dasSettings = New-Object VMware.Vim.ClusterDasVmSettings
$spec.dasVmConfigSpec[0].info.dasSettings.vmToolsMonitoringSettings = New-Object VMware.Vim.ClusterVmToolsMonitoringSettings
$spec.dasVmConfigSpec[0].info.dasSettings.vmComponentProtectionSettings = New-Object VMware.Vim.ClusterVmComponentProtectionSettings
}
$cluster.ExtensionData.ReconfigureComputeResource_Task($spec, $true)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That is one of the drawbacks of using Code Capture.
You really need to consult the API Reference to know what the captured code is actually doing/calling.
In this case the ReconfigureComputeResource method is called to make the changes you did in the Web Client.
From the description of the method you'll see that the 2nd parameter is the modify parameter.
From the description: "Flag to specify whether the specification ("spec") should be applied incrementally. If "modify" is false and the operation succeeds, then the configuration of the cluster matches the specification exactly; in this case any unset portions of the specification will result in unset or default portions of the configuration."
The $_.this notation is to indicate that the method is called on the object, a cluster.
But in this case the vSphere object for a cluster.
This is not the same object as the .NET object for a cluster, which is returned by Get-Cluster.
There are 2 ways to go from the .NET object to the vSphere object.
One point to understand, the PowerCli framework offers 2 ways for all API methods.
One with the _Task suffix, where the call will return immediately and the task will run in the background.
The call without the _Task suffix, where the call will come back when the task is completed.
Something like the RunAsync switch on PowerCli cmdlets.
Your code would be something like this
$cluster = Get-Cluster -Name <name>
$vms = Get-VM -Name <name> -Location $cluster
ForEach ($vm in $vms){
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$spec.dasVmConfigSpec = New-Object VMware.Vim.ClusterDasVmConfigSpec[] (1)
$spec.dasVmConfigSpec[0] = New-Object VMware.Vim.ClusterDasVmConfigSpec
$spec.dasVmConfigSpec[0].operation = "add"
$spec.dasVmConfigSpec[0].info = New-Object VMware.Vim.ClusterDasVmConfigInfo
$spec.dasVmConfigSpec[0].info.key = New-Object VMware.Vim.ManagedObjectReference
$spec.dasVmConfigSpec[0].info.key.type = "VirtualMachine"
$spec.dasVmConfigSpec[0].info.key.value = $vm.ExtensionData.MoRef.Value
$spec.dasVmConfigSpec[0].info.RestartPriority = "medium"
$spec.dasVmConfigSpec[0].info.PowerOffOnIsolation = $True
$spec.dasVmConfigSpec[0].info.dasSettings = New-Object VMware.Vim.ClusterDasVmSettings
$spec.dasVmConfigSpec[0].info.dasSettings.vmToolsMonitoringSettings = New-Object VMware.Vim.ClusterVmToolsMonitoringSettings
$spec.dasVmConfigSpec[0].info.dasSettings.vmComponentProtectionSettings = New-Object VMware.Vim.ClusterVmComponentProtectionSettings
}
$cluster.ExtensionData.ReconfigureComputeResource_Task($spec, $true)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hello,
Thanks for the quick and in-depth respnose. Not actually using Code Capture as we don't have it, this code was written the old-fashioned way, but I'm fairly new to PowerCLI scripting and I couldn't find much on configuring individual VMs on the cluster. I guess I've missed the API reference to ReconfigureComputeResource method in the documentation, probably entered something wrong in the search.
So what I'm guetting from the desciption of the modify parameter, if $false is used, it will set the configuration of the whole cluster to the created $spec object?
That is correct.
Note that this will set defaults for all the cluster parameters you didn't include in the $spec.
Also, some properties in $spec are obligatory, in other words, they need to be present and set.
These properties are not marked with a red asterisk in the parameter description.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi Luc. Do you know if there's an easy way to simply export a list of VMs from vCenter that have a DRS override enabled? Unfortunately the usual export list function built-in to vCenter doesn't seem to be available in the VM Overrides view. RVTools doesn't seem to collect this information either.
Something like this?
Get-Cluster -PipelineVariable cluster |
ForEach-Object -Process {
$cluster.ExtensionData.Configuration.DrsVmConfig |
ForEach-Object -Process {
New-Object -TypeName PSObject -Property ([ordered]@{
Cluster = $cluster.Name
VM = (Get-View -Id $_.Key -Property Name).Name
Automation = $_.Behavior
})
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This worked perfectly, thank you! You're the best 🙂