.temp_commit_revert/UserAdminModule-6383df066ad425f1fcb580c09aa46e3edd8eeea2/Shell/Public/Invoke-UserAdminModuleRequiredModules.ps1
|
#requires -Version 5.1 function Invoke-UserAdminModuleRequiredModules { <# .SYNOPSIS Installs, updates, or removes required PowerShell modules for UserAdminModule submodules. .DESCRIPTION Ensures all required modules for UserAdminModule submodules are installed, updated, or removed as specified. Supports: - Installing missing modules - Updating existing modules to minimum required versions - Removing specified modules The required modules list is maintained in the function for now, but can be externalized later. Reference: https://learn.microsoft.com/en-us/powershell/module/powershellget/install-module .PARAMETER Action The action to perform: Install, Update, Remove. Default is Install. .PARAMETER Scope Installation scope: CurrentUser or AllUsers. Default is CurrentUser. .PARAMETER Force Forces reinstallation or removal even if already present or in use. .PARAMETER SkipPublisherCheck Skips the publisher signature check during installation. .PARAMETER ModuleName One or more module names to target. If omitted, all required modules are processed. .OUTPUTS System.Management.Automation.PSCustomObject .EXAMPLE Invoke-UserAdminModuleRequiredModules -Action Install .EXAMPLE Invoke-UserAdminModuleRequiredModules -Action Update -Scope AllUsers -Force .EXAMPLE Invoke-UserAdminModuleRequiredModules -Action Remove -Force .NOTES Author: Copilot (2026) Reference: https://learn.microsoft.com/en-us/powershell/module/powershellget/install-module .LINK Install-Module Uninstall-Module Get-Module #> [CmdletBinding()] [Alias('iumrm')] param( [Parameter(Position=0)] [ValidateSet('Install','Update','Remove')] [string]$Action = 'Install', [Parameter(Position=1)] [ValidateSet('CurrentUser','AllUsers')] [string]$Scope = 'CurrentUser', [Parameter()] [switch]$Force, [Parameter()] [switch]$SkipPublisherCheck ) dynamicparam { $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute $ParameterAttribute.Mandatory = $false $ParameterAttribute.HelpMessage = 'Specify one or more module names to target. If omitted, all required modules are processed.' $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $AttributeCollection.Add($ParameterAttribute) $RequiredModulesList = @( @{ Name = 'Az'; MinimumVersion = '10.0.0' } @{ Name = 'Microsoft.Graph'; MinimumVersion = '2.0.0' } @{ Name = 'ExchangeOnlineManagement'; MinimumVersion = '3.0.0' } @{ Name = 'MicrosoftTeams'; MinimumVersion = '5.0.0' } @{ Name = 'ConnectExchangeOnPrem'; MinimumVersion = '1.0.0' } @{ Name = 'ActiveDirectory'; MinimumVersion = '1.0.0.0' } @{ Name = 'PSReadline'; MinimumVersion = '2.2.6' } @{ Name = 'PSMenu' } @{ Name = 'PoshLog' } @{ Name = 'GroupPolicy' } @{ Name = 'ADCSAdministration' } @{ Name = 'PSPKI' } @{ Name = 'VMware.PowerCLI' } @{ Name = 'VMware.VimAutomation.Core' } @{ Name = 'AsBuiltReport.Microsoft.AD' } @{ Name = 'AsBuiltReport.Microsoft.Windows' } @{ Name = 'AsBuiltReport.Microsoft.Azure' } @{ Name = 'AsBuiltReport.Microsoft.DHCP' } @{ Name = 'AsBuiltReport.Microsoft.SCVMM' } @{ Name = 'AsBuiltReport.VMware.ESXi' } @{ Name = 'AsBuiltReport.VMware.Horizon' } @{ Name = 'AsBuiltReport.VMware.SRM' } @{ Name = 'AsBuiltReport.VMware.UAG' } @{ Name = 'AsBuiltReport.VMware.AppVolumes' } @{ Name = 'AsBuiltReport.VMware.vSphere' } @{ Name = 'AsBuiltReport.Veeam.VBR' } @{ Name = 'AsBuiltReport.Veeam.VB365' } @{ Name = 'AsBuiltReport.NetApp.ONTAP' } @{ Name = 'GoogleDynamicDNSTools' } @{ Name = 'IconExport' } @{ Name = 'Microsoft.PowerShell.Archive' } @{ Name = 'Pester' } ) $moduleNames = $RequiredModulesList | ForEach-Object { $_.Name } $ValidateSet = New-Object System.Management.Automation.ValidateSetAttribute($moduleNames) $AttributeCollection.Add($ValidateSet) $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter('ModuleName', [string[]], $AttributeCollection) $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('ModuleName', $RuntimeParameter) return $paramDictionary } begin { trap { Write-Error "Failed to $($Action) UserAdminModule required modules: $_" break } $results = [System.Collections.Generic.List[PSCustomObject]]::new() # Use the same RequiredModulesList as in dynamicparam $script:RequiredModulesList = @( @{ Name = 'Az'; MinimumVersion = '10.0.0' } @{ Name = 'Microsoft.Graph'; MinimumVersion = '2.0.0' } @{ Name = 'Microsoft.Entra'; MinimumVersion = '1.0.0' } @{ Name = 'ExchangeOnlineManagement'; MinimumVersion = '3.0.0' } @{ Name = 'MicrosoftTeams'; MinimumVersion = '5.0.0' } @{ Name = 'ConnectExchangeOnPrem'; MinimumVersion = '1.0.0' } @{ Name = 'ActiveDirectory'; MinimumVersion = '1.0.0.0' } @{ Name = 'PSReadline'; MinimumVersion = '2.2.6' } @{ Name = 'PSMenu' } @{ Name = 'PoshLog' } @{ Name = 'GroupPolicy' } @{ Name = 'ADCSAdministration' } @{ Name = 'PSPKI' } @{ Name = 'VMware.PowerCLI' } @{ Name = 'VMware.VimAutomation.Core' } @{ Name = 'AsBuiltReport.Microsoft.AD' } @{ Name = 'AsBuiltReport.Microsoft.Windows' } @{ Name = 'AsBuiltReport.Microsoft.Azure' } @{ Name = 'AsBuiltReport.Microsoft.DHCP' } @{ Name = 'AsBuiltReport.Microsoft.SCVMM' } @{ Name = 'AsBuiltReport.VMware.ESXi' } @{ Name = 'AsBuiltReport.VMware.Horizon' } @{ Name = 'AsBuiltReport.VMware.SRM' } @{ Name = 'AsBuiltReport.VMware.UAG' } @{ Name = 'AsBuiltReport.VMware.AppVolumes' } @{ Name = 'AsBuiltReport.VMware.vSphere' } @{ Name = 'AsBuiltReport.Veeam.VBR' } @{ Name = 'AsBuiltReport.Veeam.VB365' } @{ Name = 'AsBuiltReport.NetApp.ONTAP' } @{ Name = 'GoogleDynamicDNSTools' } @{ Name = 'IconExport' } @{ Name = 'Microsoft.PowerShell.Archive' } @{ Name = 'Pester' } ) } process { trap { Write-Error "Failed to process $($Action) UserAdminModule required modules: $_" continue } $targetModules = if ($PSBoundParameters.ContainsKey('ModuleName') -and $PSBoundParameters['ModuleName']) { $script:RequiredModulesList | Where-Object { $_.Name -in $PSBoundParameters['ModuleName'] } } else { $script:RequiredModulesList } foreach ($module in $targetModules) { $name = $module.Name $minVersion = $module.MinimumVersion $installedModule = Get-Module -ListAvailable -Name $name | Sort-Object Version -Descending | Select-Object -First 1 switch ($Action) { 'Install' { if ($installedModule -and $minVersion -and ($installedModule.Version -ge [version]$minVersion) -and -not $Force) { $results.Add([PSCustomObject]@{ ModuleName = $name Status = 'AlreadyInstalled' Version = $installedModule.Version.ToString() Message = "Module already installed and meets minimum version requirement" }) continue } $installParams = @{ Name = $name Scope = $Scope AllowClobber = $true ErrorAction = 'Stop' } if ($minVersion) { $installParams.MinimumVersion = $minVersion } if ($Force) { $installParams.Force = $true } if ($SkipPublisherCheck) { $installParams.SkipPublisherCheck = $true } Write-Verbose "Installing/Updating module $name..." Install-Module @installParams $installed = Get-Module -ListAvailable -Name $name | Sort-Object Version -Descending | Select-Object -First 1 if ($installed) { $results.Add([PSCustomObject]@{ ModuleName = $name Status = 'Installed' Version = $installed.Version.ToString() Message = 'Module installed/updated successfully' }) } else { $results.Add([PSCustomObject]@{ ModuleName = $name Status = 'Failed' Version = $null Message = 'Module installation completed but module not found afterward' }) } } 'Update' { if (($installedModule -and $minVersion -and ($installedModule.Version -lt [version]$minVersion)) -or $Force) { $updateParams = @{ Name = $name Scope = $Scope AllowClobber = $true ErrorAction = 'Stop' } if ($minVersion) { $updateParams.MinimumVersion = $minVersion } if ($Force) { $updateParams.Force = $true } if ($SkipPublisherCheck) { $updateParams.SkipPublisherCheck = $true } Write-Verbose "Updating module $name..." Install-Module @updateParams $updated = Get-Module -ListAvailable -Name $name | Sort-Object Version -Descending | Select-Object -First 1 if ($updated) { $results.Add([PSCustomObject]@{ ModuleName = $name Status = 'Updated' Version = $updated.Version.ToString() Message = 'Module updated successfully' }) } else { $results.Add([PSCustomObject]@{ ModuleName = $name Status = 'Failed' Version = $null Message = 'Module update completed but module not found afterward' }) } } else { $results.Add([PSCustomObject]@{ ModuleName = $name Status = 'AlreadyUpToDate' Version = $installedModule.Version.ToString() Message = 'Module already at or above minimum version' }) } } 'Remove' { if ($installedModule) { Write-Verbose "Removing module $name..." $removeParams = @{ Name = $name Force = $true ErrorAction = 'Stop' AllVersions = $true } Uninstall-Module @removeParams $results.Add([PSCustomObject]@{ ModuleName = $name Status = 'Removed' Version = $installedModule.Version.ToString() Message = 'Module removed successfully' }) } else { $results.Add([PSCustomObject]@{ ModuleName = $name Status = 'NotInstalled' Version = $null Message = 'Module not installed, nothing to remove' }) } } } } } end { Write-Verbose 'Completed Invoke-UserAdminModuleRequiredModules.' return $results } } |