Private/ConvertTo-VmPowerStoredSchedule.ps1
|
function ConvertTo-VmPowerStoredSchedule { <# .SYNOPSIS Turn an expanded schedule back into the camelCase shape the catalogue is written in. .DESCRIPTION Two things write a catalogue variable and they used to disagree about casing. The deployment writes camelCase, because that is the documented shape and what Bicep produces. This module stored the expanded object, which is PowerShell and therefore PascalCase. Every reader in the module is case-insensitive, so nothing complained. The runbook is where it mattered. Get-AutomationVariable hands a variable back as a Newtonsoft JObject, and a JObject indexes case-sensitively: reading 'name' finds the deployment's entries and returns empty for the module's. Both custom entries then keyed on an empty string, the second replaced the first, and a machine tagged with the lost one reported ScheduleNotInCatalogue - which looks exactly like a machine nobody onboarded. Measured against a real Automation Account on 2026-09-11. Tolerating the mismatch at the read side is in the runbook as well, because a catalogue stored by an older version is still out there. This is the other half: stop creating it. .PARAMETER Schedule An expanded schedule, as Expand-VmPowerSchedule returns it. #> [CmdletBinding()] [OutputType([ordered])] param( [Parameter(Mandatory)] $Schedule ) $actions = [System.Collections.Generic.List[object]]::new() foreach ($action in @($Schedule.Actions)) { if ($null -eq $action) { continue } $actions.Add([ordered]@{ action = [string]$action.Action at = [string]$action.At weekDays = @($action.WeekDays) months = @($action.Months) daysOfMonth = @($action.DaysOfMonth) }) } [ordered]@{ name = [string]$Schedule.Name displayName = [string]$Schedule.DisplayName timeZone = [string]$Schedule.TimeZone actions = $actions.ToArray() exceptDates = @($Schedule.ExceptDates) minimumDwellMinutes = [int]$Schedule.MinimumDwellMinutes startGraceMinutes = [int]$Schedule.StartGraceMinutes } } |