Public/Install-SpecPowerShellModule.ps1

function Install-SpecPowerShellModule {
    <#
    .SYNOPSIS
        Installs and updates specified PowerShell modules from the PowerShell Gallery.
 
    .DESCRIPTION
        The Install-SpecPowerShellModule function allows you to install and update specified PowerShell modules from the
        PowerShell Gallery. It checks if the module is already installed and, if required, installs the specified version
        or the latest version available. The function also supports automatically accepting license agreements using the
        -AcceptLicense switch.
 
    .PARAMETER ModuleName
        Specifies the name of the PowerShell module(s) to install or update. This parameter supports pipeline input.
 
    .PARAMETER Scope
        Specifies the scope in which to install the PowerShell module(s). Use "AllUsers" to install them for all users
        or "CurrentUser" to install them only for the current user.
 
    .VALIDATION
        Valid values for the Scope parameter are "AllUsers" and "CurrentUser".
 
    .PARAMETER RequiredVersion
        Specifies the required version of the PowerShell module(s) to install. If this parameter is provided, the function
        will attempt to install the specified version of the module(s). If not provided, it will install the latest available version.
 
    .PARAMETER AcceptLicense
        Indicates whether to accept the license agreement for the module(s) automatically. If this switch is used, the function
        will not prompt the user for acceptance.
 
    .EXAMPLE
        "ExampleModule" | Install-SpecPowerShellModule -Scope AllUsers -RequiredVersion "1.2.0" -AcceptLicense
        Installs version 1.2.0 of the "ExampleModule" PowerShell module for all users, automatically accepting the license.
 
    .EXAMPLE
        "AnotherModule" | Install-SpecPowerShellModule -Scope CurrentUser
        Installs the latest version of the "AnotherModule" PowerShell module for the current user.
 
    .EXAMPLE
        $Modules = @(
            @{
                moduleName = 'SpecBaseModule'
                requiredVersion = "1.0.2"
 
            },
            @{
                moduleName = 'Az.Accounts'
                requiredVersion = '2.10.2'
            }
        )
 
        $modules | % { Install-SpecPowerShellModule -Module $_.moduleName -RequiredVersion $_.requiredVersion -Scope CurrentUser -Verbose}
        Installs version 1.0.2 of the "SpecBaseModule" and 2.10.2 "Az.Accounts" PowerShell modules for the current user.
 
    .EXAMPLE
        $Modules = @(
            @{
                moduleName = 'SpecBaseModule'
                requiredVersion = ""
 
            },
            @{
                moduleName = 'Az.Accounts'
                requiredVersion = '2.10.2'
            }
        )
 
        $modules | % { Install-SpecPowerShellModule -Module $_.moduleName -RequiredVersion $_.requiredVersion -Scope CurrentUser -Verbose}
        Installs the latest version of the "SpecBaseModule" and version 2.10.2 "Az.Accounts" PowerShell modules for the current user.
 
 
    .NOTES
        Author: owen.heaume
        Version: 1.0 - initial function
    #>

    [cmdletbinding()]
    param (
        [parameter(Mandatory = $true, Position = 1, ValueFromPipeline = $true)]
        $ModuleName,

        [Parameter(Mandatory = $false)]
        [ValidateSet('AllUsers', 'CurrentUser')]
        $Scope = 'AllUsers',

        [Parameter(Mandatory = $false)]
        $RequiredVersion,

        [switch]
        $AcceptLicense
    )

    process {
        foreach ($module in $ModuleName) {
            # catch null or empty values in this parameter
            if ([string]::IsNullOrEmpty($RequiredVersion)) {$RequiredVersion = ""}

            Write-Host "`nChecking module [$module] to see if already installed:" -ForegroundColor DarkCyan

            if ([string]::IsNullOrEmpty($RequiredVersion)) {
                write-host "Parameter [-RequiredVersion] was not used" -ForegroundColor DarkGray
                $installedVersionNumber = Get-SpecInstalledModule -module $Module
            } else {
                write-host "The parameter [-RequiredVersion = $RequiredVersion] has been used" -ForegroundColor DarkGray
                $installedVersionNumber = Get-SpecInstalledModule -module $Module -version $RequiredVersion
            }


            if ($installedVersionNumber -ne $false) {
                write-host "Already installed" -ForegroundColor DarkGray
                $moduleInstalled = $true
            } else {
                write-host "Module not currently installed" -ForegroundColor DarkGray
            }

            if ($moduleInstalled) {
                write-host "Checking version number of installed module:" -ForegroundColor DarkCyan
                # Required version is already the same as the installed version
                if ($RequiredVersion -eq $installedVersionNumber) {
                    Write-host "No need to install module - required version [$RequiredVersion] is the same as the installed version [$installedVersionNumber]" -ForegroundColor DarkGray
                    continue #continue to next module in the pipeline
                } else {
                    write-host "Installed version is [$installedVersionNumber]" -ForegroundColor DarkGray
                }
            }

            # Get the latest version from PowerShell gallery
            write-host "Contacting PowerShell gallery to determine latest available version:" -ForegroundColor DarkCyan
            $LatestPSGalVersion = Get-SpecPSGalleryLatestVersion -Module $module

            if ($LatestPSGalVersion -eq $false) {
                Write-Host "The module cannot be found in the PowerShell gallery. Please make sure it exists or that you haven't made a typo." -ForegroundColor DarkYellow
                continue #continue to next module in the pipeline
            } else { write-host "Latest version is [$LatestPSGalVersion]" -ForegroundColor DarkGray }


            if ($moduleInstalled) {
                # Required version not specified but the installed version is already the same as the latest PSGal version
                if ([string]::IsNullOrEmpty($RequiredVersion) -and ($installedVersionNumber -eq $LatestPSGalVersion)) {
                    Write-host "Update not required. Installed module version [$installedVersionNumber] is the same as the latest version in the PowerShell Gallery [$LatestPSGalVersion]" -ForegroundColor DarkGray
                    #break
                    continue # go to next in loop
                }
            }


            # check if NuGet installed
            write-host "Checking to see if NuGet is installed on this system:" -ForegroundColor DarkCyan
            #$nugetProvider = Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue
            $nugetProvider = get-specpackageprovider

            #install NuGet package provider if not already installed
            if ($nugetProvider -eq $false) {
                write-host "NuGet not installed so installing it" -ForegroundColor DarkGray
                if ( Install-SpecNugetPackageProvider -Scope $scope) {
                    write-host "OK" -ForegroundColor DarkGreen
                } else {
                    write-host "NuGet installation failed" -ForegroundColor DarkYellow
                }
            } else {
                write-host "NuGet is already installed" -ForegroundColor DarkGray
            }


            # No specific version has been requested
            if ([string]::IsNullOrEmpty($RequiredVersion)) {
                # No specific version has been requested

                #install the latest version of the module from PowerShell Gallery
                if ($AcceptLicense.IsPresent) {
                    write-host "The parameter switch [-AcceptLicense] has been used" -ForegroundColor DarkGray
                    Write-host "Installing [$module] version [$LatestPSGalVersion] and accepting license" -ForegroundColor DarkCyan
                    if (Install-SpecModule -Module $module -Scope $scope -AcceptLicense) {
                        Write-Host "Module installed" -ForegroundColor DarkGreen
                    } else { write-host "The module was not successfully installed" -ForegroundColor DarkRed }

                } else {
                    Write-host "Installing [$module] version [$LatestPSGalVersion]" -ForegroundColor DarkCyan
                    if (Install-SpecModule -Module $module -Scope $scope) {
                        write-host "Module installed" -ForegroundColor DarkGreen
                    } else { write-host "The module was not successfully installed" -ForegroundColor DarkRed }
                }
            }



            # The module is not installed - but a specific version has been requested
            #if ($RequiredVersion -ne "" -or $RequiredVersion -ne $null) { # A specific version has been requested
            if (!([string]::IsNullOrEmpty($RequiredVersion))) {
                #install the required version of the module from PowerShell Gallery
                if ($AcceptLicense.IsPresent) {
                    write-host "The parameter switch [-AcceptLicense] has been used" -ForegroundColor DarkGray
                    Write-Host "Installing [$module] version [$RequiredVersion] and accepting license" -ForegroundColor DarkCyan
                    if (Install-SpecModule -Module $module -Scope $scope -RequiredVersion $RequiredVersion -AcceptLicense) {
                        write-host "Module Installed" -ForegroundColor DarkGreen
                    } else { write-host "The module was not successfully installed" -ForegroundColor DarkRed }
                } else {
                    Write-Host "Installing [$module] version [$RequiredVersion]" -ForegroundColor DarkCyan
                    if (Install-SpecModule -Module $module -Scope $scope -RequiredVersion $RequiredVersion) {
                        write-host "Module Installed" -ForegroundColor DarkGreen
                    } else { Write-Host "The module was not successfully installed" -ForegroundColor DarkRed }
                }
            }

        }
    }
}