AzLocal.UpdateManagement.psd1
|
@{ # Script module or binary module file associated with this manifest. RootModule = 'AzLocal.UpdateManagement.psm1' # Version number of this module. ModuleVersion = '0.8.4' # Supported PSEditions CompatiblePSEditions = @('Desktop', 'Core') # ID used to uniquely identify this module GUID = 'a8b9c0d1-e2f3-4a5b-6c7d-8e9f0a1b2c3d' # Author of this module Author = 'Neil Bird, Microsoft' # Company or vendor of this module CompanyName = 'Microsoft' # Copyright statement for this module Copyright = '(c) Microsoft. All rights reserved.' # Description of the functionality provided by this module Description = 'PowerShell module to manage Azure Local (formerly Azure Stack HCI) cluster updates using Azure Update Manager APIs. Provides functions to start updates, check update status, list available updates, and monitor update runs. Renamed from AzStackHci.ManageUpdates in v0.7.3 to align with the Azure Local product name.' # Minimum version of the PowerShell engine required by this module PowerShellVersion = '5.1' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. NestedModules = @( # Private helpers (loaded first) 'Private/Convert-AzLocalUpdateWindowToCron.ps1', 'Private/ConvertFrom-AzLocalCronExpression.ps1', 'Private/ConvertFrom-AzLocalUpdateExclusion.ps1', 'Private/ConvertFrom-AzLocalScheduleYaml.ps1', 'Private/ConvertFrom-AzLocalUpdateExcluded.ps1', 'Private/ConvertFrom-AzLocalUpdateSideloaded.ps1', 'Private/ConvertFrom-AzLocalUpdateWindow.ps1', 'Private/Convert-AzLocalScheduleSchemaVersion.ps1', 'Private/ConvertTo-AzLocalAdditionalProperties.ps1', 'Private/ConvertTo-SafeCsvCollection.ps1', 'Private/ConvertTo-SafeCsvField.ps1', 'Private/ConvertTo-ScrubbedCliOutput.ps1', 'Private/ConvertTo-AzLocalUpdateRingKqlFilter.ps1', 'Private/Export-ResultsToJUnitXml.ps1', 'Private/Format-AzLocalDurationHuman.ps1', 'Private/Format-AzLocalIncidentBody.ps1', 'Private/Format-AzLocalUpdateRun.ps1', 'Private/Get-AzLocalClusterUpdateRuns.ps1', 'Private/Get-AzLocalItsmDedupeKey.ps1', 'Private/Get-AzLocalItsmTriggerDecision.ps1', 'Private/Get-AzLocalModuleRootManifestPath.ps1', 'Private/Get-AzLocalPipelineCustomiseMarkers.ps1', 'Private/Get-AzLocalRunEndTime.ps1', 'Private/Get-CurrentStepPath.ps1', 'Private/Get-DeepestActiveStep.ps1', 'Private/Get-DeepestErrorMessage.ps1', 'Private/Get-ExportFormat.ps1', 'Private/Get-HealthCheckFailureSummary.ps1', 'Private/Get-LastUpdateRunErrorSummary.ps1', 'Private/Get-LatestUpdateByYYMM.ps1', 'Private/Get-TagValue.ps1', 'Private/Import-AzLocalFleetState.ps1', 'Private/Install-AzGraphExtension.ps1', 'Private/Invoke-AzCliJson.ps1', 'Private/Invoke-AzLocalSideloadedAutoReset.ps1', 'Private/Invoke-AzLocalSideloadedAutoResetForCluster.ps1', 'Private/Invoke-AzLocalItsmHttp.ps1', 'Private/Invoke-AzLocalServiceNowAdapter.ps1', 'Private/Invoke-AzResourceGraphQuery.ps1', 'Private/Invoke-AzRestJson.ps1', 'Private/Invoke-AzLocalUpdateApply.ps1', 'Private/Invoke-FleetJobsInParallel.ps1', 'Private/Invoke-FleetOpClusterAction.ps1', 'Private/Read-AzLocalApplyUpdatesYamlCrons.ps1', 'Private/Resolve-AzLocalItsmSecret.ps1', 'Private/Resolve-AzLocalUpdateRunDeepestError.ps1', 'Private/Resolve-SafeOutputPath.ps1', 'Private/Resolve-WildcardDate.ps1', 'Private/Resolve-WildcardDateRange.ps1', 'Private/Set-AzLocalClusterTagsMerge.ps1', 'Private/Test-AzCliAvailable.ps1', 'Private/Test-AzLocalAllowedUpdateVersionsString.ps1', 'Private/Test-AzLocalUpdateExclusion.ps1', 'Private/Test-AzLocalUpdateExcludedAllowed.ps1', 'Private/Test-AzLocalUpdateSideloadedAllowed.ps1', 'Private/Test-AzLocalUpdateVersionInProgressMatch.ps1', 'Private/Test-AzLocalUpdateWindow.ps1', 'Private/Test-ExportPathWritable.ps1', 'Private/Write-Log.ps1', 'Private/Write-UpdateCsvLog.ps1', 'Private/Write-Utf8NoBomFile.ps1', # Pipeline host abstraction (v0.8.2) - foundations for the upcoming executable-YAML refactor 'Private/Get-AzLocalPipelineHost.ps1', 'Private/Set-AzLocalPipelineOutput.ps1', 'Private/Add-AzLocalPipelineStepSummary.ps1', 'Private/Write-AzLocalPipelineNotice.ps1', 'Private/Write-AzLocalPipelineWarning.ps1', # Public exported functions 'Public/Connect-AzLocalServicePrincipal.ps1', 'Public/Copy-AzLocalItsmSample.ps1', 'Public/Copy-AzLocalPipelineExample.ps1', 'Public/Export-AzLocalFleetState.ps1', 'Public/Get-AzLocalApplyUpdatesScheduleConfig.ps1', 'Public/Get-AzLocalApplyUpdatesScheduleNextFirings.ps1', 'Public/Get-AzLocalAvailableUpdates.ps1', 'Public/Get-AzLocalClusterInfo.ps1', 'Public/Get-AzLocalClusterInventory.ps1', 'Public/Get-AzLocalClusterUpdateReadiness.ps1', 'Public/Get-AzLocalFleetProgress.ps1', 'Public/Get-AzLocalFleetStatusData.ps1', 'Public/Get-AzLocalFleetHealthFailures.ps1', 'Public/Get-AzLocalFleetHealthOverview.ps1', 'Public/Get-AzLocalItsmConfig.ps1', 'Public/Get-AzLocalLatestSolutionVersion.ps1', 'Public/Get-AzLocalUpdateRunFailures.ps1', 'Public/Get-AzLocalUpdateRuns.ps1', 'Public/Get-AzLocalUpdateSummary.ps1', 'Public/Invoke-AzLocalFleetOperation.ps1', 'Public/New-AzLocalApplyUpdatesScheduleConfig.ps1', 'Public/New-AzLocalFleetStatusHtmlReport.ps1', 'Public/New-AzLocalIncident.ps1', 'Public/Reset-AzLocalSideloadedTag.ps1', 'Public/Resolve-AzLocalCurrentUpdateRing.ps1', 'Public/Resume-AzLocalFleetUpdate.ps1', 'Public/Set-AzLocalClusterUpdateRingTag.ps1', 'Public/Start-AzLocalClusterUpdate.ps1', 'Public/Stop-AzLocalFleetUpdate.ps1', 'Public/Test-AzLocalApplyUpdatesScheduleCoverage.ps1', 'Public/Test-AzLocalClusterHealth.ps1', 'Public/Test-AzLocalFleetHealthGate.ps1', 'Public/Test-AzLocalItsmConnection.ps1', 'Public/Test-AzLocalUpdateScheduleAllowed.ps1', 'Public/Update-AzLocalApplyUpdatesScheduleConfig.ps1', 'Public/Update-AzLocalPipelineExample.ps1', 'Public/Get-AzLocalFleetConnectivityStatus.ps1', 'Public/New-AzLocalFleetConnectivityStatusSummary.ps1' ) FunctionsToExport = @( 'Connect-AzLocalServicePrincipal', 'Start-AzLocalClusterUpdate', 'Get-AzLocalClusterUpdateReadiness', 'Get-AzLocalClusterInventory', 'Get-AzLocalClusterInfo', 'Get-AzLocalUpdateSummary', 'Get-AzLocalAvailableUpdates', 'Get-AzLocalUpdateRuns', 'Set-AzLocalClusterUpdateRingTag', # Fleet-Scale Operations (v0.5.6) 'Invoke-AzLocalFleetOperation', 'Get-AzLocalFleetProgress', 'Test-AzLocalFleetHealthGate', 'Export-AzLocalFleetState', 'Resume-AzLocalFleetUpdate', 'Stop-AzLocalFleetUpdate', # Pre-Update Health Validation (v0.6.1) 'Test-AzLocalClusterHealth', # Fleet Status Data Collection & Reporting (v0.6.4) 'Get-AzLocalFleetStatusData', 'New-AzLocalFleetStatusHtmlReport', # Update Schedule Tag Helpers (v0.6.4) 'Test-AzLocalUpdateScheduleAllowed', # Sideloaded Payload Workflow (v0.7.1) 'Reset-AzLocalSideloadedTag', # ITSM Connector Phase 1 (v0.7.4) 'Get-AzLocalItsmConfig', 'Test-AzLocalItsmConnection', 'New-AzLocalIncident', # Pipeline-Examples Convenience (v0.7.4 / Update added v0.7.68) 'Copy-AzLocalPipelineExample', 'Update-AzLocalPipelineExample', # ITSM Sample Convenience (v0.7.50) 'Copy-AzLocalItsmSample', # Fleet Health Failures (v0.7.65) - 24-hour system health-check failures across the fleet 'Get-AzLocalFleetHealthFailures', # Apply-Updates Schedule Coverage Advisor (v0.7.65) - compares apply-updates YAML cron(s) to UpdateStartWindow tags 'Test-AzLocalApplyUpdatesScheduleCoverage', # Update Run Failures (v0.7.68) - ARG-only deep-error extraction (9 levels deep) for fleet-scale verbose error information 'Get-AzLocalUpdateRunFailures', # Ring-Aware Apply-Updates Schedule (v0.7.69) - human-readable schedule file + cycle-based resolver 'Get-AzLocalApplyUpdatesScheduleConfig', 'Resolve-AzLocalCurrentUpdateRing', 'Get-AzLocalApplyUpdatesScheduleNextFirings', 'New-AzLocalApplyUpdatesScheduleConfig', 'Update-AzLocalApplyUpdatesScheduleConfig', # Fleet Health Overview (v0.7.70) - one row per cluster, ARG-first projection of cluster + updateSummaries (fleet-scale) 'Get-AzLocalFleetHealthOverview', # Latest Released Solution Version (v0.7.70) - public manifest probe (aka.ms/AzureEdgeUpdates) that anchors the rolling YYMM support window 'Get-AzLocalLatestSolutionVersion', # Fleet Connectivity Status (v0.7.79) - 4-scope connectivity audit: cluster, Arc agent, physical NIC, ARB 'Get-AzLocalFleetConnectivityStatus', # Fleet Connectivity Status Summary Renderer (v0.7.87) - markdown step-summary builder used by Step.4 GH+ADO pipelines 'New-AzLocalFleetConnectivityStatusSummary' ) # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() # Variables to export from this module VariablesToExport = @() # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. AliasesToExport = @() # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. PrivateData = @{ PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. Tags = @('Azure', 'AzureLocal', 'AzureStackHCI', 'Updates', 'UpdateManager', 'HCI', 'Automation', 'CICD', 'Pipeline', 'ServiceNow', 'ITSM', 'Incident') # A URL to the license for this module. LicenseUri = 'https://github.com/NeilBird/Azure-Local/blob/main/LICENSE' # A URL to the main website for this project. ProjectUri = 'https://github.com/NeilBird/Azure-Local' # A URL to an icon representing this module. IconUri = '' # ReleaseNotes of this module ReleaseNotes = @' ## Version 0.8.4 - Step.3 advisor enhancements (NoWindowTag CSV remediation + Cycle calendar + Exclusion windows summary) + Step.6 per-cluster Step Summary + Node 24 opt-in + version banner on every install step + RBAC custom role renamed to `Azure Stack HCI Update Operator (custom)` Step.3 advisor enhancement release. No public API removed. One new optional parameter on `Test-AzLocalApplyUpdatesScheduleCoverage`: `-ClusterCsvPath <path>`. Two new informational sections on `-View Recommend` that render whenever `-SchedulePath` is supplied (Step.3 yml now passes it). All v0.8.3 behaviour preserved unchanged. - **Enhancement A - NoWindowTag CSV remediation (new `-ClusterCsvPath` parameter).** When the operator supplies the path to the source-controlled cluster inventory CSV (the file Step.2 consumes - default `config/ClusterUpdateRings.csv`), `-View Recommend` emits a new `## Action required - NoWindowTag remediation` section. For each cluster that has an `UpdateRing` tag but no `UpdateStartWindow` tag, the advisor proposes a **peer-derived `UpdateStartWindow` value** (mode of peers' values in the same ring) plus a source label explaining the choice (unanimous / majority / sole peer / no peers). It then looks up the cluster in the CSV - **case-insensitive on `ResourceId` first, falling back to `ClusterName + ResourceGroup`** for older CSVs that pre-date the `ResourceId` column - and tells the operator either to edit the `UpdateStartWindow` cell on that row, or (if the cluster is absent from the CSV) to re-run Step.1 to regenerate the inventory artifact and replace the source-controlled CSV with it. ARG query also projects `UpdateExclusionsWindow` so the new Enhancement C section has data to render. - **Enhancement B - Cycle calendar (informational, auto-emits when `-SchedulePath` is supplied).** A new `## Cycle calendar - next N day(s)` table renders one row per UTC day for one full cycle (`CycleWeeks * 7` days starting today). Each row shows Date, Day-of-week, CycleWeek (`X of N`, with `(cycle wraps)` annotation on the wrap row), Eligible rings (UNION of all matching schedule rows), and effective `AllowedUpdateVersions` (or `_(no constraint)_`). Re-uses `Resolve-AzLocalCurrentUpdateRing` per-day so cycle-week, UNION, and allow-list math is identical to runtime - no duplicate ISO-8601 / week-arithmetic logic to drift. Lets operators verify ring coverage matches policy and spot dead days where no ring is eligible. - **Enhancement C - Configured exclusion windows summary (informational, auto-emits when at least one cluster has a non-empty `UpdateExclusionsWindow` tag).** A new `## Configured exclusion windows (UpdateExclusionsWindow tag)` section groups tagged clusters by `(UpdateRing, UpdateExclusionsWindow)` and renders a rollup table (cluster count + first 10 cluster names + `+N more`). Plus a per-ring breakdown of clusters that have NO `UpdateExclusionsWindow` tag (so operators can spot drift where some clusters in a ring have a blackout configured and others do not). - **Step.3 GH + ADO yml: new `cluster_csv_path` / `clusterCsvPath` input** (default `config/ClusterUpdateRings.csv`). Validates the file exists at job time - missing file skips Enhancement A quietly (vs throwing) so repos that don't version-control a cluster CSV yet keep getting the legacy advisor output. Both yml templates now also pass `-SchedulePath` to the `-View Recommend` invocation so Enhancements B+C render in the Step Summary. - **Pester suite updates**: drift-sync test bumped to `'0.8.4'`; new It blocks for CSV-lookup paths, peer-derivation modes, cycle-calendar math + cycle-wrap rendering + UNION rows, and exclusion-windows rollup grouping. - **Step.6 Enhancement D - per-cluster Step Summary in `apply-updates` (GH + ADO).** `apply-updates` step persists `apply-results.json`; Summary renders new `### Cluster Actions` (icon + Status + UpdateName + Duration + Message per cluster handed to apply) + `### Clusters Skipped at Readiness Gate` (reads `readiness-report.csv`, capped at 100 rows). Eliminates JUnit-artifact downloads to identify per-cluster outcomes. - **Node.js 24 opt-in across all 10 GH yml.** `FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true` at workflow level, ahead of GitHub's platform-wide cutover. - **Version banner appended to every install step** - one banner per yml across all 20 bundled `Step.{0..9}.yml` templates (Step.6 ADO has 2 install steps but the second deliberately skips upload to avoid duplicating the banner): `_Pipeline YAML v<g> | Module v<i> installed (<pin>) | PSGallery latest <l> | <verdict>_` rendered in the Summary view, eliminating "is my YAML / module out of date?" investigation lag. - **RBAC custom role renamed: `Azure Stack HCI Update Operator` -> `Azure Stack HCI Update Operator (custom)`.** Bundled JSON `Name` updated; `Actions[]` byte-identical to v0.8.3. Existing tenants: `az role definition update --role-definition ./azlocal-update-management-custom-role.json` is an in-place rename - GUID + every existing role assignment preserved; zero pipeline downtime. Reference by `roleDefinitionId` (GUID) in automation, not display name. - **All 20 bundled `Step.{0..9}.yml` templates** bump `GENERATED_AGAINST_MODULE_VERSION` from `'0.8.3'` to `'0.8.4'`. ## Version 0.8.3 - Test-AzLocalApplyUpdatesScheduleCoverage Step.3 advisor accuracy + readability fixes: Recommend now diff-prunes against `-PipelineYamlPath`, Step.3 yml `pipeline_path` REQUIRED, Allow-list heading reframed, closing-fence typo fixed ## Version 0.8.2 - Test-AzLocalApplyUpdatesScheduleCoverage operator-UX release: -View Recommend snippet embeds `# All cron times below are UTC` comment + `Indent tip` blockquote; -View Audit `NoWindowTag` row now names affected clusters grouped by `UpdateRing` + sorts AFTER Covered; Step.3 GH/ADO Allow-list section trimmed; five new internal pipeline-host helpers (Get/Set/Add/Write-AzLocalPipeline*) laid down as foundations for the upcoming executable-YAML refactor ## Version 0.8.1 - Test-AzLocalApplyUpdatesScheduleCoverage -View Recommend GH snippet emits ONLY the `schedule:` block (no `on:` / `workflow_dispatch:` lines) so it can be pasted straight into Step.6_apply-updates.yml without producing a duplicate-key YAML error ## Version 0.8.0 - Step.7 form-default regressions fixed (criticalElapsedDays 7->3, updateRing Wave1->empty) + Pii-Guard.Tests.ps1 (repo-hygiene guard) + Publish-Module.ps1 excludes maintainer-only RELEASE-PROCESS.md ## Version 0.7.99 - Property/Summary renames (AvailableUpdates -> AllAvailableUpdates, AvailableUpdatesCount -> ActionableUpdatesCount, Ready/NotReady Summary -> ReadyForUpdate/UpToDate/NotReadyForUpdate) + Step.7 CRITICAL elapsed-days 7->3 + artifact zip names prefixed with step.X- For full v0.7.x and v0.8.x release notes see: https://github.com/NeilBird/Azure-Local/blob/main/AzLocal.UpdateManagement/CHANGELOG.md '@ # Prerelease string of this module # Prerelease = '' # Flag to indicate whether the module requires explicit user acceptance for install/update/save # RequireLicenseAcceptance = $false # External dependent modules of this module # ExternalModuleDependencies = @() } } # HelpInfo URI of this module # HelpInfoURI = '' # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. # DefaultCommandPrefix = '' } |