Public/Install-NSPModule.ps1
|
function Install-NSPModule { <# .SYNOPSIS Ensures one or more PSGallery modules are present (optionally at a minimum version), installing for the current user if they are not. .DESCRIPTION Consolidates the "Set-PSRepository / Find-Module / compare / Install-Module" block that is copy-pasted across the NSP scripts. Deliberately conservative: - Does NOT permanently mark PSGallery trusted (uses Install-Module -Force to suppress the per-call prompt instead). - Installs to CurrentUser scope by default (no elevation needed). - Forces TLS 1.2 first - Windows PowerShell 5.1 defaults to SSL3/TLS1.0 and the gallery refuses those. .PARAMETER Name One or more module names. .PARAMETER MinimumVersion If set, a module already present below this version is upgraded. .PARAMETER Scope CurrentUser (default) or AllUsers (needs elevation). .PARAMETER Force Reinstall even if a satisfying version is already present. .PARAMETER SkipPublisherCheck Pass through to Install-Module. Needed when upgrading a module that shipped in-box under a Microsoft signature to a gallery build signed by a different publisher - the classic case is Pester 3.4.0 (in-box) -> Pester 5/6. .EXAMPLE Install-NSPModule -Name Microsoft.PowerShell.SecretManagement, Microsoft.PowerShell.SecretStore .EXAMPLE Install-NSPModule -Name Pester -MinimumVersion 5.5.0 -SkipPublisherCheck #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory, Position = 0)][string[]]$Name, [string]$MinimumVersion, [ValidateSet('CurrentUser', 'AllUsers')][string]$Scope = 'CurrentUser', [switch]$Force, [switch]$SkipPublisherCheck ) try { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 } catch { Write-Verbose "Install-NSPModule: could not set TLS 1.2 ($_) - continuing." } foreach ($moduleName in $Name) { $satisfying = Get-Module -ListAvailable -Name $moduleName | Where-Object { -not $MinimumVersion -or $_.Version -ge [version]$MinimumVersion } | Sort-Object Version -Descending | Select-Object -First 1 if ($satisfying -and -not $Force) { Write-Verbose "Install-NSPModule: '$moduleName' $($satisfying.Version) already present." continue } if (-not (Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) { if ($PSCmdlet.ShouldProcess('NuGet', 'Install-PackageProvider')) { Install-PackageProvider -Name NuGet -MinimumVersion '2.8.5.201' -Scope $Scope -Force | Out-Null } } $installParams = @{ Name = $moduleName Scope = $Scope Force = $true AllowClobber = $true ErrorAction = 'Stop' } if ($MinimumVersion) { $installParams.MinimumVersion = $MinimumVersion } if ($SkipPublisherCheck) { $installParams.SkipPublisherCheck = $true } if ($PSCmdlet.ShouldProcess($moduleName, "Install-Module (scope $Scope)")) { Write-Verbose "Install-NSPModule: installing '$moduleName'..." Install-Module @installParams } } } |