functions/Install-PsModuleFast.ps1

Function Install-PsModuleFast {
    [CmdletBinding()]
    param([string] $module
        , [version] $version
        , [version] $MaxVersion
        , [version] $RequiredVersion
        , [string] $Repository)

    if ($requiredVersion.Build -eq -1) { throw "Required version has to be a 3 part version, " }

    Write-Verbose "Loading module $Module"

    Repair-PSModulePath;
    
    $InstallmoduleArgs = @{}
    if ($Repository) { $InstallmoduleArgs.Add("Repository", $Repository) }

    $InstallmoduleVersionArgs = @{}
    if ($Version) { $InstallmoduleVersionArgs.Add("MinimumVersion", $Version) }
    if ($RequiredVersion) { $InstallmoduleVersionArgs.Add("RequiredVersion", $RequiredVersion) }
    if ($MaxVersion) { $InstallmoduleVersionArgs.Add("MaximumVersion", $MaxVersion) }
   
    if (Test-ShouldInstallModule -Module $Module @InstallmoduleVersionArgs) {
        Write-Output " Installing module $module"
        install-module $module -force -AllowClobber -Scope CurrentUser -SkipPublisherCheck @InstallmoduleArgs @InstallmoduleVersionArgs
    }

    $ImportmoduleArgs = @{}
    if ($Version) { $ImportmoduleArgs.Add("MinimumVersion", $Version) }
    if ($RequiredVersion) { $ImportmoduleArgs.Add("RequiredVersion", $RequiredVersion) }
    if ($MaxVersion) { $ImportmoduleArgs.Add("MaximumVersion", $MaxVersion) }
   
    if (Test-ShouldImportModule -module $module  @ImportmoduleArgs) {
        Write-Output " importing module $module $version"
        get-MOdule $module | remove-module -Verbose
        import-module $module -force  @ImportmoduleArgs -Global -Verbose #:$VerbosePreference
        Write-Verbose "### Module imported"
        Write-Verbose (get-Module  | out-string)
    }
}

function Test-ShouldInstallModule() {
    [CmdletBinding()]
    [OutputType([Boolean])]
    param($module
        , [version]$RequiredVersion
        , [version]$MaximumVersion
        , [version]$MinimumVersion)
        
    $modulesInstalled = get-module $module -ListAvailable

    return Test-ShouldGetVersion -modules $modulesInstalled -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion

}
function Test-ShouldImportModule() {
    [CmdletBinding()]
    [OutputType([Boolean])]
    param($module
        , [version]$RequiredVersion
        , [version]$MaximumVersion
        , [version]$MinimumVersion)
        
    $modulesLoaded = get-module $module 

    return Test-ShouldGetVersion -modules $modulesLoaded -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion

}

function Test-ShouldGetVersion() {
    [CmdletBinding()]
    [OutputType([Boolean])]
    param($modules
        , [version]$RequiredVersion
        , [version]$MaximumVersion
        , [version]$MinimumVersion)
    Write-Verbose " Min=$MinimumVersion Max =$MaximumVersion"
    if ($null -ne $RequiredVersion ) {
        write-Verbose "Required version"
        if ( -not ($modules.Version -eq $RequiredVersion)) {
            write-Verbose "Required version not found so have to install"
            return $true
        }
    }
    if ($null -ne $MinimumVersion -and -not ($modules.Version -ge $MinimumVersion)) {
        write-Verbose "Minimum version not found so have to install"
        return $true
    }
    if ($null -ne $MaximumVersion -and -not ($modules.Version -le $MaximumVersion)) {
        write-Verbose "Maximum version modules found so have to install"
        return $true
    }
    if (($null -ne $MinimumVersion) -and ($null -ne $MaximumVersion) ) {
        Write-Verbose "Min and Max"
        if (-not ($modules | Where-Object { $_.Version -ge $MinimumVersion -and $_.Version -le $MaximumVersion })) {
            write-Verbose "Minimum and Maximum version modules found so have to install"
            return $true
        }
    }
    if ($null -eq $modules ) {
        write-Verbose "No modules found so have to install"
        return $true
    }
    write-Verbose "All tests passed don't install $($modules.Version)"
    return $false;

}


# Function Install-PsModuleFast {
# [CmdletBinding()]
# param([string] $module
# , [version] $version
# , [parameter(Mandatory=$false)][string] $path)
#
# Repair-PSModulePath;
#
# Write-Verbose "Loading module $Module"
# if (-not (get-module $(join-path $path $module) -ListAvailable | Where-object Version -ge $version)) {
# Write-Output " Installing module $module"
# if ($null -eq $version) {
# install-module $module -path $path -force -AllowClobber -Scope CurrentUser -SkipPublisherCheck
# }
# else {
# install-module $module -path $path -force -AllowClobber -Scope CurrentUser -SkipPublisherCheck -MinimumVersion $version
# }
# }
#
# if (-not (get-module $module | Where-object Version -GE $version)) {
# Write-Output " importing module $module $version"
# if ($null -eq $version ) {
# import-module $module -force
# }
# else {
# import-module $module -force -MinimumVersion $version
# }
# }
# }

function Repair-PSModulePath {

    if ($PSVersionTable.PsEdition -eq "Core") {
        $mydocsPath = "$([environment]::GetFolderPath("MyDocuments"))\PowerShell\Modules"
    }
    else {
        $mydocsPath = "$([environment]::GetFolderPath("MyDocuments"))\WindowsPowerShell\Modules"
    }

    If ("$($env:PSModulePath)".Split(";") -notcontains $mydocsPath) {
        Write-Verbose "Adding LocalModule folder to PSModulePath"
        $env:PSModulePath = "$mydocsPath;$($env:PSModulePath)"
    }
}

# $PSModules = @{Module = "Pester"; Version = "4.5" }, `
# @{Module = "Microsoft.PowerApps.PowerShell" }, `
# @{Module = "Microsoft.PowerApps.Administration.PowerShell" }, `
# @{Module = "VSSetup" }
# foreach ($Ps in $PSModules) {
#
# Install-PsModuleFast @PS
# }