Private/Helper/Test-IntegrisModuleDependency.ps1

<#
Copyright © 2024 Integris. For internal company use only. All rights reserved.
#>


FUNCTION Test-IntegrisModuleDependency {
    <#
    .SYNOPSIS
    Tests and ensures the specified PowerShell module is installed and up to date.
 
    .DESCRIPTION
    This function checks if a specified PowerShell module is installed and meets the minimum version requirement. If not, it prompts the user to install or update the module.
 
    .PARAMETER Name
    Specifies the name of the module to test.
 
    .PARAMETER MinimumVersion
    Specifies the minimum version of the module required.
 
    .PARAMETER Confirm
    Prompts the user for confirmation before installing or updating the module. Defaults to $true. Use -Confirm:$False to override.
 
    .PARAMETER Force
    Forces the installation or update of the module.
 
    .EXAMPLE
    Test-IntegrisModuleDependency -Name "ModuleName" -MinimumVersion "1.0.0" -Confirm -Force
    Tests and ensures the specified module is installed and up to date, with user confirmation and force options.
 
    .NOTES
    The function checks for the module and handles installation or update as needed.
    #>


    [CmdletBinding()]
    PARAM (
        [Parameter(Mandatory)]
        [String]$Name,
        [String]$MinimumVersion,
        [Switch]$Confirm,
        [Switch]$Force
    )

    # Set TLS Protocol for PowerShell Session
    TRY { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 }
    CATCH {}

    # Check if Module is installed
    $InstalledModules = Get-Module -ListAvailable -Name $Name -ErrorAction SilentlyContinue

    IF ($null -eq $InstalledModules) {
        # Check if user consent is required
        IF ($Confirm) {
            Write-Host "$($Name) PowerShell module is requied, do you want to install it?" -ForegroundColor Yellow
            $UserInputInstall = Read-Host "Do you want to install module? [Y] Yes [N] No "
            IF ($UserInputInstall -match "[yY]") {
                $Install = $True
            }
            ELSE {
                $Install = $False
            }
        }

        # If user consent is granted, proceed to install
        IF ($Install -or !($Confirm)) {
            # Check if Package Provider and Source are available and registered
            TRY {
                IF ($null -eq (Get-PackageSource -Name nugetRepository -ErrorAction SilentlyContinue)) {
                    Find-PackageProvider -Name NuGet -ErrorAction SilentlyContinue -Force | Install-PackageProvider -Force -Scope CurrentUser | Out-Null
                    Register-PackageSource -Provider NuGet -Name nugetRepository -Location https://www.nuget.org/api/v2 -Force | Out-Null
                }
            }
            CATCH {
                Write-Warning "Error validating NuGet package provider and source. This may cause the Module installation to fail."
            }

            # Install Module
            Write-Verbose "Installing $($Name) Module"
            IF($Force){ Install-Module $Name -Repository PSGallery -Scope CurrentUser -AllowClobber -Force }
            ELSE{ Install-Module $Name -Repository PSGallery -Scope CurrentUser }

            #Test if the install was successful
            $InstalledModules = Get-Module -ListAvailable -Name $Name -ErrorAction SilentlyContinue
            IF ($null -eq $InstalledModules) {
                Write-Error "Error installing $($Name) Module. Please install manually."
                Return $False
            }
        }
        ELSE {
            Write-Error "Please install $($Name) Module manually."
            Return $False
        }
    }
    
    # Check if MinimumVersion was defined
    IF ($MinimumVersion) {
        #Check if module matches the latest version. If it does not, remove the module from the session and update the module
        IF ($InstalledModules[0].Version -lt $MinimumVersion) {
            Write-Verbose "$($Name) Module not up to date."
            
            # Check if user consent is required
            IF ($Confirm) {
                $UserInputUpdate = Read-Host "Do you want to update module? [Y] Yes [N] No "
                IF ($UserInputUpdate -match "[yY]") {
                    $Update = $True
                }
                ELSE {
                    $Update = $False
                }
            }

            # If user consent is granted, proceed to update
            IF ($Update -or !($Confirm)) {
                Write-Verbose "Removing $($Name) Module from current session."
                IF($Force){ Remove-Module -Name $Name -Force -ErrorAction SilentlyContinue }
                ELSE { Remove-Module -Name $Name -ErrorAction SilentlyContinue }
                Write-Verbose "Updating Module: $($Name)"
                IF($Force){ Update-Module -Name $Name -Force -ErrorAction SilentlyContinue }
                ELSE { Update-Module -Name $Name -ErrorAction SilentlyContinue }
            }
            ELSE {
                Write-Error "Please update $($Name) module manually."
                RETURN $False
            }
        }
    }
    
    #Import Module
    TRY {
        Write-Verbose "Importing Module: $($Name)"
        Import-Module -Name $Name
        RETURN $True
    }
    CATCH {
        Write-Error "Error importing $($Name) Module."
        RETURN $False
    }
}