Functions/Install-PsModuleFast.ps1
<#
.SYNOPSIS Installs and Imports a module .DESCRIPTION Encapsulates the logic to ensure the required version is installed and loaded into the session. If not installed the module is downloaded to the CurrentUser scope. If a version that isn't compatible is loaded it will be removed If the version required isn't loaded it will be imported You can specify, ```-MinimumVersion```, ```-MaximumVersion``` in which case an appropriate version is loaded if installed. It will not go and install a later version even if one exists in the repository unless `-latest` is used If required version is specified only that version will be installed and imported . .EXAMPLE none .OUTPUTS none .NOTES none #> Function Install-PsModuleFast { [CmdletBinding()] param([string] #Name of the module to install $module , #Minimum version to install and import [version] $version #Maximumversion to install and import , [version] $MaxVersion #The version that has to be found to install. Must be 3 part version number , [string] $RequiredVersion #Allows for pre release versions to be installed , [switch] $AllowPrerelease #Repository to look for modules , [string] $Repository #Will find the latest version within the Min and Max specified and install that ,[switch]$Latest ,[string]$Scope="CurrentUser") if ($PSBoundParameters.ContainsKey("RequiredVersion") -and $requiredVersion -notmatch "^\d*\.\d*\.\d*") { throw "Required version has to be a 3 part semver version" } Write-Verbose "Loading module $Module" Repair-PSModulePath; if ($Latest){ $FindModuleArgs = @{Name=$Module} if ($version){$FindModuleArgs.Add("MinimumVersion",$version)} if ($MaxVersion){$FindModuleArgs.Add("MaximumVersion",$MaxVersion)} if ( $Repository){ $FindModuleArgs.Add("Repository",$Repository)} Write-Verbose "Finding Latest version for module" $RequiredVersion = (Find-Module @FindModuleArgs).Version Write-Verbose "Latest version found $RequiredVersion " } $InstallmoduleArgs = @{} if ($Repository) { $InstallmoduleArgs.Add("Repository", $Repository) } $VersionArgs = @{} if ($RequiredVersion) { $versionparts = split-version $RequiredVersion Write-Verbose "Only using Required Version" $VersionArgs.Add("RequiredVersion", $RequiredVersion) # $VersionArgs.Add("prerelease", $versionparts.Prerelease) } else{ if ($Version) { $VersionArgs.Add("MinimumVersion", $Version) } if ($MaxVersion) { $VersionArgs.Add("MaximumVersion", $MaxVersion) } } if (Test-ShouldInstallModule -Module $Module @VersionArgs) { Write-Host " Installing module $module" -NoNewline install-module $module -force -AllowClobber -Scope $Scope -SkipPublisherCheck @InstallmoduleArgs @VersionArgs -AllowPrerelease:$AllowPrerelease Write-Host " - installed $((get-module $module -ListAvailable).Version)" } if (Test-ShouldImportModule -module $module @VersionArgs) { Write-Host " importing module $module " -NoNewline #remove module from session get-Module $module | ForEach-Object{ Write-Host " - removing $($_.version)" -NoNewline remove-module -Name $_.name -Verbose } #import module doesn't understand prerelease if ($RequiredVersion) { $versionparts = split-version $RequiredVersion Write-Verbose "Only using Required Version" $VersionArgs.RequiredVersion=$versionparts.Version } import-module $module -force @VersionArgs -Global -Verbose:$VerbosePreference Write-Host " - imported $((get-module $module).Version)" } Write-Host ("using module {0:-20} - {1}" -f $module, $($(Get-Module $module).version)) } function split-version{ param ($version) $versionparts = $version | Select-String "^(\d*\.\d*\.\d*)-?(.*)" write-Verbose "splitting out $version " write-Verbose ($versionparts | Format-List | out-string) return @{ version=$versionparts.Matches.Groups[1].value; prerelease=$versionparts.Matches.Groups[2].value } } function Test-ShouldInstallModule() { [CmdletBinding()] [OutputType([Boolean])] param($module , [string]$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 , [string]$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 ,[string]$RequiredVersion ,[version]$MaximumVersion ,[version]$MinimumVersion) if ($RequiredVersion -ne "" ){ write-Verbose "Required version" if ($RequiredVersion -match "^\d*\.\d*\.\d*$"){ if ( -not ($modules.Version -eq $RequiredVersion)) { write-Verbose "Required version not found so have to install" return $true } } else { $versionparts = split-version $requiredVersion if (($modules | where-object {$_.Version -eq $versionparts.version -and $_.privateData.psdata.prerelease -eq $versionparts.prerelease}).Count -eq 0){ write-Verbose "Required version ($version) for prerelease ($prerelease) 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 installed are $($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 # } # } # } # $PSModules = @{Module = "Pester"; Version = "4.5" }, ` # @{Module = "Microsoft.PowerApps.PowerShell" }, ` # @{Module = "Microsoft.PowerApps.Administration.PowerShell" }, ` # @{Module = "VSSetup" } # foreach ($Ps in $PSModules) { # # Install-PsModuleFast @PS # } |