functions/Set-WUGDeviceMaintenanceSchedule.ps1

    <#
    .SYNOPSIS
        Configures maintenance schedules for specified devices in WhatsUp Gold.
 
    .DESCRIPTION
        The Set-WUGDeviceMaintenanceSchedule function allows administrators to create, update, or delete maintenance schedules for devices managed by WhatsUp Gold.
        It supports various scheduling types, including Daily, Weekly, Monthly, Monthly Advanced, Yearly, and Yearly Advanced schedules.
        Users can define schedules by specifying individual parameters or by providing a configuration object.
        Additionally, the function enables the deletion of all existing maintenance schedules for one or more devices.
 
    .PARAMETER DeviceId
        Specifies the ID(s) of the device(s) for which the maintenance schedule will be set.
        This parameter is mandatory across all parameter sets.
 
    .PARAMETER ScheduleType
        Defines the type of maintenance schedule to apply.
        Valid options are: 'Daily', 'Weekly', 'Monthly', 'MonthlyAdvanced', 'Yearly', 'YearlyAdvanced'.
        This parameter is mandatory when using the 'ByParameters' parameter set.
 
    .PARAMETER StartTimeHour
        Specifies the hour when the maintenance window starts.
        This parameter is mandatory when using the 'ByParameters' parameter set.
 
    .PARAMETER StartTimeMinute
        Specifies the minute when the maintenance window starts.
        Defaults to 0 if not provided.
 
    .PARAMETER EndTimeHour
        Specifies the hour when the maintenance window ends.
        This parameter is mandatory when using the 'ByParameters' parameter set.
 
    .PARAMETER EndTimeMinute
        Specifies the minute when the maintenance window ends.
        Defaults to 0 if not provided.
 
    .PARAMETER RecurEvery
        Determines the recurrence interval for the schedule.
        For example, a value of 1 means the schedule repeats every day/week/month/year based on the ScheduleType.
        Defaults to 1.
 
    .PARAMETER DaysOfWeek
        Specifies the days of the week when the maintenance schedule should occur.
        Applicable for 'Weekly' ScheduleType.
 
    .PARAMETER DayOfMonth
        Defines the day of the month for the maintenance schedule.
        Applicable for 'Monthly' and 'Yearly' ScheduleTypes.
 
    .PARAMETER Occurence
        Indicates the occurrence pattern within the month or year, such as 'First', 'Second', 'Third', 'Fourth', or 'Last'.
        Applicable for 'MonthlyAdvanced' and 'YearlyAdvanced' ScheduleTypes.
 
    .PARAMETER DayOfWeek
        Specifies the day of the week associated with the occurrence pattern.
        Applicable for 'MonthlyAdvanced' and 'YearlyAdvanced' ScheduleTypes.
 
    .PARAMETER Month
        Defines the month for the maintenance schedule.
        Applicable for 'Yearly' and 'YearlyAdvanced' ScheduleTypes.
 
    .PARAMETER EffectiveStartDate
        Sets the start date for the maintenance schedule.
        If not specified, defaults to the current date.
 
    .PARAMETER EffectiveExpirationDate
        Sets the expiration date for the maintenance schedule.
        If not specified, the schedule does not expire.
 
    .PARAMETER Config
        Provides a configuration object containing one or more maintenance schedules.
        Applicable when using the 'ByConfig' parameter set.
 
    .PARAMETER DeleteAllSchedules
        Deletes all existing maintenance schedules for the specified device(s).
        Applicable when using the 'ByDeletion' parameter set.
 
    .EXAMPLE
        # Create a Yearly Advanced maintenance schedule for device 2367 using individual parameters
        Set-WUGDeviceMaintenanceSchedule `
            -DeviceId 2367 `
            -ScheduleType 'YearlyAdvanced' `
            -StartTimeHour 1 `
            -EndTimeHour 1 `
            -Occurence 'First' `
            -DayOfWeek 'Monday' `
            -Month 'December'
 
    .EXAMPLE
        # Create a Monthly Advanced maintenance schedule for device 2367 using a configuration object
        $sched = @{
            ScheduleType = 'MonthlyAdvanced'
            StartTimeHour = 1
            EndTimeHour = 1
            Occurence = 'Last'
            DayOfWeek = 'Saturday'
            EffectiveStartDate = @{ day = 29; month = 'september'; year = 2024 }
        }
        Set-WUGDeviceMaintenanceSchedule -DeviceId 2367 -Config $sched
 
    .EXAMPLE
        # Retrieve an existing maintenance schedule and update it using the -Config parameter
        $sched = Get-WUGDeviceMaintenanceSchedule -DeviceID 2367
        $sched.ScheduleType = 'YearlyAdvanced'
        $sched.Occurence = 'First'
        $sched.DayOfWeek = 'Monday'
        $sched.Month = 'December'
        Set-WUGDeviceMaintenanceSchedule -DeviceId 2367 -Config $sched
 
    .EXAMPLE
        # Delete all maintenance schedules for device 2367
        Set-WUGDeviceMaintenanceSchedule -DeviceId 2367 -DeleteAllSchedules
 
    .PARAMETER ByParameters
        (Parameter Set Name) Use individual parameters to define the maintenance schedule.
 
    .PARAMETER ByConfig
        (Parameter Set Name) Use a configuration object to define one or more maintenance schedules.
 
    .PARAMETER ByDeletion
        (Parameter Set Name) Delete all existing maintenance schedules for the specified device(s).
 
    .NOTES
        - Ensure that the global variables `$WUGBearerHeaders` and `$WhatsUpServerBaseURI` are set before invoking this function.
          These are typically initialized by running the `Connect-WUGServer` function.
        - The `-Config` parameter expects an object with properties matching the schedule configuration.
          Use the output from `Get-WUGDeviceMaintenanceSchedule` as a template for the configuration object.
          Author: Jason Alberino (jason@wug.ninja) 2024-09-29
 
    .LINK
        https://docs.ipswitch.com/NM/WhatsUpGold2024/02_Guides/rest_api/index.html#operation/Device_UpdateMaintenanceBatchSchedule
        https://docs.ipswitch.com/NM/WhatsUpGold2024/02_Guides/rest_api/index.html#operation/Device_UpdateMaintenanceSchedule
 
    #>

function Set-WUGDeviceMaintenanceSchedule {
    [CmdletBinding(DefaultParameterSetName = 'ByParameters')]
    param(
        # Common Parameters for All Parameter Sets
        [Parameter(Mandatory=$true, Position=0, ParameterSetName='ByParameters')]
        [Parameter(Mandatory=$true, Position=0, ParameterSetName='ByConfig')]
        [Parameter(Mandatory=$true, Position=0, ParameterSetName='ByDeletion')]
        [Alias('id')]
        [int[]]$DeviceId,

        # Parameters for 'ByParameters' Parameter Set
        [Parameter(Mandatory=$true, ParameterSetName='ByParameters')]
        [int]$StartTimeHour,

        [Parameter(ParameterSetName='ByParameters')]
        [int]$StartTimeMinute = 0,

        [Parameter(Mandatory=$true, ParameterSetName='ByParameters')]
        [int]$EndTimeHour,

        [Parameter(ParameterSetName='ByParameters')]
        [int]$EndTimeMinute = 0,

        [Parameter(Mandatory=$true, ParameterSetName='ByParameters')]
        [ValidateSet('Daily', 'Weekly', 'Monthly', 'MonthlyAdvanced', 'Yearly', 'YearlyAdvanced')]
        [string]$ScheduleType,

        [Parameter(ParameterSetName='ByParameters')]
        [int]$RecurEvery = 1,

        [Parameter(ParameterSetName='ByParameters')]
        [ValidateSet('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday')]
        [string[]]$DaysOfWeek,

        [Parameter(ParameterSetName='ByParameters')]
        [ValidateRange(1,31)]
        [int]$DayOfMonth,

        [Parameter(ParameterSetName='ByParameters')]
        [ValidateSet('First', 'Second', 'Third', 'Fourth', 'Last')]
        [string]$Occurence,

        [Parameter(ParameterSetName='ByParameters')]
        [ValidateSet('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday')]
        [string]$DayOfWeek,

        [Parameter(ParameterSetName='ByParameters')]
        [ValidateSet('january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december')]
        [string]$Month,

        [Parameter(ParameterSetName='ByParameters')]
        [object]$EffectiveStartDate,

        [Parameter(ParameterSetName='ByParameters')]
        [object]$EffectiveExpirationDate,

        # Parameters for 'ByConfig' Parameter Set
        [Parameter(Mandatory=$true, ParameterSetName='ByConfig')]
        [array]$Config,

        # Switch Parameter for 'ByDeletion' Parameter Set
        [Parameter(Mandatory=$true, ParameterSetName='ByDeletion')]
        [switch]$DeleteAllSchedules
    )

    begin {
        Write-Debug "Starting Set-WUGDeviceMaintenanceSchedule function"

        # Check for required global variables
        if (-not $global:WUGBearerHeaders) {
            Write-Error -Message "Authorization header not set. Please run Connect-WUGServer first."
            return
        }
        if (-not $global:WhatsUpServerBaseURI) {
            Write-Error -Message "Base URI not found. Please run Connect-WUGServer."
            return
        }
    }

    process {
        switch ($PSCmdlet.ParameterSetName) {
            'ByParameters' {
                # Validate parameters based on ScheduleType
                switch ($ScheduleType) {
                    'Daily' {
                        # No additional parameters required
                        if (-not $StartTimeHour -or -not $EndTimeHour) {
                            throw "StartTimeHour and EndTimeHour are required for 'Daily' ScheduleType."
                        }
                    }
                    'Weekly' {
                        if (-not $DaysOfWeek -or $DaysOfWeek.Count -eq 0) {
                            throw "When ScheduleType is 'Weekly', the DaysOfWeek parameter is required."
                        }
                        if (-not $StartTimeHour -or -not $EndTimeHour) {
                            throw "StartTimeHour and EndTimeHour are required for 'Weekly' ScheduleType."
                        }
                    }
                    'Monthly' {
                        if (-not $DayOfMonth) {
                            throw "When ScheduleType is 'Monthly', the DayOfMonth parameter is required."
                        }
                        if (-not $StartTimeHour -or -not $EndTimeHour) {
                            throw "StartTimeHour and EndTimeHour are required for 'Monthly' ScheduleType."
                        }
                    }
                    'MonthlyAdvanced' {
                        if (-not $Occurence -or -not $DayOfWeek) {
                            throw "When ScheduleType is 'MonthlyAdvanced', both Occurence and DayOfWeek parameters are required."
                        }
                        if (-not $StartTimeHour -or -not $EndTimeHour) {
                            throw "StartTimeHour and EndTimeHour are required for 'MonthlyAdvanced' ScheduleType."
                        }
                    }
                    'Yearly' {
                        if (-not $DayOfMonth -or -not $Month) {
                            throw "When ScheduleType is 'Yearly', both DayOfMonth and Month parameters are required."
                        }
                        if (-not $StartTimeHour -or -not $EndTimeHour) {
                            throw "StartTimeHour and EndTimeHour are required for 'Yearly' ScheduleType."
                        }
                    }
                    'YearlyAdvanced' {
                        if (-not $Occurence -or -not $DayOfWeek -or -not $Month) {
                            throw "When ScheduleType is 'YearlyAdvanced', Occurence, DayOfWeek, and Month parameters are required."
                        }
                        if (-not $StartTimeHour -or -not $EndTimeHour) {
                            throw "StartTimeHour and EndTimeHour are required for 'YearlyAdvanced' ScheduleType."
                        }
                    }
                    default {
                        throw "Invalid ScheduleType: $ScheduleType"
                    }
                }

                # If EffectiveStartDate is not specified, default to today's date
                if (-not $EffectiveStartDate) {
                    $today = Get-Date
                    $EffectiveStartDate = @{
                        "day"   = $today.Day
                        "month" = $today.ToString('MMMM').ToLower()
                        "year"  = $today.Year
                    }
                }

                # Build the schedule object based on ScheduleType
                $schedule = @{
                    "effectiveStartDate" = $EffectiveStartDate
                    "duration" = @{
                        "startTime" = @{
                            "hour" = $StartTimeHour
                            "minute" = $StartTimeMinute
                        }
                        "endTime" = @{
                            "hour" = $EndTimeHour
                            "minute" = $EndTimeMinute
                        }
                    }
                }

                switch ($ScheduleType) {
                    'Daily' {
                        $schedule["daily"] = @{
                            "repeat" = $RecurEvery
                        }
                    }
                    'Weekly' {
                        # Build daysOfTheWeek as a hashtable
                        $daysOfTheWeek = @{}
                        foreach ($day in $DaysOfWeek) {
                            $daysOfTheWeek[$day.ToLower()] = $true
                        }
                        $schedule["weekly"] = @{
                            "repeat" = $RecurEvery
                            "daysOfTheWeek" = $daysOfTheWeek
                        }
                    }
                    'Monthly' {
                        $schedule["monthly"] = @{
                            "repeat" = $RecurEvery
                            "day" = $DayOfMonth
                        }
                    }
                    'MonthlyAdvanced' {
                        $schedule["monthlyAdvance"] = @{
                            "repeat" = $RecurEvery
                            "occurence" = $Occurence.ToLower()
                            "dayOfWeek" = $DayOfWeek.ToLower()
                        }
                    }
                    'Yearly' {
                        $schedule["yearly"] = @{
                            "day" = $DayOfMonth
                            "month" = $Month.ToLower()
                        }
                    }
                    'YearlyAdvanced' {
                        $schedule["yearlyAdvance"] = @{
                            "week" = $Occurence.ToLower()
                            "dayOfWeek" = $DayOfWeek.ToLower()
                            "month" = $Month.ToLower()
                        }
                    }
                    default {
                        throw "Invalid ScheduleType: $ScheduleType"
                    }
                }

                # Remove 'effectiveExpirationDate' if it's null
                if ($null -eq $EffectiveExpirationDate) {
                    $schedule.PSObject.Properties.Remove('effectiveExpirationDate') | Out-Null
                } else {
                    $schedule["effectiveExpirationDate"] = $EffectiveExpirationDate
                }

                $schedules = @($schedule)
                $body = @{
                    "schedules" = $schedules
                    "devices" = $DeviceId
                }

                $jsonBody = ConvertTo-Json -InputObject $body -Depth 10
                Write-Debug "Request Body: $jsonBody"

                # Send the PATCH request to the API
                $url = "$($global:WhatsUpServerBaseURI)/api/v1/devices/-/config/maintenance/schedule"
                Write-Debug "Sending PATCH request to URL: $url"

                try {
                    $result = Get-WUGAPIResponse -Uri $url -Method "PATCH" -Body $jsonBody
                    # Directly output the 'data' property for better readability
                    Write-Output $result.data
                }
                catch {
                    # Capture detailed error information
                    if ($_.Exception.Response) {
                        $responseStream = $_.Exception.Response.GetResponseStream()
                        $reader = New-Object System.IO.StreamReader($responseStream)
                        $responseBody = $reader.ReadToEnd()
                        Write-Error "API call failed. Status Code: $($_.Exception.Response.StatusCode) ($($_.Exception.Response.StatusDescription)). Response Body: $responseBody"
                    }
                    else {
                        Write-Error "API call failed. Exception: $($_.Exception.Message)"
                    }
                    return
                }
            }
            'ByConfig' {
                # Handle setting the schedule via Config object (Supports Single and Multiple Devices)

                if ($DeviceId.Count -eq 0) {
                    Write-Error "At least one DeviceId must be specified with the -Config parameter."
                    return
                }

                $isSingleDevice = $DeviceId.Count -eq 1

                if ($isSingleDevice) {
                    # Single Device: Use PUT
                    $deviceId = $DeviceId[0]

                    # Transform each schedule in Config to the API expected format
                    $scheduleList = @()

                    foreach ($sched in $Config) {
                        # Ensure EffectiveStartDate is set
                        if (-not $sched.effectiveStartDate) {
                            $today = Get-Date
                            $sched.effectiveStartDate = @{
                                "day" = $today.Day
                                "month" = $today.ToString('MMMM').ToLower()
                                "year" = $today.Year
                            }
                        }

                        # Remove 'effectiveExpirationDate' if it's null or not set
                        if (-not $sched.effectiveExpirationDate) {
                            $sched.PSObject.Properties.Remove('effectiveExpirationDate') | Out-Null
                        }

                        # Normalize ScheduleType by removing spaces and converting to lowercase
                        $normalizedScheduleType = $sched.ScheduleType.ToLower().Replace(' ', '')

                        # Build the schedule object
                        $schedule = @{
                            "effectiveStartDate" = $sched.effectiveStartDate
                            "duration" = @{
                                "startTime" = @{
                                    "hour" = $sched.StartTimeHour
                                    "minute" = $sched.StartTimeMinute
                                }
                                "endTime" = @{
                                    "hour" = $sched.EndTimeHour
                                    "minute" = $sched.EndTimeMinute
                                }
                            }
                        }

                        # Depending on normalized ScheduleType, add the appropriate schedule type field
                        switch ($normalizedScheduleType) {
                            'daily' {
                                $schedule["daily"] = @{
                                    "repeat" = $sched.RecurEvery
                                }
                            }
                            'weekly' {
                                # Build daysOfTheWeek as a hashtable
                                $daysOfTheWeek = @{}
                                if ($sched.DaysOfWeek) {
                                    foreach ($day in $sched.DaysOfWeek) {
                                        $daysOfTheWeek[$day.ToLower()] = $true
                                    }
                                }
                                $schedule["weekly"] = @{
                                    "repeat" = $sched.RecurEvery
                                    "daysOfTheWeek" = $daysOfTheWeek
                                }
                            }
                            'monthly' {
                                $schedule["monthly"] = @{
                                    "repeat" = $sched.RecurEvery
                                    "day" = $sched.DayOfMonth
                                }
                            }
                            'monthlyadvanced' {
                                $schedule["monthlyAdvance"] = @{
                                    "repeat" = $sched.RecurEvery
                                    "occurence" = $sched.Occurence.ToLower()
                                    "dayOfWeek" = $sched.DayOfWeek.ToLower()
                                }
                            }
                            'yearly' {
                                $schedule["yearly"] = @{
                                    "day" = $sched.DayOfMonth
                                    "month" = $sched.Month.ToLower()
                                }
                            }
                            'yearlyadvanced' {
                                $schedule["yearlyAdvance"] = @{
                                    "week" = $sched.Occurence.ToLower()
                                    "dayOfWeek" = $sched.DayOfWeek.ToLower()
                                    "month" = $sched.Month.ToLower()
                                }
                            }
                            default {
                                throw "Invalid ScheduleType in Config: $($sched.ScheduleType)"
                            }
                        }

                        $scheduleList += $schedule
                    }

                    $body = @{
                        "schedules" = $scheduleList
                    }

                    $jsonBody = ConvertTo-Json -InputObject $body -Depth 10
                    Write-Debug "Request Body: $jsonBody"

                    # Send the PUT request to the API
                    $url = "$($global:WhatsUpServerBaseURI)/api/v1/devices/$deviceId/config/maintenance/schedule"
                    Write-Debug "Sending PUT request to URL: $url"

                    try {
                        $result = Get-WUGAPIResponse -Uri $url -Method "PUT" -Body $jsonBody
                        # Directly output the 'data' property for better readability
                        Write-Output $result.data
                    }
                    catch {
                        # Capture detailed error information
                        if ($_.Exception.Response) {
                            $responseStream = $_.Exception.Response.GetResponseStream()
                            $reader = New-Object System.IO.StreamReader($responseStream)
                            $responseBody = $reader.ReadToEnd()
                            Write-Error "API call failed. Status Code: $($_.Exception.Response.StatusCode) ($($_.Exception.Response.StatusDescription)). Response Body: $responseBody"
                        }
                        else {
                            Write-Error "API call failed. Exception: $($_.Exception.Message)"
                        }
                        return
                    }
                }
                else {
                    # Multiple Devices: Use PATCH
                    # Transform each schedule in Config to the API expected format
                    $scheduleList = @()

                    foreach ($sched in $Config) {
                        # Ensure EffectiveStartDate is set
                        if (-not $sched.effectiveStartDate) {
                            $today = Get-Date
                            $sched.effectiveStartDate = @{
                                "day" = $today.Day
                                "month" = $today.ToString('MMMM').ToLower()
                                "year" = $today.Year
                            }
                        }

                        # Remove 'effectiveExpirationDate' if it's null or not set
                        if (-not $sched.effectiveExpirationDate) {
                            $sched.PSObject.Properties.Remove('effectiveExpirationDate') | Out-Null
                        }

                        # Normalize ScheduleType by removing spaces and converting to lowercase
                        $normalizedScheduleType = $sched.ScheduleType.ToLower().Replace(' ', '')

                        # Build the schedule object
                        $schedule = @{
                            "effectiveStartDate" = $sched.effectiveStartDate
                            "duration" = @{
                                "startTime" = @{
                                    "hour" = $sched.StartTimeHour
                                    "minute" = $sched.StartTimeMinute
                                }
                                "endTime" = @{
                                    "hour" = $sched.EndTimeHour
                                    "minute" = $sched.EndTimeMinute
                                }
                            }
                        }

                        # Depending on normalized ScheduleType, add the appropriate schedule type field
                        switch ($normalizedScheduleType) {
                            'daily' {
                                $schedule["daily"] = @{
                                    "repeat" = $sched.RecurEvery
                                }
                            }
                            'weekly' {
                                # Build daysOfTheWeek as a hashtable
                                $daysOfTheWeek = @{}
                                if ($sched.DaysOfWeek) {
                                    foreach ($day in $sched.DaysOfWeek) {
                                        $daysOfTheWeek[$day.ToLower()] = $true
                                    }
                                }
                                $schedule["weekly"] = @{
                                    "repeat" = $sched.RecurEvery
                                    "daysOfTheWeek" = $daysOfTheWeek
                                }
                            }
                            'monthly' {
                                $schedule["monthly"] = @{
                                    "repeat" = $sched.RecurEvery
                                    "day" = $sched.DayOfMonth
                                }
                            }
                            'monthlyadvanced' {
                                $schedule["monthlyAdvance"] = @{
                                    "repeat" = $sched.RecurEvery
                                    "occurence" = $sched.Occurence.ToLower()
                                    "dayOfWeek" = $sched.DayOfWeek.ToLower()
                                }
                            }
                            'yearly' {
                                $schedule["yearly"] = @{
                                    "day" = $sched.DayOfMonth
                                    "month" = $sched.Month.ToLower()
                                }
                            }
                            'yearlyadvanced' {
                                $schedule["yearlyAdvance"] = @{
                                    "week" = $sched.Occurence.ToLower()
                                    "dayOfWeek" = $sched.DayOfWeek.ToLower()
                                    "month" = $sched.Month.ToLower()
                                }
                            }
                            default {
                                throw "Invalid ScheduleType in Config: $($sched.ScheduleType)"
                            }
                        }

                        $scheduleList += $schedule
                    }

                    $body = @{
                        "devices" = $DeviceId
                        "schedules" = $scheduleList
                    }

                    $jsonBody = ConvertTo-Json -InputObject $body -Depth 10
                    Write-Debug "Request Body: $jsonBody"

                    # Send the PATCH request to the API
                    $url = "$($global:WhatsUpServerBaseURI)/api/v1/devices/-/config/maintenance/schedule"
                    Write-Debug "Sending PATCH request to URL: $url"

                    try {
                        $result = Get-WUGAPIResponse -Uri $url -Method "PATCH" -Body $jsonBody
                        # Directly output the 'data' property for better readability
                        Write-Output $result.data
                    }
                    catch {
                        # Capture detailed error information
                        if ($_.Exception.Response) {
                            $responseStream = $_.Exception.Response.GetResponseStream()
                            $reader = New-Object System.IO.StreamReader($responseStream)
                            $responseBody = $reader.ReadToEnd()
                            Write-Error "API call failed. Status Code: $($_.Exception.Response.StatusCode) ($($_.Exception.Response.StatusDescription)). Response Body: $responseBody"
                        }
                        else {
                            Write-Error "API call failed. Exception: $($_.Exception.Message)"
                        }
                        return
                    }
                }
            }
            'ByDeletion' {
                # Handle deletion of all schedules (Multiple Devices using PATCH)

                $url = "$($global:WhatsUpServerBaseURI)/api/v1/devices/-/config/maintenance/schedule"
                Write-Debug "Sending PATCH DELETE request to URL: $url"

                $body = @{
                    "devices" = $DeviceId
                }

                $jsonBody = ConvertTo-Json -InputObject $body
                Write-Debug "Request Body: $jsonBody"

                try {
                    $result = Get-WUGAPIResponse -Uri $url -Method "PATCH" -Body $jsonBody
                    # Directly output the 'data' property for better readability
                    Write-Output $result.data
                }
                catch {
                    # Capture detailed error information
                    if ($_.Exception.Response) {
                        $responseStream = $_.Exception.Response.GetResponseStream()
                        $reader = New-Object System.IO.StreamReader($responseStream)
                        $responseBody = $reader.ReadToEnd()
                        Write-Error "API call failed. Status Code: $($_.Exception.Response.StatusCode) ($($_.Exception.Response.StatusDescription)). Response Body: $responseBody"
                    }
                    else {
                        Write-Error "API call failed. Exception: $($_.Exception.Message)"
                    }
                    return
                }
            }
            default {
                Write-Error "Invalid parameter set."
                return
            }
        }
    }

    end {
        Write-Debug "Set-WUGDeviceMaintenanceSchedule function completed."
    }
}



# SIG # Begin signature block
# MIIVvgYJKoZIhvcNAQcCoIIVrzCCFasCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBuSyTp52Xdh9og
# pLgC8Uj/aCeARKMxcfGensivAP/4PKCCEfkwggVvMIIEV6ADAgECAhBI/JO0YFWU
# jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI
# DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM
# EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy
# dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG
# EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv
# IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s
# hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD
# J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7
# P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme
# me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz
# T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q
# RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz
# mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc
# QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T
# OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/
# AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID
# AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD
# VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV
# HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE
# VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v
# ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE
# KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI
# hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF
# OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC
# J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ
# pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl
# d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH
# +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M
# UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD
# VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv
# ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5
# NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp
# BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G
# CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI
# ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV
# DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3
# 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw
# mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm
# +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe
# dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4
# 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM
# dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY
# MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU
# pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV
# HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG
# A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1
# YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG
# AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl
# U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0
# aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh
# w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd
# OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj
# cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc
# WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO
# hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs
# zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7
# 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J
# KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH
# j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2
# Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/
# L9Uo2bC5a4CH2RwwggZkMIIEzKADAgECAhEA6IUbK/8zRw2NKvPg4jKHsTANBgkq
# hkiG9w0BAQwFADBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1p
# dGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2
# MB4XDTIzMDQxOTAwMDAwMFoXDTI2MDcxODIzNTk1OVowVTELMAkGA1UEBhMCVVMx
# FDASBgNVBAgMC0Nvbm5lY3RpY3V0MRcwFQYDVQQKDA5KYXNvbiBBbGJlcmlubzEX
# MBUGA1UEAwwOSmFzb24gQWxiZXJpbm8wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
# ggIKAoICAQC2JA01BehqpO3INejKVsKScaS9sd0Hjoz1tceFig6Yyu2glTKimH9n
# r9l5438Cjpc1x+n42gMfnS5Cza4tZUWr1usOq3d0TljKFOOSW8Uve1J+PC0f/Hxp
# DbI8hE38ICDmgv8EozBOgo4lPm/rDHVTHgiRZvy1H8gPTuE13ck2sevVslku2E2F
# 8wst5Kb12OqngF96RXptEeM0iTipPhfNinWCa8e58+mbt1dHCbX46593DRd3yQv+
# rvPkIh9QkMGmumfjV5lv1S3iqf/Vg6XP9R3lTPMWNO2IEzIjk12t817rU3xYyf2Q
# 4dlA/i1bRpFfjEVcxQiZJdQKnQlqd3hOk0tr8bxTI3RZxgOLRgC8mA9hgcnJmreM
# WP4CwXZUKKX13pMqzrX/qiSUsB+Mvcn7LHGEo9pJIBgMItZW4zn4uPzGbf53EQUW
# nPfUOSBdgkRAdkb/c7Lkhhc1HNPWlUqzS/tdopI7+TzNsYr7qEckXpumBlUSONoJ
# n2V1zukFbgsBq0mRWSZf+ut3OVGo7zSYopsMXSIPFEaBcxNuvcZQXv6YdXEsDpvG
# mysbgVa/7uP3KwH9h79WeFU/TiGEISH5B59qTg26+GMRqhyZoYHj7wI36omwSNja
# tUo5cYz4AEYTO58gceMcztNO45BynLwPbZwZ0bxPN2wL1ruIYd+ewQIDAQABo4IB
# rjCCAaowHwYDVR0jBBgwFoAUDyrLIIcouOxvSK4rVKYpqhekzQwwHQYDVR0OBBYE
# FJHuVIzRubayI0tfw82Q7Q/47iu9MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
# AjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMEoGA1UdIARDMEEwNQYMKwYBBAGyMQEC
# AQMCMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeB
# DAEEATBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLnNlY3RpZ28uY29tL1Nl
# Y3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNybDB5BggrBgEFBQcBAQRtMGsw
# RAYIKwYBBQUHMAKGOGh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1B1Ymxp
# Y0NvZGVTaWduaW5nQ0FSMzYuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5z
# ZWN0aWdvLmNvbTAjBgNVHREEHDAagRhqYXNvbi5hbGJlcmlub0BnbWFpbC5jb20w
# DQYJKoZIhvcNAQEMBQADggGBAET0EFH0r+hqoQWr4Ha9UDuEv28rTgV2aao1nFRg
# GZ/5owM7x9lxappLUbgQFfeIzzAsp3gwTKMYf47njUjvOBZD9zV/3I/vaLmY2enm
# MXZ48Om9GW4pNmnvsef2Ub1/+dRzgs8UFX5wBJcfy4OWP3t0OaKJkn+ZltgFF1cu
# L/RPiWSRcZuhh7dIWgoPQrVx8BtC8pkh4F5ECxogQnlaDNBzGYf1UYNfEQOFec31
# UK8oENwWx5/EaKFrSi9Y4tu6rkpH0idmYds/1fvqApGxujhvCO4Se8Atfc98icX4
# DWkc1QILREHiVinmoO3smmjB5wumgP45p9OVJXhI0D0gUFQfOSappa5eO2lbnNVG
# 90rCsADmVpDDmNt2qPG01luBbX6VtWMP2thjP5/CWvUy6+xfrhlqvwZyZt3SKtuf
# FWkqnNWMnmgtBNSmBF5+q8w5SJW+24qrncKJWSIim/nRtC11XnoI9SXlaucS3Nlb
# crQVicXOtbhksEqMTn52i8NOfzGCAxswggMXAgEBMGkwVDELMAkGA1UEBhMCR0Ix
# GDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UEAxMiU2VjdGlnbyBQdWJs
# aWMgQ29kZSBTaWduaW5nIENBIFIzNgIRAOiFGyv/M0cNjSrz4OIyh7EwDQYJYIZI
# AWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0B
# CQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAv
# BgkqhkiG9w0BCQQxIgQgrcnnx6RHL/kIByUMzsDH+JBGD/vSSMNNUJ1J7C07zkQw
# DQYJKoZIhvcNAQEBBQAEggIAOhvZ8OULTcPSy9iWTELKh6P2JOQnmEs3yra+pKwM
# Cv0C7FJBbYT/X78EFKSMvuw/XOvGI4UWojw+Lt2KaUB0oIPJVdGg72PMZyodop+t
# As0ur2ImZEy5I6CggevDs0jHMvJRVhr7uwQHM9bp1cd+s41ISqen29oVAAO4tmYf
# +njewXtQ/mWRMf5WuNQr1+EmpNyrZwfeRxFA/soO5EltA3uRP2Sz+81Fystbo5rO
# AgePbb561bTXDHnflVjdEUgyT+IHCdi7aWvYQdkHWKfTS9B41+MlQVqX7Ppa6oSP
# e9qWwHLuTCEBl9WHWRB7MtAoAuCg1nwwpZ3OSSmx4tsu94312P0hJ9p3qXYUaGli
# M76tq7Vt9VMcG9bbisXNx7tXfFEeaF4+GMGRCiOFdePGl56V3Qzujf1FL5OJgqr7
# t6RkLfoILbSQcWqBfOvcrMGM7FXEwRZeo3vBhigETARmSCDZ4EH9Fn8aKE7H4e9r
# stUeXZu9yS/LBUlWCRUl1wcGi/U7/GcQ/GuZXDT8wzT8VVZQzAj5hABrTPtIK8Z8
# xGLBFbj+nbrdTRuAWJKg+uaZGHtYQVFDRSF2QtVaCzAkqrFNSKG7gfkSVpdACv8J
# 9KLPFvZPWhWEJWKE0NgtdbI7SCRKeKcpNbAULGY3seHc0uBCszncVAqnDlSH/3Zl
# c/A=
# SIG # End signature block