functions/Get-WUGDeviceMaintenanceSchedule.ps1
<#
.SYNOPSIS Retrieves maintenance schedules for specified devices in WhatsUp Gold. .DESCRIPTION The Get-WUGDeviceMaintenanceSchedule function fetches the current maintenance schedules configured for one or more devices managed by WhatsUp Gold. It supports retrieving schedules for individual devices or multiple devices simultaneously. The function processes the API response to provide a structured output containing detailed schedule information, including schedule type, recurrence, effective dates, and duration. .PARAMETER DeviceId Specifies the ID(s) of the device(s) for which the maintenance schedules will be retrieved. This parameter is mandatory and accepts one or more integer values. It supports pipeline input, allowing you to pass device IDs directly through the pipeline. .INPUTS System.Int32[] The function accepts integer values representing Device IDs from the pipeline. .OUTPUTS PSCustomObject[] Returns an array of custom objects, each representing a maintenance schedule for a device. The output includes properties such as: - DeviceID - StartTimeHour - StartTimeMinute - EndTimeHour - EndTimeMinute - ScheduleType - RecurEvery - DaysOfWeek - DayOfMonth - Occurence - DayOfWeek - Month - EffectiveStartDate - EffectiveExpirationDate .EXAMPLE # Retrieve maintenance schedules for device 2367 Get-WUGDeviceMaintenanceSchedule -DeviceId 2367 .EXAMPLE # Retrieve maintenance schedules for multiple devices and display the results Get-WUGDeviceMaintenanceSchedule -DeviceId 2367, 2368, 2369 | Format-Table -AutoSize .EXAMPLE # Retrieve maintenance schedules for device 2367 and update it using the -Config parameter $sched = Get-WUGDeviceMaintenanceSchedule -DeviceId 2367 # Modify the schedule as needed, for example, changing the ScheduleType $sched.ScheduleType = 'YearlyAdvanced' $sched.Occurence = 'First' $sched.DayOfWeek = 'Monday' $sched.Month = 'December' Set-WUGDeviceMaintenanceSchedule -DeviceId 2367 -Config $sched .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 function utilizes the WhatsUp Gold REST API to fetch maintenance schedules. Refer to the official WhatsUp Gold REST API documentation for more details: https://docs.ipswitch.com/NM/WhatsUpGold2024/02_Guides/rest_api/index.html#operation/Device_GetPollingConfig - The `Occurence` property is intentionally misspelled to match the API response. Ensure consistency when using this property. Author: Jason Alberino (jason@wug.ninja) 2024-09-29 #> #> function Get-WUGDeviceMaintenanceSchedule { [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('id')] [int[]]$DeviceId ) begin { Write-Debug "Function: Get-WUGDeviceMaintenanceSchedule -- DeviceIDs: $($DeviceID -join ', ')" # Check for required global variables if (-not $global:WUGBearerHeaders) { Write-Error -Message "Authorization header not set. Please run Connect-WUGServer first." Connect-WUGServer } if (-not $global:WhatsUpServerBaseURI) { Write-Error -Message "Base URI not found. Please run Connect-WUGServer." Connect-WUGServer } } process { $allMaintenanceConfigs = @() # Array to store all configurations $totalDevices = $DeviceID.Count $currentDeviceIndex = 0 foreach ($id in $DeviceID) { $currentDeviceIndex++ $percentComplete = [Math]::Round(($currentDeviceIndex / $totalDevices) * 100) Write-Progress -Activity "Fetching maintenance schedules" -Status "Processing Device ID $id ($currentDeviceIndex of $totalDevices)" -PercentComplete $percentComplete try { # Get the current maintenance configuration for each device $url = "$($global:WhatsUpServerBaseURI)/api/v1/devices/$id/config/polling" Write-Debug "Fetching maintenance schedule from: $url" $response = Get-WUGAPIResponse -Uri $url -Method Get # Check if the response contains expected data if (-not $response -or -not $response.data) { Write-Error "No data returned from API for DeviceID $id. Check if the API endpoint is correct and accessible." continue } # Extract the maintenance configuration $maintenance = $response.data.maintenance if ($maintenance -and $maintenance.schedules) { Write-Debug "Found $($maintenance.schedules.Count) maintenance schedules for DeviceID $id." # Iterate over each schedule foreach ($schedule in $maintenance.schedules) { # Initialize variables $scheduleType = 'Unknown' $recurEvery = $null $daysOfWeek = $null $dayOfMonth = $null $occurence = $null # Intentionally misspelled to match API $dayOfWeek = $null $month = $null # Extract start and end times as separate hour and minute properties $startHour = $schedule.duration.startTime.hour $startMinute = $schedule.duration.startTime.minute $endHour = $schedule.duration.endTime.hour $endMinute = $schedule.duration.endTime.minute # Extract effective dates $effectiveStartDate = $schedule.effectiveStartDate $effectiveExpirationDate = $schedule.effectiveExpirationDate # Determine Schedule Type if ($schedule.daily) { $scheduleType = 'Daily' $recurEvery = $schedule.daily.repeat } elseif ($schedule.weekly) { $scheduleType = 'Weekly' $recurEvery = $schedule.weekly.repeat $daysOfWeek = $schedule.weekly.daysOfTheWeek } elseif ($schedule.monthly) { $scheduleType = 'Monthly' $recurEvery = $schedule.monthly.repeat $dayOfMonth = $schedule.monthly.day } elseif ($schedule.monthlyAdvance) { $scheduleType = 'Monthly Advanced' $recurEvery = $schedule.monthlyAdvance.repeat $occurence = $schedule.monthlyAdvance.occurence # Intentionally misspelled $dayOfWeek = $schedule.monthlyAdvance.dayOfWeek } elseif ($schedule.yearly) { $scheduleType = 'Yearly' $dayOfMonth = $schedule.yearly.day $month = $schedule.yearly.month } elseif ($schedule.yearlyAdvance) { $scheduleType = 'Yearly Advanced' $occurence = $schedule.yearlyAdvance.week # Assuming 'week' is correctly spelled $dayOfWeek = $schedule.yearlyAdvance.dayOfWeek $month = $schedule.yearlyAdvance.month } # Build the schedule object with separate hour and minute properties $scheduleDetails = [PSCustomObject]@{ DeviceID = $id StartTimeHour = $startHour StartTimeMinute = $startMinute EndTimeHour = $endHour EndTimeMinute = $endMinute ScheduleType = $scheduleType RecurEvery = $recurEvery DaysOfWeek = $daysOfWeek DayOfMonth = $dayOfMonth Occurence = $occurence # Intentionally misspelled DayOfWeek = $dayOfWeek Month = $month EffectiveStartDate = $effectiveStartDate EffectiveExpirationDate = $effectiveExpirationDate } $allMaintenanceConfigs += $scheduleDetails } } else { Write-Debug "No maintenance schedules found for DeviceID $id." } } catch { Write-Error "Failed to get maintenance schedule for DeviceID ${id}: $($_.Exception.Message)" } } # Clear the progress bar after completion Write-Progress -Activity "Fetching maintenance schedules" -Completed } end { Write-Debug "Get-WUGDeviceMaintenanceSchedule function completed." return $allMaintenanceConfigs } } # SIG # Begin signature block # MIIVvgYJKoZIhvcNAQcCoIIVrzCCFasCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCB3KCFqw5Pci6E1 # fBd3JMqk8rdZ3BbXznM8KOmSPDjVx6CCEfkwggVvMIIEV6ADAgECAhBI/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 # BgkqhkiG9w0BCQQxIgQg0gqrhmN4jLaeaE2isX2YxvV5aZQqwDJlNY8xV+tfDm0w # DQYJKoZIhvcNAQEBBQAEggIAWnlnTL20+OIBMS30hrFietrt2p2VDjoTBA3Dy5kJ # VCjkXHBClMB22Iz2OWe641uD7/JJbHPbV3l6mPomt7/b9GzHu1iM2oo1nfMRknSK # HbcAcbFKJ3jS0z8aL7HHi5CQbtqBIfACzqzGWjkRzTzpdUooIcWGbyCcNMgkcoCT # Ej8KiEM4kdIxOWIjiIxCbaXkBI5HgmR5pkbZ7Df4tDwabNtPz56xAN9YUML4pdx5 # lLpdsrICRscQhLuEjhd4jagVXQyfhyCHmwly0JZUMUI0OlSp1AMmyGkzNsV6jnis # uajFcCnQHI8Zhj/kEx5mKWNIzEtoyHowCJe6kE349PE4xX4XALjBJqUYobwhqakF # OJCiueY2F3VF6ZbKmP85akcJEo/m5xLbDlaJihRn7/ME5Oci1Njmm96YXq8349Uu # lzfcvlDYBBXSPTzQuINQ7ut2j348m8L8+o1dRExlECMJdD6jIRXXVHBdyMJbnaNS # 7ntuOt807/0ofliiU5QXBcfWLuTsVOB8X+pCT8qQuMkPH5jnSpuaZyqd5229C+r/ # qJvs8BUuDn/u0kMONa8ROpBnAtDWS4pCYLVygyzXJb1m5Nnyq8a6BUprMRFW7VeT # QyEUwrllQ8NuC6vjuG4lxAcmdDyHAl7/8zvrhQQQiBg8jImwvxn3ZJhCumDcgBh2 # JvU= # SIG # End signature block |