Public/Update-HostRemediationConfig.ps1

function Update-HostRemediationConfig {
    <#
    .SYNOPSIS
        Change a configuration item on a host remediation configuration object.
 
        With thanks to Lyuboslav Asenov @ VMWare for providing assistance with new Update Manager API.
 
    .DESCRIPTION
        Change a configuration item on a host remediation configuration object.
        The base configuration object is generate from Get-HostRemediationConfig and can be piped to this function (see examples).
        This can then be used to set the default Update Manager configuration, or at remediation runtime to override Update Manager defaults.
 
    .PARAMETER HostRemediationConfig
        A host remediation configuration object of type IntegrityApi.HostRemediationScheduleOption.
        This object is generated by Get-HostRemediationConfig (see examples).
 
    .PARAMETER HostFailureAction
        Optional. Configure action when host maintenance mode fails.
        If specified must also be accompanied by retryDelay and retryAttempts.
 
    .PARAMETER HostRetryDelaySeconds
        Optional. Set the retry delay for failureAction.
 
    .PARAMETER HostNumberOfRetries
        Optional. Set the number of retry attempts for failureAction.
 
    .PARAMETER HostPreRemediationPowerAction
        Optional. Set the action for powered on VMs when a host goes into maintenance mode.
 
    .PARAMETER ClusterDisableDistributedPowerManagement
        Optional. Temporarily disbale cluster DPM before remediation. After remediation, it will be re-enabled.
 
    .PARAMETER ClusterDisableHac
        Optional. Temporarily disbale cluster high availability admission control before remediation. After remediation, it will be re-enabled.
 
    .PARAMETER ClusterDisableFaultTolerance
        Optional. Temporarily disbale cluster Fault Tolerance before remediation. After remediation, it will be re-enabled.
 
    .PARAMETER HostEnablePXEbootHostPatching
        Optional. Enable PXE booting ESXi hosts patching.
 
    .PARAMETER HostEvacuateOfflineVMs
        Optional. Migrate powered off and suspended VMs to other hosts in the cluster.
 
    .PARAMETER HostDisableMediaDevices
        Optional. Temporarily disable any media devices that might prevent the specified hosts from entering maintenance mode.
 
    .PARAMETER HostEnableQuickBoot
        Optional. Enable host quick boot on supported platforms.
 
    .PARAMETER ClusterEnableParallelRemediation
        Optional. Enable parallel remediation for the specified cluster.
 
    .PARAMETER ClusterMaxConcurrentRemediations
        Optional. The number of hosts to remediate in parallel. If 0 or not specified, the maximum concurrent remediations will be configured to "automatic".
        Not applicable to vSAN enabled clusters, these will always be remediated serially.
        A note on the behaviour of the VUM GUI versus the API:
            * On the GUI, the user must select "Enabled for hosts in maintenance mode" - this will skip all hosts not in MM.
              It is not possible to parallel remediate non-MM hosts via the GUI.
              If the user does not explicitely set enableParallelRemediateOfMMHosts, it will be set as true to mimick GUI behaviour.
            * Parallel remediation of non-MM hosts is possible at runtime via the API.
              The user must explicitely set enableParallelRemediateOfMMHosts as false at remediation runtime. This will result in non-MM hosts being remediated in parallel.
 
    .PARAMETER enableParallelRemediateOfMMHosts
        Optional when specifying ClusterEnableParallelRemediation. Enable parallel remediation of maintenance mode hosts. Hosts not in maintenance mode will be skipped.
        See note above on ClusterMaxConcurrentRemediations.
 
    .INPUTS
        IntegrityApi.HostRemediationScheduleOption. Host remediation configuration object.
 
    .OUTPUTS
        IntegrityApi.HostRemediationScheduleOption. Updated host remediation configuration object.
 
    .EXAMPLE
        $remediationConfig = Get-HostRemediationConfig | Update-HostRemediationConfig -ClusterEnableParallelRemediation $true -ClusterMaxConcurrentRemediations 2
 
        Create a remediation configuration object. Fetch the current config, then enable parallel remediation specifying a maximum of 2 hosts concurrently.
 
    .EXAMPLE
        $remediationConfig = Get-HostRemediationConfig | Update-HostRemediationConfig -HostFailureAction Retry -HostRetryDelaySeconds 20 -HostNumberOfRetries 2 -HostEnableQuickBoot $true
 
        Create a remediation configuration object. Fetch the current config, then set host failure action to retry with a delay of 20 seconds and 2 retries. Enable host Quick Boot.
 
    .EXAMPLE
        Update-EntityBaselineGroup -baselineGroupName "Sample Baseline Group" -entity $cluster -HostRemediationConfig $remediationConfig
 
        Remediate entity $cluster with "Sample Baseline Group", using the preconfigured remediation options as created in preceding examples.
 
    .EXAMPLE
        Set-HostRemediationConfig -HostRemediationConfig $newConfig
 
        Configure the default VUM host remediation settings as per the configuration object created in the preceding examples.
 
    .LINK
        https://github.com/TheDotSource/VUMXtra
 
    .NOTES
        01 06/01/22 Initial version. A McNair
    #>


    [OutputType([IntegrityApi.HostRemediationScheduleOption])]
    [CmdletBinding(DefaultParameterSetName="minimalInput")]
    Param
    (
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [IntegrityApi.HostRemediationScheduleOption]$HostRemediationConfig,
        [Parameter(ParameterSetName="retryConfig",Mandatory=$false,ValueFromPipeline=$false)]
        [ValidateSet("Retry","FailTask")]
        [string]$HostFailureAction,
        [Parameter(ParameterSetName="retryConfig",Mandatory=$false,ValueFromPipeline=$false)]
        [ValidateRange(60,360000)]
        [int]$HostRetryDelaySeconds = 60,
        [Parameter(ParameterSetName="retryConfig",Mandatory=$false,ValueFromPipeline=$false)]
        [ValidateRange(1,100)]
        [int]$HostNumberOfRetries = 3,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [ValidateSet("DoNotChangeVMsPowerState","SuspendVMs","PowerOffVMs")]
        [string]$HostPreRemediationPowerAction,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [bool]$ClusterDisableDistributedPowerManagement,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [bool]$ClusterDisableHac,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [bool]$ClusterDisableFaultTolerance,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [bool]$HostEnablePXEbootHostPatching,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [bool]$HostEvacuateOfflineVMs,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [bool]$HostDisableMediaDevices,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [bool]$HostEnableQuickBoot,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [bool]$ClusterEnableParallelRemediation,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [ValidateRange(0,64)]
        [int]$ClusterMaxConcurrentRemediations,
        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [bool]$enableParallelRemediateOfMMHosts
    )

    begin {

        Write-Verbose ("Function start.")

        ## If ClusterMaxConcurrentRemediations or enableParallelRemediateOfMMHosts, we need to ensure that ClusterEnableParallelRemediation is true
        if ($ClusterMaxConcurrentRemediations -or $enableParallelRemediateOfMMHosts) {

            if (!$ClusterEnableParallelRemediation) {
                throw ("Parallel remediation options set, but -ClusterEnableParallelRemediation has not been specified.")
            } # if

        } # if

    } # begin


    process {

        ## Examine each parameter in turn and configure object as necessary

        switch ($HostFailureAction) {

            "Retry" {

                Write-Verbose ("Configuring failure action to Retry with a delay of " + $HostRetryDelaySeconds + " seconds and " + $HostNumberOfRetries + " retry attempts.")

                ## Set failure action to Retry
                $hostRemediationConfig.failureAction = "Retry"

                ## We also need to set the retry delay and retry attempts
                Write-Verbose ("Setting Retry Delay to " + $HostRetryDelaySeconds)
                $hostRemediationConfig.retryDelay = $HostRetryDelaySeconds
                $hostRemediationConfig.retryDelaySpecified = $true

                Write-Verbose ("Setting Retry Attempts to " + $HostNumberOfRetries)
                $hostRemediationConfig.numberOfRetries = $HostNumberOfRetries
                $hostRemediationConfig.numberOfRetriesSpecified = $true

            } # retry

            "FailTask" {
                Write-Verbose ("Configuring failure action to Fail Task.")

                ## Set failure action to FailTask
                $hostRemediationConfig.failureAction = "FailTask"

                ## The API seems to expect these to be enabled with a value of "1", even if we are configuring this for FailTask
                $hostRemediationConfig.retryDelaySpecified = $true
                $hostRemediationConfig.retryDelay = 1
                $hostRemediationConfig.numberOfRetriesSpecified = $true
                $hostRemediationConfig.numberOfRetries = 1

            } # failTask

        } # switch


        ## Check if a VM power action has been specified
        if ($PSBoundParameters.ContainsKey("HostPreRemediationPowerAction")) {

            $hostRemediationConfig.preRemediationPowerAction = $HostPreRemediationPowerAction
            Write-Verbose ("VM power action has been set to " + $HostPreRemediationPowerAction)

        } # if


        ## Check if disable DPM has been specified.
        if ($PSBoundParameters.ContainsKey("ClusterDisableDistributedPowerManagement")) {

            Write-Verbose ("Setting Disable DPM to " + $ClusterDisableDistributedPowerManagement)
            $hostRemediationConfig.disableDpm = $ClusterDisableDistributedPowerManagement
            $hostRemediationConfig.disableDpmSpecified = $true

        } # if


        ## Check if disable HAC has been specified.
        if ($PSBoundParameters.ContainsKey("ClusterDisableHac")) {

            Write-Verbose ("Setting Disable DPM to " + $ClusterDisableHac)
            $hostRemediationConfig.disableHac = $ClusterDisableHac
            $hostRemediationConfig.disableHacSpecified = $true

        } # if


        ## Check if disable FT has been specified.
        if ($PSBoundParameters.ContainsKey("ClusterDisableFaultTolerance")) {

            Write-Verbose ("Setting Disable DPM to " + $ClusterDisableFaultTolerance)
            $hostRemediationConfig.disableFt = $ClusterDisableFaultTolerance
            $hostRemediationConfig.disableFtSpecified = $true

        } # if


        ## Check if allow PXE booted hosts has been specified.
        if ($PSBoundParameters.ContainsKey("HostEnablePXEbootHostPatching")) {

            Write-Verbose ("Setting Allow PXE Booted Hosts to " + $HostEnablePXEbootHostPatching)
            $hostRemediationConfig.allowStatelessRemediation = $HostEnablePXEbootHostPatching
            $hostRemediationConfig.allowStatelessRemediationSpecified = $true

        } # if


        ## Check if evacuateOfflineVMs has been specified.
        if ($PSBoundParameters.ContainsKey("HostEvacuateOfflineVMs")) {

            Write-Verbose ("Setting Evacuate Powered Off and Suspended VMs to " + $HostEvacuateOfflineVMs)
            $hostRemediationConfig.evacuateOfflineVMs = $HostEvacuateOfflineVMs
            $hostRemediationConfig.evacuateOfflineVMsSpecified = $true

        } # if


        ## Check if disconnectRemovableDevices has been specified.
        if ($PSBoundParameters.ContainsKey("HostDisableMediaDevices")) {

            Write-Verbose ("Setting Disconnect Removable Devices to " + $HostDisableMediaDevices)
            $hostRemediationConfig.disconnectRemovableDevices = $HostDisableMediaDevices
            $hostRemediationConfig.disconnectRemovableDevicesSpecified = $true

        } # if


        ## Check if enableQuickBoot has been specified.
        if ($PSBoundParameters.ContainsKey("HostEnableQuickBoot")) {

            Write-Verbose ("Setting Enable Quick Boot to " + $HostEnableQuickBoot)
            $hostRemediationConfig.enableLoadEsx = $HostEnableQuickBoot
            $hostRemediationConfig.enableLoadEsxSpecified = $true

        } # if


        ## Check if parallelRemediation has been specified.
        if ($PSBoundParameters.ContainsKey("ClusterEnableParallelRemediation")) {

            ## There is a quirk of the GUI versus the API.
            ## In the GUI, the user must select "Enabled for hosts in maintenance mode" to enable parallel remediation.
            ## However this will skip all hosts not in MM mode.
            ## Oddly, enabling parallel remediation without MM hosts via API is possible.
            ## An unelegant solution is to set enableParallelRemediateOfMMHosts to true is it's not explicitely provided by the user, resuling in behaviour as per GUI.
            ## If it is specificed as false, then we set it to false to allow the user to perform parallel remediation at runtime.

            Write-Verbose ("Setting Parallel Remediation to " + $ClusterEnableParallelRemediation)
            $hostRemediationConfig.concurrentRemediationInCluster = $ClusterEnableParallelRemediation
            $hostRemediationConfig.concurrentRemediationInClusterSpecified = $true

            if ($PSBoundParameters.ContainsKey("enableParallelRemediateOfMMHosts")) {

                ## The user has explicitely set this parameter, adhere to their preference.
                $hostRemediationConfig.enableParallelRemediateOfMMHosts = $enableParallelRemediateOfMMHosts
                $hostRemediationConfig.enableParallelRemediateOfMMHostsSpecified = $true
            } # if
            else {

                ## The user has not specified this parameter. We will assume GUI behaviour and set this to true.
                $hostRemediationConfig.enableParallelRemediateOfMMHosts = $true
                $hostRemediationConfig.enableParallelRemediateOfMMHostsSpecified = $true
            } # else


            ## Check ClusterMaxConcurrentRemediations. If it's not specified, or the value is 0, we set to automatic.
            if ((!$ClusterMaxConcurrentRemediations) -or ($ClusterMaxConcurrentRemediations -eq 0)) {

                $hostRemediationConfig.maxHostsForParallelRemediationInCluster = 0
                $hostRemediationConfig.maxHostsForParallelRemediationInClusterSpecified = $true

            } # if
            else {

                $hostRemediationConfig.maxHostsForParallelRemediationInCluster = $ClusterMaxConcurrentRemediations
                $hostRemediationConfig.maxHostsForParallelRemediationInClusterSpecified = $true

            } # else

        } # if


        ## We are done, return completed configuration object
        return $hostRemediationConfig

    } # process

    end {

        Write-Verbose ("Function completed.")

    } # end

} # function