diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/apply-updates-schedule-audit.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/apply-updates-schedule-audit.yml
index df65b935..9b2f479b 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/apply-updates-schedule-audit.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/apply-updates-schedule-audit.yml
@@ -87,7 +87,7 @@ parameters:
default: false
variables:
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
REQUIRED_MODULE_VERSION: '${{ parameters.moduleVersion }}'
reportsPath: '$(Build.ArtifactStagingDirectory)/reports'
# v0.8.7 sideload advisor defaults. Override at the pipeline / variable-group
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/apply-updates.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/apply-updates.yml
index 2f7e4767..6f1c597d 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/apply-updates.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/apply-updates.yml
@@ -129,7 +129,7 @@ variables:
# log if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- name: GENERATED_AGAINST_MODULE_VERSION
- value: '0.8.82'
+ value: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): queue-time parameter > pipeline variable
# 'REQUIRED_MODULE_VERSION' overridden at queue time > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/assess-update-readiness.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/assess-update-readiness.yml
index ba872542..e07ec3d9 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/assess-update-readiness.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/assess-update-readiness.yml
@@ -70,7 +70,7 @@ variables:
# the version actually installed and to the latest on PSGallery, and emits a warning
# log if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): queue-time parameter > pipeline variable
# 'REQUIRED_MODULE_VERSION' overridden at queue time > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/authentication-test.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/authentication-test.yml
index f1d3f49f..e82b660f 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/authentication-test.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/authentication-test.yml
@@ -60,7 +60,7 @@ variables:
# log if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- name: GENERATED_AGAINST_MODULE_VERSION
- value: '0.8.82'
+ value: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): queue-time parameter > pipeline variable
# 'REQUIRED_MODULE_VERSION' overridden at queue time > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-connectivity-status.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-connectivity-status.yml
index e704ec57..f1091a90 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-connectivity-status.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-connectivity-status.yml
@@ -110,7 +110,7 @@ variables:
# the version actually installed and to the latest on PSGallery, and emits a warning
# log if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): queue-time parameter > pipeline variable
# 'REQUIRED_MODULE_VERSION' overridden at queue time > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-health-status.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-health-status.yml
index 18d3d941..fcf13284 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-health-status.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-health-status.yml
@@ -105,7 +105,7 @@ variables:
# the version actually installed and to the latest on PSGallery, and emits a warning
# log if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): queue-time parameter > pipeline variable
# 'REQUIRED_MODULE_VERSION' overridden at queue time > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-update-status.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-update-status.yml
index 56eecbbf..f2e248fd 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-update-status.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/fleet-update-status.yml
@@ -93,7 +93,7 @@ variables:
# the version actually installed and to the latest on PSGallery, and emits a warning
# log if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): queue-time parameter > pipeline variable
# 'REQUIRED_MODULE_VERSION' overridden at queue time > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/inventory-clusters.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/inventory-clusters.yml
index f6a14518..a0ba88ff 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/inventory-clusters.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/inventory-clusters.yml
@@ -43,7 +43,7 @@ variables:
# log if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- name: GENERATED_AGAINST_MODULE_VERSION
- value: '0.8.82'
+ value: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): queue-time parameter > pipeline variable
# 'REQUIRED_MODULE_VERSION' overridden at queue time > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/manage-updatering-tags.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/manage-updatering-tags.yml
index 36c6cf6a..74ddd2fe 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/manage-updatering-tags.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/manage-updatering-tags.yml
@@ -46,7 +46,7 @@ variables:
# log if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- name: GENERATED_AGAINST_MODULE_VERSION
- value: '0.8.82'
+ value: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): queue-time parameter > pipeline variable
# 'REQUIRED_MODULE_VERSION' overridden at queue time > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/monitor-updates.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/monitor-updates.yml
index 1afbd133..f0944baa 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/monitor-updates.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/monitor-updates.yml
@@ -84,7 +84,7 @@ parameters:
default: ''
variables:
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
REQUIRED_MODULE_VERSION: '${{ parameters.moduleVersion }}'
reportsPath: '$(Build.ArtifactStagingDirectory)/reports'
@@ -137,9 +137,10 @@ stages:
# failed tables) has been condensed into the Public cmdlet
# Export-AzLocalUpdateRunMonitorReport. The cmdlet writes
# $(reportsPath)/update-monitor.csv + .xml, uploads the markdown
- # summary via ##vso[task.uploadsummary], and sets the six pipeline
+ # summary via ##vso[task.uploadsummary], and sets the seven pipeline
# variables (in_flight, long_running, long_running_step,
- # step_errored, recent_failures, unresolved_failures).
+ # step_errored, recent_failures, unresolved_failures,
+ # attempts_without_run).
inputs:
azureSubscription: 'AzureLocal-ServiceConnection' # Update with your service connection name
scriptType: 'pscore'
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/sideload-updates.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/sideload-updates.yml
index 50757f39..4467f025 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/sideload-updates.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/azure-devops/sideload-updates.yml
@@ -79,7 +79,7 @@ variables:
# the version actually installed and to the latest on PSGallery, and emits a warning
# log if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): queue-time parameter > pipeline variable
# 'REQUIRED_MODULE_VERSION' overridden at queue time > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/apply-updates-schedule-audit.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/apply-updates-schedule-audit.yml
index 0a4dec12..627f1c30 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/apply-updates-schedule-audit.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/apply-updates-schedule-audit.yml
@@ -96,7 +96,7 @@ env:
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
REQUIRED_MODULE_VERSION: ${{ github.event.inputs.module_version || vars.REQUIRED_MODULE_VERSION || '' }}
# v0.8.4 - opt this workflow into Node.js 24 for all JavaScript actions
# (actions/checkout, actions/download-artifact, actions/upload-artifact,
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/apply-updates.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/apply-updates.yml
index 70ee333a..26e0e637 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/apply-updates.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/apply-updates.yml
@@ -148,7 +148,7 @@ env:
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): manual workflow_dispatch input >
# repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/assess-update-readiness.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/assess-update-readiness.yml
index e4c5c94e..5e5854ee 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/assess-update-readiness.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/assess-update-readiness.yml
@@ -72,7 +72,7 @@ env:
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): manual workflow_dispatch input >
# repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/authentication-test.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/authentication-test.yml
index 03d5f4d9..7337e221 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/authentication-test.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/authentication-test.yml
@@ -79,7 +79,7 @@ env:
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): manual workflow_dispatch input >
# repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-connectivity-status.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-connectivity-status.yml
index 3cbfae1a..9bd1e317 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-connectivity-status.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-connectivity-status.yml
@@ -116,7 +116,7 @@ env:
# PSGallery, and emits a ::notice annotation if the YAML appears stale -
# prompting you to refresh via Copy-AzLocalPipelineExample -Update. See
# Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install
# the latest, the default "fix-forward" behaviour): manual workflow_dispatch
# input > repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-health-status.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-health-status.yml
index 0603bbb0..7b66bd9f 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-health-status.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-health-status.yml
@@ -116,7 +116,7 @@ env:
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): manual workflow_dispatch input >
# repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-update-status.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-update-status.yml
index 461004f2..5e822334 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-update-status.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/fleet-update-status.yml
@@ -105,7 +105,7 @@ env:
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): manual workflow_dispatch input >
# repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/inventory-clusters.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/inventory-clusters.yml
index a3d472dd..e06a1bf2 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/inventory-clusters.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/inventory-clusters.yml
@@ -48,7 +48,7 @@ env:
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): manual workflow_dispatch input >
# repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/manage-updatering-tags.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/manage-updatering-tags.yml
index 381cb051..b74df924 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/manage-updatering-tags.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/manage-updatering-tags.yml
@@ -65,7 +65,7 @@ env:
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): manual workflow_dispatch input >
# repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/monitor-updates.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/monitor-updates.yml
index f6ebbfee..aff8f36c 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/monitor-updates.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/monitor-updates.yml
@@ -86,7 +86,7 @@ env:
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): manual workflow_dispatch input >
# repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
@@ -121,6 +121,12 @@ jobs:
step_errored: ${{ steps.snapshot.outputs.step_errored }}
recent_failures: ${{ steps.snapshot.outputs.recent_failures }}
unresolved_failures: ${{ steps.snapshot.outputs.unresolved_failures }}
+ # v0.8.83: expose the Step.08 UpdateLastAttempt-reconciliation count
+ # (clusters whose UpdateLastAttempt tag points at an attempt with no
+ # observable updateRun resource - typically a URP package-internal
+ # pre-install health-check failure). Wired so downstream pipeline
+ # jobs can gate on attempts_without_run > 0.
+ attempts_without_run: ${{ steps.snapshot.outputs.attempts_without_run }}
steps:
- name: Checkout repository
diff --git a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/sideload-updates.yml b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/sideload-updates.yml
index 238cae2a..3ffc7cf6 100644
--- a/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/sideload-updates.yml
+++ b/AzLocal.UpdateManagement/Automation-Pipeline-Examples/github-actions/sideload-updates.yml
@@ -83,7 +83,7 @@ env:
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- GENERATED_AGAINST_MODULE_VERSION: '0.8.82'
+ GENERATED_AGAINST_MODULE_VERSION: '0.8.83'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): manual workflow_dispatch input >
# repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
diff --git a/AzLocal.UpdateManagement/AzLocal.UpdateManagement.psd1 b/AzLocal.UpdateManagement/AzLocal.UpdateManagement.psd1
index 32f05894..3b8dd563 100644
--- a/AzLocal.UpdateManagement/AzLocal.UpdateManagement.psd1
+++ b/AzLocal.UpdateManagement/AzLocal.UpdateManagement.psd1
@@ -3,7 +3,7 @@
RootModule = 'AzLocal.UpdateManagement.psm1'
# Version number of this module.
- ModuleVersion = '0.8.82'
+ ModuleVersion = '0.8.83'
# Supported PSEditions
CompatiblePSEditions = @('Desktop', 'Core')
@@ -317,6 +317,8 @@
# ReleaseNotes of this module
ReleaseNotes = @'
+## Version 0.8.83 - Patch: fix-forward for v0.8.82 Item-5. The Step.08 `UpdateLastAttempt` reconciliation in `Export-AzLocalUpdateRunMonitorReport` reads `$inv.tags` from `Get-AzLocalClusterInventory`, but the v0.8.82 inventory projection did not carry the raw ARM `tags` bag - so the "Recent update attempts with no observable updateRun" section was silently always empty in production. v0.8.83 surfaces the raw `tags` bag on every inventory row (in-memory only; the CSV / JSON export keeps its explicit `$selectColumns` whitelist - new regression test asserts both). Also wires `attempts_without_run` into the GitHub Actions `monitor-updates.yml` `jobs.outputs:` block (ADO `Set-AzLocalPipelineOutput` auto-publishes so only an ADO docstring refresh needed), and corrects the `Export-AzLocalUpdateRunMonitorReport` "6 step outputs" docstring to "7 step outputs". No public API change. Export count unchanged (still 60). All bundled pipeline templates bump `GENERATED_AGAINST_MODULE_VERSION` from `'0.8.82'` to `'0.8.83'`.
+
## Version 0.8.82 - Patch: four Step-summary UX polish fixes from v0.8.81 manual pipeline-run review. (1) Step.05 Summary counts table no longer duplicates labels: each row reused the shared `Get-AzLocalStatusIconMap` cell (which already includes its own label) AND appended a duplicate trailing label, producing `Ready for Update Ready for update` / `Up to Date Up to date` / `Action Required Not ready for update` / `Health Failure Clusters with Critical health failures`. Fixed by emitting the icon-map cell unmodified; the HealthFailure row keeps `(Clusters with Critical health failures)` in parentheses since it counts something different from the readiness cascade. (2) Step.05 All clusters detail table now sorts by Status priority first (`InProgress` -> `HealthFailure` -> `UpdateFailed` -> `ActionRequired` -> `SbeBlocked` -> `NeedsInvestigation` -> `ReadyForUpdate` -> `UpToDate`), then UpdateRing + ClusterName. In-flight + remediation rows surface at the top; Up-to-Date drops to the bottom. (3) Step.05 Not-Ready clusters (review first) table no longer leaves the `Blocking reasons` column as `-` for rows blocked by `UpdateFailed` / `NeedsAttention` / `InProgress` / Warning-only HealthFailure / SbeBlocked - the renderer now derives an actionable token from the Status bucket when the upstream `BlockingReasons` is empty (e.g. `UpdateInProgress (run in-flight)`, `UpdateState=NeedsAttention`, `PrerequisiteRequired (SBE update first)`, `HealthState=Failure (no Critical findings; review Warning findings)`), with `; HealthState=Warning` appended where relevant. (4) Step.10 Detailed Results Description column inline-vs-collapse threshold bumped from 120 to 280 characters, so short single-sentence descriptions render inline and only long multi-line descriptions collapse behind `view
... `. The previous 120-char cutoff put roughly half the rows inline and half collapsed on the same table, which looked broken. No public API or export-count change (still 60). All bundled pipeline templates bump `GENERATED_AGAINST_MODULE_VERSION` from `'0.8.81'` to `'0.8.82'`.
## Version 0.8.81 - Step summary polish across Steps 05-10. Step.10 fixes the KPI bug where Healthy + Unhealthy did not sum to Total (splits into Cluster Counts + Failing Checks Breakdown tables, adds `OtherClusters` step output; Detailed Results gains Title, raw FailureName and collapsible Description columns surfacing drive/volume detail e.g. file paths from `...FileSystem.Corruption.Correctable`). Steps 05-09 adopt three shared private helpers: `Get-AzLocalStatusIconMap` (host-aware GitHub Unicode vs Azure DevOps shortcodes), `Get-AzLocalClusterPortalLink` (portal deep-link wrapper) and `Get-AzLocalCtrlClickTip` (single-source Ctrl-click banner). Fixes literal shortcode text (`:white_check_mark:` etc.) rendering on Azure DevOps step summaries in Step.08 monitor + Step.09 fleet-update-status. No public API change (still 60 exports). All bundled pipeline templates bump `GENERATED_AGAINST_MODULE_VERSION` from `'0.8.80'` to `'0.8.81'`.
@@ -331,7 +333,7 @@
- **TESTS**: parameter-presence regressions for both new switches; new `v0.8.79 Step.7 break-glass` YAML smoke-test context with 8 assertions covering the GHA / ADO input declarations, anti-injection guards, and a sweep of `Resolve-AzLocalPipelineUpdateRing` / `New-AzLocalApplyUpdatesScheduleConfig` / `Get-AzLocalApplyUpdatesScheduleAudit` confirming the override is NOT referenced from any schedule-config code path.
- **All bundled pipeline templates** bump `GENERATED_AGAINST_MODULE_VERSION` from `'0.8.78'` to `'0.8.79'`.
-## Version 0.8.78 - Patch: pipeline-summary UX polish. (1) JUnit re-classification - `ScheduleBlocked` / `SideloadedBlocked` / `ExcludedByTag` are designed gate-respect outcomes, now render as `` so `dorny/test-reporter` no longer flips Step.07 RED (`HealthCheckBlocked` stays ``). (2) `Add-AzLocalApplyUpdatesStepSummary` gains optional `-UpToDateCount` / `-NotReadyCount` for full ring breakdown in the Readiness KPI table (both `apply-updates.yml` templates wire the upstream `readiness.UpToDateCount` / `readiness.NotReadyCount` outputs through). (3) `actions/download-artifact@v6` -> `@v7` in `apply-updates.yml` (GHA) silences the Node.js 20 deprecation warning. No public API or export-count change (still 60). All bundled pipeline templates bump `GENERATED_AGAINST_MODULE_VERSION` from `'0.8.77'` to `'0.8.78'`. See CHANGELOG.md / docs/release-history.md for the full v0.8.78 entry.
+## Version 0.8.78 - Patch: pipeline-summary UX polish (`ScheduleBlocked` / `SideloadedBlocked` / `ExcludedByTag` now JUnit ``; `Add-AzLocalApplyUpdatesStepSummary` gains `-UpToDateCount` / `-NotReadyCount`; `actions/download-artifact@v6` -> `@v7`). See CHANGELOG.md / docs/release-history.md.
For full v0.7.x and v0.8.x release notes see:
https://github.com/NeilBird/Azure-Local/blob/main/AzLocal.UpdateManagement/CHANGELOG.md
diff --git a/AzLocal.UpdateManagement/AzLocal.UpdateManagement.psm1 b/AzLocal.UpdateManagement/AzLocal.UpdateManagement.psm1
index fa0ce749..90c6ac5e 100644
--- a/AzLocal.UpdateManagement/AzLocal.UpdateManagement.psm1
+++ b/AzLocal.UpdateManagement/AzLocal.UpdateManagement.psm1
@@ -151,7 +151,7 @@ Set-StrictMode -Version 1.0
# bumps to one but not the other are caught before release. Two consumers:
# - Start-AzLocalClusterUpdate emits this in the run log header.
# - Get-AzLocalFleetStatusData stamps it into exported fleet-state JSON.
-$script:ModuleVersion = '0.8.82'
+$script:ModuleVersion = '0.8.83'
$script:DefaultApiVersion = '2025-10-01'
$script:DefaultLogFolder = Join-Path -Path $env:ProgramData -ChildPath 'AzLocal.UpdateManagement'
diff --git a/AzLocal.UpdateManagement/CHANGELOG.md b/AzLocal.UpdateManagement/CHANGELOG.md
index 76904d67..4c566ba1 100644
--- a/AzLocal.UpdateManagement/CHANGELOG.md
+++ b/AzLocal.UpdateManagement/CHANGELOG.md
@@ -5,6 +5,54 @@ All notable changes to the AzLocal.UpdateManagement module (renamed from AzStack
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [0.8.83] - 2026-06-15
+
+Patch release. Fix-forward for v0.8.82 Item-5: the new Step.08 `UpdateLastAttempt`
+reconciliation pass reads `$inv.tags` from `Get-AzLocalClusterInventory`, but the
+v0.8.82 inventory projection did not carry the raw ARM `tags` bag. As a result the
+"Recent update attempts with no observable updateRun" section was always empty in
+production - the reconciliation found zero attempt gaps regardless of fleet
+state. v0.8.83 surfaces the raw `tags` bag on every inventory row (in-memory only;
+the on-disk CSV / JSON export keeps its explicit `$selectColumns` whitelist so
+artefacts continue to omit the raw bag). Also fixes the GH Actions
+`monitor-updates.yml` `jobs.outputs:` block to expose `attempts_without_run` to
+downstream jobs (the cmdlet was already emitting it in v0.8.82 - only the YAML
+wiring was missing), and a docstring drift in `Export-AzLocalUpdateRunMonitorReport`
+("6 step outputs" -> "7 step outputs"). No public API change. Export count
+unchanged (still 60).
+
+### Fixed
+
+- **`Get-AzLocalClusterInventory` PassThru output now carries the raw ARM `tags`
+ bag** on every cluster row (`$itemProps['tags'] = $cluster.tags`). v0.8.82's
+ Step.08 `UpdateLastAttempt` reconciliation pass in
+ `Export-AzLocalUpdateRunMonitorReport` reads `$inv.tags` via
+ `PSObject.Properties['tags']` to find the audit tag - without this fix, the
+ reconciliation silently always reported zero gaps. The on-disk CSV / JSON
+ export remains unchanged: the existing `$selectColumns` whitelist explicitly
+ names the columns to persist and does NOT include `tags`, so artefacts do
+ not leak the raw bag. New regression test
+ (`v0.8.83: Get-AzLocalClusterInventory preserves raw ARM tag bag on PassThru`)
+ asserts the in-memory property is present AND that `$selectColumns` does not
+ surface `tags`.
+- **GitHub Actions `monitor-updates.yml` `jobs.outputs:` block** now exposes the
+ `attempts_without_run` step output (`${{ steps.snapshot.outputs.attempts_without_run }}`)
+ so downstream jobs can gate on `attempts_without_run > 0` (e.g. open a triage
+ issue when URP package-internal pre-install health-check failures are
+ detected). The cmdlet was already emitting the step output in v0.8.82; only
+ the pipeline-level `jobs.outputs:` wiring was missing. Azure DevOps requires
+ no change here - `Set-AzLocalPipelineOutput` auto-publishes the step variable
+ via `##vso[task.setvariable variable=...;isOutput=true]`.
+- **`Export-AzLocalUpdateRunMonitorReport` cmdlet docstring drift**. The
+ comment-based help still said "Emits 6 step outputs" after v0.8.82 added the
+ seventh (`attempts_without_run`). Now reads "Emits 7 step outputs" with
+ `attempts_without_run` listed alongside the existing six.
+
+### Changed
+
+- `GENERATED_AGAINST_MODULE_VERSION` bumped from `'0.8.82'` to `'0.8.83'`
+ across all bundled GitHub Actions and Azure DevOps pipeline templates.
+
## [0.8.82] - 2026-06-15
Patch release. Step.05 + Step.10 step-summary UX polish from the v0.8.81 manual
diff --git a/AzLocal.UpdateManagement/Public/Export-AzLocalUpdateRunMonitorReport.ps1 b/AzLocal.UpdateManagement/Public/Export-AzLocalUpdateRunMonitorReport.ps1
index 18dbd982..7423e791 100644
--- a/AzLocal.UpdateManagement/Public/Export-AzLocalUpdateRunMonitorReport.ps1
+++ b/AzLocal.UpdateManagement/Public/Export-AzLocalUpdateRunMonitorReport.ps1
@@ -40,9 +40,9 @@ function Export-AzLocalUpdateRunMonitorReport {
threshold line + metric table + 'In-flight runs' table +
'Failed runs (unresolved)' table + action-required / healthy
footer) via `Add-AzLocalPipelineStepSummary`.
- 6. Emits 6 step outputs via `Set-AzLocalPipelineOutput`:
+ 6. Emits 7 step outputs via `Set-AzLocalPipelineOutput`:
in_flight, long_running, long_running_step, step_errored,
- recent_failures, unresolved_failures.
+ recent_failures, unresolved_failures, attempts_without_run.
Internal reuse (per the v0.8.5 thin-YAML consistency contract):
* `Get-AzLocalUpdateRuns` (with `-PassThru -SkipSideloadedReset`)
diff --git a/AzLocal.UpdateManagement/Public/Get-AzLocalClusterInventory.ps1 b/AzLocal.UpdateManagement/Public/Get-AzLocalClusterInventory.ps1
index 93ff24c3..ca0be149 100644
--- a/AzLocal.UpdateManagement/Public/Get-AzLocalClusterInventory.ps1
+++ b/AzLocal.UpdateManagement/Public/Get-AzLocalClusterInventory.ps1
@@ -336,6 +336,8 @@ function Get-AzLocalClusterInventory {
$itemProps['UpdateAuthAccountId'] = if ($authIdTagValue) { $authIdTagValue } else { "" }
}
$itemProps['ResourceId'] = $cluster.id
+ # Preserve raw ARM tag bag so downstream consumers can read tags this projection does not explicitly surface (CSV/JSON export below uses an explicit $selectColumns list so this field is excluded from on-disk artefacts).
+ $itemProps['tags'] = $cluster.tags
$inventoryItem = [PSCustomObject]$itemProps
$inventory += $inventoryItem
}
diff --git a/AzLocal.UpdateManagement/README.md b/AzLocal.UpdateManagement/README.md
index 27358057..71c707e6 100644
--- a/AzLocal.UpdateManagement/README.md
+++ b/AzLocal.UpdateManagement/README.md
@@ -2,7 +2,7 @@
> ⚠️ **Disclaimer**: This module is **NOT** a Microsoft supported service offering or product. It is provided as example code only, with no warranty or official support. Refer to the [MIT license](https://github.com/NeilBird/Azure-Local/blob/main/LICENSE) for further information.
-**Latest Version:** v0.8.82 - [Published in PowerShell Gallery](https://www.powershellgallery.com/packages/AzLocal.UpdateManagement/0.8.82)
+**Latest Version:** v0.8.83 - [Published in PowerShell Gallery](https://www.powershellgallery.com/packages/AzLocal.UpdateManagement/0.8.83)
> 📢 **Renamed in v0.7.3**: this module was previously published as `AzStackHci.ManageUpdates`. The new module name aligns with the Azure Local product name (_Microsoft retired the *Azure Stack HCI* brand in late 2024_). The module GUID is preserved across the rename. If you have the old name installed, run:
>
@@ -23,7 +23,7 @@ Azure Local REST API specification (includes update management endpoints): https
**This README (overview + most-recent release notes):**
- [Where to Start](#where-to-start)
-- [What's New in v0.8.82](#whats-new-in-v0882)
+- [What's New in v0.8.83](#whats-new-in-v0883)
- [Files](#files)
- [Prerequisites](#prerequisites)
- [RBAC Requirements](#rbac-requirements) (summary; full reference in [docs/rbac.md](docs/rbac.md))
@@ -86,33 +86,24 @@ If you are new to this module, work through these in order from a regular PowerS
> Most CI/CD pipelines in [Automation-Pipeline-Examples/](Automation-Pipeline-Examples/) are direct implementations of one of these workflows. Start there if you want a copy-pasteable end-to-end pipeline.
-## What's New in v0.8.82
+## What's New in v0.8.83
-**Patch release. Step.05 + Step.10 step-summary UX polish from the v0.8.81 manual pipeline-run review.** Four small fixes; no public API or export-count change (still 60 exports).
+**Patch release. Fix-forward for v0.8.82 Item-5.** The new Step.08 `UpdateLastAttempt` reconciliation pass in `Export-AzLocalUpdateRunMonitorReport` reads `$inv.tags` from `Get-AzLocalClusterInventory`, but the v0.8.82 inventory projection did not carry the raw ARM `tags` bag - so the "Recent update attempts with no observable updateRun" section was silently always empty in production regardless of fleet state. v0.8.83 surfaces the raw `tags` bag on every inventory row (in-memory only; the on-disk CSV / JSON export keeps its explicit `$selectColumns` whitelist so artefacts continue to omit the raw bag). Also fixes the GitHub Actions `monitor-updates.yml` `jobs.outputs:` block to expose `attempts_without_run` to downstream jobs (the cmdlet was already emitting it in v0.8.82 - only the YAML wiring was missing), and a docstring drift in `Export-AzLocalUpdateRunMonitorReport` ("6 step outputs" -> "7 step outputs"). No public API change. Export count unchanged (still 60).
-### Step.05 cluster update readiness report
+### Fixes
-- **Summary counts table no longer duplicates labels.** Each row was reusing the shared `Get-AzLocalStatusIconMap` cell (which already includes its own label, e.g. `Ready for Update`) AND appending a duplicate trailing label, producing `Ready for Update Ready for update` / `Up to Date Up to date` / `Action Required Not ready for update` / `Health Failure Clusters with Critical health failures`. The icon-map cell is now emitted unmodified. The HealthFailure row keeps `(Clusters with Critical health failures)` in parentheses since it counts something different from the readiness cascade.
-- **All clusters detail table** now sorts by **Status priority** first (`InProgress` -> `HealthFailure` -> `UpdateFailed` -> `ActionRequired` -> `SbeBlocked` -> `NeedsInvestigation` -> `ReadyForUpdate` -> `UpToDate`), then `UpdateRing` + `ClusterName` as before. In-flight + remediation rows surface at the top of the table; Up-to-Date clusters drop to the bottom so operators see actionable items first.
-- **Not-Ready clusters (review first) table - Blocking reasons column** no longer shows `-` for rows blocked by `UpdateFailed` / `NeedsAttention` / `InProgress` / Warning-only `HealthFailure` / `SbeBlocked`. The upstream `Get-AzLocalClusterUpdateReadiness` only populates `BlockingReasons` for `CriticalHealthCheck` findings and abnormal cluster connectivity states (e.g. `NotConnectedRecently`). For every other Not-Ready category the column was left empty and rendered as `-`, forcing operators to cross-read the `Update state` + `Health` columns to infer the reason. The renderer now derives an actionable token from the Status bucket when `BlockingReasons` is empty:
- - `InProgress` -> `UpdateInProgress (run in-flight)`
- - `UpdateFailed` -> `UpdateState=` (e.g. `UpdateState=NeedsAttention`, `UpdateState=UpdateFailed`)
- - `ActionRequired` -> `UpdateState=PreparationFailed`
- - `HealthFailure` -> `HealthState=Failure (no Critical findings; review Warning findings)`
- - `SbeBlocked` -> `PrerequisiteRequired (SBE update first)`
- - `NeedsInvestigation` -> `NeedsInvestigation (no Update or Health signal)`
- - For any of the above, `; HealthState=Warning` is appended when the cluster's `HealthState` is `Warning` and the Status bucket is not already `HealthFailure`.
-
-### Step.10 fleet health status report
-
-- **Detailed Results - Description column** inline-vs-collapse threshold bumped from 120 to **280 characters**. Short single-sentence descriptions render inline and only long multi-line descriptions collapse behind `view
... `. The previous 120-char cutoff put roughly half the rows inline and half collapsed on the same table, which looked broken.
+- **`Get-AzLocalClusterInventory` PassThru output now carries the raw ARM `tags` bag** on every cluster row. v0.8.82's Step.08 reconciliation reads `$inv.tags` via `PSObject.Properties['tags']` to find the `UpdateLastAttempt` audit tag - without this fix, the reconciliation silently always reported zero gaps. The on-disk CSV / JSON export remains unchanged: the existing `$selectColumns` whitelist explicitly names the columns to persist and does NOT include `tags`, so artefacts do not leak the raw bag. New regression test asserts the in-memory property is present AND that the whitelist still excludes `tags`.
+- **GitHub Actions `monitor-updates.yml` `jobs.outputs:` block** now exposes the `attempts_without_run` step output (`${{ steps.snapshot.outputs.attempts_without_run }}`) so downstream jobs can gate on `attempts_without_run > 0` (e.g. open a triage issue when URP package-internal pre-install health-check failures are detected). Azure DevOps requires no change - `Set-AzLocalPipelineOutput` auto-publishes the step variable via `##vso[task.setvariable variable=...;isOutput=true]`; the ADO `monitor-updates.yml` comment-only update brings its docstring in line with the seven step outputs.
+- **`Export-AzLocalUpdateRunMonitorReport` cmdlet docstring drift** - now reads "Emits 7 step outputs" with `attempts_without_run` listed alongside the existing six (was still "6 step outputs" after v0.8.82 added the seventh).
### Notes
- **No new exports** (count unchanged at 60).
-- **`GENERATED_AGAINST_MODULE_VERSION`** bumped from `0.8.81` to `0.8.82` across all bundled pipeline templates.
+- **`GENERATED_AGAINST_MODULE_VERSION`** bumped from `0.8.82` to `0.8.83` across all bundled pipeline templates.
+
+> Previous release notes have moved into the [Release History](#release-history) appendix at the bottom of this document.
-See [CHANGELOG.md](CHANGELOG.md#0882---2026-06-15) for the full v0.8.82 entry. See [`What's New in v0.8.81`](docs/release-history.md#whats-new-in-v0881) in the Release History for the previous release.
+See [CHANGELOG.md](CHANGELOG.md#0883---2026-06-15) for the full v0.8.83 entry. See [`What's New in v0.8.82`](#whats-new-in-v0882) in the Release History for the previous release.
## Files
@@ -591,7 +582,11 @@ This code is provided as-is for educational and reference purposes.
The full What's-New history (v0.7.81 and earlier) has moved to [docs/release-history.md](docs/release-history.md).
-The most recent release notes for **v0.8.82** stay above under [`What's New in v0.8.82`](#whats-new-in-v0882).
+The most recent release notes for **v0.8.83** stay above under [`What's New in v0.8.83`](#whats-new-in-v0883).
+
+### What's New in v0.8.82
+
+**Patch release. Step.05 + Step.10 step-summary UX polish from the v0.8.81 manual pipeline-run review.** Four small fixes; no public API or export-count change (still 60 exports). Step.05 Summary counts table no longer duplicates row labels (each row was reusing the shared `Get-AzLocalStatusIconMap` cell - which already includes its own label - AND appending a duplicate trailing label). Step.05 All clusters detail table sorts by **Status priority** first (`InProgress` -> `HealthFailure` -> `UpdateFailed` -> `ActionRequired` -> `SbeBlocked` -> `NeedsInvestigation` -> `ReadyForUpdate` -> `UpToDate`), then `UpdateRing` + `ClusterName`; Up-to-Date drops to the bottom so operators see actionable items first. Step.05 Not-Ready clusters Blocking reasons column derives an actionable token from the Status bucket when upstream `BlockingReasons` is empty (`UpdateInProgress (run in-flight)`, `UpdateState=`, `PrerequisiteRequired (SBE update first)`, `NeedsInvestigation (no Update or Health signal)`, etc.; appends `; HealthState=Warning` when relevant). Step.10 Detailed Results Description column inline-vs-collapse threshold bumped from 120 to 280 characters in `Export-AzLocalFleetHealthStatusReport`. `GENERATED_AGAINST_MODULE_VERSION` bumped from `0.8.81` to `0.8.82` across all bundled pipeline templates. See [CHANGELOG.md](CHANGELOG.md#0882---2026-06-15) for the full v0.8.82 entry and [docs/release-history.md](docs/release-history.md#whats-new-in-v0882) for the archived entry.
### What's New in v0.8.81
diff --git a/AzLocal.UpdateManagement/Tests/AzLocal.UpdateManagement.Tests.ps1 b/AzLocal.UpdateManagement/Tests/AzLocal.UpdateManagement.Tests.ps1
index 07ecf512..9eaa3741 100644
--- a/AzLocal.UpdateManagement/Tests/AzLocal.UpdateManagement.Tests.ps1
+++ b/AzLocal.UpdateManagement/Tests/AzLocal.UpdateManagement.Tests.ps1
@@ -34,8 +34,8 @@ Describe 'Module: AzLocal.UpdateManagement' {
$script:ModuleInfo | Should -Not -BeNullOrEmpty
}
- It 'Should have version 0.8.82' {
- $script:ModuleInfo.Version | Should -Be '0.8.82'
+ It 'Should have version 0.8.83' {
+ $script:ModuleInfo.Version | Should -Be '0.8.83'
}
It 'Module version constants are in sync between .psm1 and .psd1' {
@@ -1214,6 +1214,76 @@ Describe 'Regression: Get-AzLocalClusterInventory ValidatePattern shadowing' {
}
}
+Describe 'v0.8.83: Get-AzLocalClusterInventory preserves raw ARM tag bag on PassThru' {
+ # v0.8.82 shipped Export-AzLocalUpdateRunMonitorReport's UpdateLastAttempt
+ # reconciliation pass, which reads $inv.tags via PSObject.Properties['tags']
+ # to find the audit tag. The Get-AzLocalClusterInventory projection in
+ # v0.8.82 didn't carry .tags, so the reconciliation was silently always-empty
+ # in production. v0.8.83 surfaces the raw .tags bag on every inventory row.
+ # In-memory only - the on-disk CSV/JSON export uses an explicit $selectColumns
+ # whitelist that excludes .tags, so this regression test also confirms that
+ # exported CSV does NOT contain a 'tags' column.
+
+ It 'PassThru output exposes raw ARM tags property on every cluster row' {
+ InModuleScope AzLocal.UpdateManagement {
+ function global:az {
+ param()
+ $global:LASTEXITCODE = 0
+ if ($args -contains 'show') {
+ return '{"id":"00000000-0000-0000-0000-000000000000","name":"sub"}'
+ }
+ return '{}'
+ }
+ Mock Test-AzCliAvailable { return $true }
+ Mock Install-AzGraphExtension { return $true }
+ Mock Invoke-AzResourceGraphQuery {
+ return @(
+ [PSCustomObject]@{
+ id = '/subscriptions/s/resourceGroups/r/providers/Microsoft.AzureStackHCI/clusters/c1'
+ name = 'c1'
+ resourceGroup = 'r'
+ subscriptionId = 's'
+ tags = @{
+ UpdateRing = 'Wave1'
+ UpdateLastAttempt = '2026-06-14T21:28:23Z;UpdateStarted;Solution12.2605.1003.210;Update initiated successfully'
+ UpdateWindow = 'Mon|18-22'
+ }
+ },
+ [PSCustomObject]@{
+ id = '/subscriptions/s/resourceGroups/r/providers/Microsoft.AzureStackHCI/clusters/c2'
+ name = 'c2'
+ resourceGroup = 'r'
+ subscriptionId = 's'
+ tags = $null
+ }
+ )
+ }
+
+ $result = Get-AzLocalClusterInventory -PassThru
+ $result | Should -HaveCount 2
+ $c1 = $result | Where-Object ClusterName -eq 'c1'
+ $c1.PSObject.Properties['tags'] | Should -Not -BeNullOrEmpty
+ $c1.tags | Should -Not -BeNullOrEmpty
+ $c1.tags['UpdateRing'] | Should -Be 'Wave1'
+ $c1.tags['UpdateLastAttempt'] | Should -Be '2026-06-14T21:28:23Z;UpdateStarted;Solution12.2605.1003.210;Update initiated successfully'
+ $c1.tags['UpdateWindow'] | Should -Be 'Mon|18-22'
+
+ # Untagged cluster still gets a .tags property; value is $null/empty bag.
+ $c2 = $result | Where-Object ClusterName -eq 'c2'
+ $c2.PSObject.Properties['tags'] | Should -Not -BeNullOrEmpty
+ }
+ }
+
+ It 'CSV/JSON export uses explicit $selectColumns whitelist that excludes the raw tags bag' {
+ $src = Get-Content -Raw -LiteralPath "$PSScriptRoot/../Public/Get-AzLocalClusterInventory.ps1"
+ # The whitelist must exist and must NOT name 'tags' (would leak the raw bag to artefacts).
+ $src | Should -Match '\$selectColumns\s*='
+ $whitelistMatch = [regex]::Match($src, '\$selectColumns\s*=\s*@\(([\s\S]*?)\)')
+ $whitelistMatch.Success | Should -BeTrue -Because 'Get-AzLocalClusterInventory must declare an explicit $selectColumns whitelist for CSV/JSON export'
+ $whitelistMatch.Groups[1].Value | Should -Not -Match "'tags'"
+ }
+}
+
Describe 'Function: Set-AzLocalClusterUpdateRingTag' {
Context 'Parameter Validation' {
diff --git a/AzLocal.UpdateManagement/docs/release-history.md b/AzLocal.UpdateManagement/docs/release-history.md
index 9c6a17c9..9edd9e6d 100644
--- a/AzLocal.UpdateManagement/docs/release-history.md
+++ b/AzLocal.UpdateManagement/docs/release-history.md
@@ -4,7 +4,15 @@
>
> **For older releases**, this is the canonical reference; the main README intentionally stays slim so the most recent block is easy to find.
>
-> **For v0.8.82 (the current release)**, see the main [README.md](../README.md#whats-new-in-v0882) `What's New in v0.8.82` section.
+> **For v0.8.83 (the current release)**, see the main [README.md](../README.md#whats-new-in-v0883) `What's New in v0.8.83` section.
+
+---
+
+### What's New in v0.8.83
+
+Patch release. Fix-forward for v0.8.82 Item-5. The new Step.08 `UpdateLastAttempt` reconciliation pass in `Export-AzLocalUpdateRunMonitorReport` reads `$inv.tags` from `Get-AzLocalClusterInventory`, but the v0.8.82 inventory projection did not carry the raw ARM `tags` bag, so the "Recent update attempts with no observable updateRun" section silently always reported zero gaps in production. v0.8.83 surfaces the raw `tags` bag on every inventory row (in-memory only; the on-disk CSV / JSON export keeps its explicit `$selectColumns` whitelist so artefacts continue to omit the raw bag). Also fixes the GitHub Actions `monitor-updates.yml` `jobs.outputs:` block to expose `attempts_without_run` to downstream jobs (the cmdlet was already emitting it in v0.8.82 - only the YAML wiring was missing), and a docstring drift in `Export-AzLocalUpdateRunMonitorReport` ("6 step outputs" -> "7 step outputs"). No public API change. Export count unchanged (still 60).
+
+`GENERATED_AGAINST_MODULE_VERSION` bumped from `0.8.82` to `0.8.83` across all bundled pipeline templates.
---