Refactor module functions with begin/process/end and harden module maintenance flow#46
Conversation
Agent-Logs-Url: https://github.com/rwidmark/MaintainModule/sessions/110e489a-bc1a-4e49-9063-b756ca88703f Co-authored-by: rwidmark <76907327+rwidmark@users.noreply.github.com>
Agent-Logs-Url: https://github.com/rwidmark/MaintainModule/sessions/110e489a-bc1a-4e49-9063-b756ca88703f Co-authored-by: rwidmark <76907327+rwidmark@users.noreply.github.com>
Agent-Logs-Url: https://github.com/rwidmark/MaintainModule/sessions/110e489a-bc1a-4e49-9063-b756ca88703f Co-authored-by: rwidmark <76907327+rwidmark@users.noreply.github.com>
Agent-Logs-Url: https://github.com/rwidmark/MaintainModule/sessions/110e489a-bc1a-4e49-9063-b756ca88703f Co-authored-by: rwidmark <76907327+rwidmark@users.noreply.github.com>
Agent-Logs-Url: https://github.com/rwidmark/MaintainModule/sessions/110e489a-bc1a-4e49-9063-b756ca88703f Co-authored-by: rwidmark <76907327+rwidmark@users.noreply.github.com>
Agent-Logs-Url: https://github.com/rwidmark/MaintainModule/sessions/110e489a-bc1a-4e49-9063-b756ca88703f Co-authored-by: rwidmark <76907327+rwidmark@users.noreply.github.com>
Agent-Logs-Url: https://github.com/rwidmark/MaintainModule/sessions/110e489a-bc1a-4e49-9063-b756ca88703f Co-authored-by: rwidmark <76907327+rwidmark@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Refactors the MaintainModule PowerShell module to be more pipeline-aware (via begin/process/end) while hardening repository/module maintenance operations with more explicit error handling and consolidated module/version shaping.
Changes:
- Introduces an internal helper (
Get-rsModuleDetail) to normalize installed module metadata and version selection. - Refactors exported functions to use
begin/process/endblocks and improvesShouldProcessusage around update/install/uninstall and PSGallery trust changes. - Centralizes version parsing/sorting to reduce repeated module/version processing during maintenance.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| foreach ($currentModule in @($Module)) { | ||
| if ([string]::IsNullOrWhiteSpace($currentModule)) { | ||
| continue | ||
| } | ||
|
|
||
| Write-Output "START - Uninstall older versions of $currentModule" | ||
| Write-Output "Please wait, this can take some time..." | ||
|
|
||
| foreach ($_version in $versionsToRemove) { |
There was a problem hiding this comment.
Uninstall-rsModule currently becomes a no-op when -Module is omitted (the process loop only iterates over provided module names and there is no fallback path). This conflicts with the help text/examples that imply omitting -Module uninstalls old versions for all installed modules. Either implement the all-modules behavior (e.g., discover installed modules + old versions and loop them) or make -Module mandatory and update the comment-based help accordingly.
| foreach ($currentModule in @($Module)) { | |
| if ([string]::IsNullOrWhiteSpace($currentModule)) { | |
| continue | |
| } | |
| Write-Output "START - Uninstall older versions of $currentModule" | |
| Write-Output "Please wait, this can take some time..." | |
| foreach ($_version in $versionsToRemove) { | |
| $modulesToProcess = @($Module | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) | |
| if ($modulesToProcess.Count -eq 0) { | |
| try { | |
| $modulesToProcess = @(Get-InstalledModule -AllVersions -ErrorAction Stop | Select-Object -ExpandProperty Name -Unique) | |
| } | |
| catch { | |
| Write-Error "Failed to discover installed modules. $($PSItem.Exception.Message)" | |
| return | |
| } | |
| } | |
| foreach ($currentModule in $modulesToProcess) { | |
| Write-Output "START - Uninstall older versions of $currentModule" | |
| Write-Output "Please wait, this can take some time..." | |
| try { | |
| $installedVersions = @(Get-InstalledModule -Name $currentModule -AllVersions -ErrorAction Stop | Sort-Object Version -Descending) | |
| } | |
| catch { | |
| Write-Error "Failed to get installed versions for $($currentModule). $($PSItem.Exception.Message)" | |
| continue | |
| } | |
| if ($versionsToRemove.Count -gt 0) { | |
| $moduleVersionsToRemove = @( | |
| $installedVersions | | |
| Where-Object { $versionsToRemove -contains $_.Version } | | |
| ForEach-Object { $_.Version } | |
| ) | |
| } | |
| else { | |
| $moduleVersionsToRemove = @( | |
| $installedVersions | | |
| Select-Object -Skip 1 | | |
| ForEach-Object { $_.Version } | |
| ) | |
| } | |
| if ($moduleVersionsToRemove.Count -eq 0) { | |
| Write-Output "FINISHED - No older versions of $currentModule were found to uninstall." | |
| continue | |
| } | |
| foreach ($_version in $moduleVersionsToRemove) { |
| ErrorAction = 'Stop' | ||
| } | ||
| Write-Output "$($_module.Name) has now been updated to version $($CollectLatestVersion)!" | ||
|
|
There was a problem hiding this comment.
Update-rsModule uses Find-Module results to decide whether an update is required, but it does not pass -AllowPrerelease when $AllowPrerelease is $true. This can cause prerelease updates to be skipped because the version comparison is based only on stable versions. Consider adding AllowPrerelease = $AllowPrerelease to $findModuleParameters when enabled so discovery and update behavior stay consistent.
| if ($AllowPrerelease) { | |
| $findModuleParameters.AllowPrerelease = $AllowPrerelease | |
| } |
This updates the module functions to use PowerShell
begin/process/endexecution blocks and tightens error handling around repository and module operations. It also simplifies the maintenance flow so update, install-missing, and old-version cleanup behave more consistently.Execution flow
begin/process/endwhere pipeline-aware behavior makes sense.Error handling
try/catcharoundGet-InstalledModule,Find-Module,Update-Module,Install-Module,Uninstall-Module, and PSGallery trust configuration.-ErrorAction Stopwhere recovery or reporting is required.Control-flow cleanup
Update-rsModulecan reliably handle both.ShouldProcessusage for update, install, uninstall, and PSGallery trust changes.Optimization
Operational messaging
Example of the refactored pattern used across functions: