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-InstalledModule -Name $this.moduleName -ErrorAction SilentlyContinue } else { # Check if the module exists based on both name and version $module = Get-InstalledModule -Name $this.moduleName -RequiredVersion $this.version -ErrorAction SilentlyContinue } # Return true if the module is found return $null -ne $module } # 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 the module is already imported, remove it first if ($this.isImported()) { Remove-Module -Name $this.moduleName -Force Write-Host "Module $($this.moduleName) removed." } # 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 { 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 -AllVersions -ErrorAction SilentlyContinue | Where-Object { $_.Version -eq [Version]$this.version } # If the module is not installed or the wrong version is installed if (-not $installedModule) { # Construct the install parameters $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 } try { # Install the module Install-Module @installParams # If no version was specified, retrieve the installed version if ([string]::IsNullOrEmpty($this.version)) { $installedModule = Get-InstalledModule -Name $this.moduleName $this.version = $installedModule.Version.ToString() # Update the version property with the installed version } Write-Host "Module '$($this.moduleName)' version $($this.version) has been installed. <--- **" } catch { Write-Error "Failed to install module '$($this.moduleName)': $_" } } else { # The correct version is already installed Write-Host "Module '$($this.moduleName)' version $($this.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, specifying the version $this.import() # Call ReportStatus only if both install and import are successful $this.reportStatus() } catch { Write-Error "An error occurred: $_" $this.reportStatus() } } } |