Classes/psmodule.ps1
class psmodule { <# .SYNOPSIS A class for managing PowerShell modules, including installation, importation, and removal. .DESCRIPTION The psmodule class provides a structured approach to managing PowerShell modules. It allows users to check if a module is installed or imported, install new modules from the PowerShell Gallery, import existing modules into the current session, remove modules from memory, and uninstall modules entirely. The class includes features to handle versioning and user scope for module installations. .EXAMPLES # Example 1: Create an instance of the class with only the module name. $module = [psmodule]::new("Spec.Base.Utilities") # Creates a new psmodule object for managing the specified module. # Example 2: Create an instance of the class with module name and version. $moduleWithVersion = [psmodule]::new("Spec.Base.Utilities", "1.0.9") # Creates a new psmodule object specifically for version 1.0.9 of the module. # Example 3: Install the module if not already installed and import it. $module.InstallAndImport() # Checks if the module is installed; if not, it installs and imports it into the current session. # Example 4: Check if the module is installed and display the result. if ($module.isInstalled()) { Write-Host "Module is installed." } else { Write-Host "Module is not installed." } # Example 5: Remove the module from memory if it is currently imported. # This does not uninstall the module; it just removes it from the current session. $module.remove() # Example 6: Report the current status of the module to determine its state. $module.reportStatus() # This will output whether the module is installed, imported, or both. # Example 7: Uninstall the module completely, removing all versions if applicable. # You can also uninstall a specific version of the module by providing the version # during class instantiation. If no version is specified, all versions will be uninstalled. $module.Uninstall() # Uninstalls all versions # Or for a specific version: $specificModule = [psmodule]::new("Spec.Base.Utilities", "1.0.9") $specificModule.Uninstall() # Uninstalls only version 1.0.9 # Example 8: Install and import the module with specific scope and license acceptance. $specificModule = [psmodule]::new("Spec.Base.Utilities", "1.0.9", "CurrentUser", $true) $specificModule.InstallAndImport() # Installs version 1.0.9 of the module for the current user, accepting the license. Then imports it. # Example 9: Check if the module is currently loaded in the session. if ($module.isImported()) { Write-Host "Module is currently loaded." } else { Write-Host "Module is not loaded." } # Example 10: Install the latest available version of a module without specifying a version. $latestModule = [psmodule]::new("Spec.Base.Utilities") $latestModule.InstallAndImport() # If the module is not already installed, this will install the latest version available. # If a lower version is already installed, it will update to the latest version. # Example 11: Attempt to install a module that requires a specific version. $versionSpecificModule = [psmodule]::new("Spec.Base.Utilities", "1.0.9") if (-not $versionSpecificModule.isInstalled()) { $versionSpecificModule.InstallAndImport() } # This ensures that version 1.0.9 is installed and imported if it isn't already. .NOTES See Also: The helper function for instantiating an object: New-specPSModuleObject. Author: owen.heaume Version: 1.0.0 - initial release #> [string] $moduleName [string] $version [ValidateSet('CurrentUser', 'AllUsers')] [string] $scope = 'AllUsers' [bool] $acceptLicense = $true # Constructor with only moduleName psmodule([string] $moduleName) { $this.moduleName = $moduleName } # Constructor with only moduleName and version psmodule([string] $moduleName, [string]$version) { $this.moduleName = $moduleName $this.version = $version } # Constructor with moduleName, version, scope, and acceptLicense psmodule([string] $moduleName, [string] $version, [string] $scope = 'AllUsers', [bool] $acceptLicense = $true) { $this.moduleName = $moduleName $this.version = $version $this.scope = $scope $this.acceptLicense = $acceptLicense } # Method to check if the module is installed [bool]isInstalled() { if ([string]::IsNullOrEmpty($this.version)) { # Check if the module exists $module = Get-Module -ListAvailable -Name $this.moduleName } else { # Check if the module exists based on both name and version $module = Get-Module -ListAvailable -Name $this.moduleName | Where-Object { $_.Version -eq $this.version } } # Return true if any module(s) are found, otherwise false return @($module).Count -gt 0 } # Method to check if module is currently loaded [bool]isImported() { # Check if the module is loaded based on name only if ([string]::IsNullOrEmpty($this.version)) { $module = Get-Module -Name $this.moduleName } else { # Check if the module is loaded based on both name and version $module = Get-Module -Name $this.moduleName | Where-Object { $_.Version -eq $this.version } } # Return true if any module(s) are found, otherwise false return @($module).Count -gt 0 } # method to remove the module (Unload it from memory) [void]remove() { if ($this.isImported()) { Remove-Module -Name $this.moduleName -Force Write-Host "Module $($this.moduleName) removed." } else { Write-Host "Module $($this.moduleName) is not imported." } } # Method to import the module [void]import() { if ($this.isInstalled()) { if (-not ($this.isImported())) { # If a version is specified, use the -RequiredVersion parameter if ([string]::IsNullOrEmpty($this.version)) { Import-Module -Name $this.moduleName -Force -DisableNameChecking -Global Write-Host "Module $($this.moduleName) imported." } else { Import-Module -Name $this.moduleName -RequiredVersion $this.version -Force -DisableNameChecking -Global Write-Host "Module $($this.moduleName) version $($this.version) imported." } } else { # Modified to include version if specified if (![string]::IsNullOrEmpty($this.version)) { Write-Host "Module $($this.moduleName) version $($this.version) is already imported." } else { Write-Host "Module $($this.moduleName) is already imported." } } } else { Write-Host "Module $($this.moduleName) is not installed." } } [void]reportStatus() { if ($this.isInstalled() -and $this.isImported()) { Write-Host "Module $($this.moduleName) is installed and imported." -ForegroundColor DarkGreen } elseif ($this.isInstalled()) { Write-Host "Module $($this.moduleName) is installed but not imported." -ForegroundColor DarkYellow } else { Write-Host "Module $($this.moduleName) is not installed." -ForegroundColor DarkYellow } } [void] install() { # Check if the module is installed $installedModule = Get-InstalledModule -Name $this.moduleName -ErrorAction SilentlyContinue if (-not $installedModule) { # Module is not installed, install the latest version $installParams = @{ Name = $this.moduleName Force = $true ErrorAction = 'Stop' Scope = $this.scope } # Add AcceptLicense only if $this.acceptLicense is true if ($this.acceptLicense) { $installParams['AcceptLicense'] = $true } # If a version is specified, add it to the parameters if (![string]::IsNullOrEmpty($this.version)) { $installParams['RequiredVersion'] = $this.version } # Install the module try { Install-Module @installParams Write-Host "Module '$($this.moduleName)' has been installed." } catch { Write-Error "Failed to install module '$($this.moduleName)': $_" } } elseif ($this.version -and $installedModule.Version -ne $this.version) { # If a specific version is provided and it's different, install the specified version $installParams = @{ Name = $this.moduleName RequiredVersion = $this.version Force = $true } # Add AcceptLicense only if $this.acceptLicense is true if ($this.acceptLicense) { $installParams['AcceptLicense'] = $true } try { Install-Module @installParams -ea stop Write-Host "Module '$($this.moduleName)' version $($this.version) has been installed." } catch { Write-Error "Failed to install module '$($this.moduleName)' version '$($this.version)': $_" } } elseif (-not $this.version) { # If no version is specified, install the latest version if the installed version is outdated $latestModule = Find-Module -Name $this.moduleName if ($installedModule.Version -lt $latestModule.Version) { $installParams = @{ Name = $this.moduleName Force = $true } # Add AcceptLicense only if $this.acceptLicense is true if ($this.acceptLicense) { $installParams['AcceptLicense'] = $true } try { Install-Module @installParams -ea stop Write-Host "Module '$($this.moduleName)' has been updated to the latest version $($latestModule.Version)." } catch { Write-Error "Failed to update module '$($this.moduleName)': $_" } } else { Write-Host "Module '$($this.moduleName)' is already at the latest version." } } else { Write-Host "Module '$($this.moduleName)' version $($installedModule.Version) is already installed." } } # Uninstall method to remove the module [void] Uninstall() { # Check if a specific version is provided if ([string]::IsNullOrEmpty($this.version)) { # No version specified, uninstall all versions $installedModules = Get-InstalledModule -Name $this.moduleName -AllVersions -ErrorAction SilentlyContinue if ($null -ne $installedModules) { # Uninstall all installed versions foreach ($module in $installedModules) { try { Uninstall-Module -Name $module.Name -Force -RequiredVersion $module.Version -ErrorAction Stop Write-Host "Module '$($module.Name)' version $($module.Version) has been uninstalled." } catch { # Only warn if the error is not related to not finding the module if ($_.Exception.Message -notlike '*No match was found*') { Write-Warning "Failed to uninstall module '$($module.Name)' version $($module.Version). It may have already been removed." } } } } else { Write-Host "Module '$($this.moduleName)' is not installed." } } else { # A specific version is provided, uninstall only that version $installedModule = Get-InstalledModule -Name $this.moduleName -RequiredVersion $this.version -ErrorAction SilentlyContinue if ($null -ne $installedModule) { try { Uninstall-Module -Name $installedModule.Name -RequiredVersion $this.version -Force -ErrorAction Stop Write-Host "Module '$($installedModule.Name)' version $($this.version) has been uninstalled." } catch { # Only warn if the error is not related to not finding the module if ($_.Exception.Message -notlike '*No match was found*') { Write-Warning "Failed to uninstall module '$($installedModule.Name)' version $($this.version)." } } } else { Write-Host "Module '$($this.moduleName)' version $($this.version) is not installed." } } } # Method to install the module if required, import the module and report the status [void] InstallAndImport() { try { # Attempt to install the module $this.install() # Check if the module is installed successfully if (-not $this.isInstalled()) { Write-Error "Module '$($this.ModuleName)' was not installed successfully." -ea stop } # Attempt to import the module $this.import() # Call ReportStatus only if both install and import are successful $this.ReportStatus() } catch { Write-Error "An error occurred: $_" $this.ReportStatus() } } } |