private/Software/Install-MicrosoftPwsh.ps1
|
<#
.SYNOPSIS Installs Microsoft PowerShell 7.6 using winget. .DESCRIPTION Ensures PowerShell 7.6 is available by installing it with winget when needed, using recommended installer override switches. .OUTPUTS System.Management.Automation.PSCustomObject .EXAMPLE Install-MicrosoftPwsh Installs PowerShell 7.6 if it is not already available. .NOTES Author: David Segura Company: Recast Software This function is supported only on Windows and requires winget. .LINK https://learn.microsoft.com/en-us/powershell/scripting/install/install-powershell-on-windows?view=powershell-7.6 Change Summary: #> function Install-MicrosoftPwsh { [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] [OutputType([pscustomobject])] param ( ) if (-not $IsWindows) { throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Install-MicrosoftPwsh is supported only on Windows." } $winget = Get-Command -Name 'winget' -ErrorAction SilentlyContinue if (-not $winget) { throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] winget is required but was not found. Install App Installer from Microsoft Store and try again." } $packageId = 'Microsoft.PowerShell' $installerOverride = '/passive ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL=1 ENABLE_PSREMOTING=1 REGISTER_MANIFEST=1 USE_MU=1 ENABLE_MU=1 ADD_PATH=1' if ($global:OSDeployModule -and $global:OSDeployModule.Software.pwsh) { if ($global:OSDeployModule.Software.pwsh.wingetid) { $packageId = [string]$global:OSDeployModule.Software.pwsh.wingetid } if ($global:OSDeployModule.Software.pwsh.override) { $installerOverride = [string]$global:OSDeployModule.Software.pwsh.override } } $existingPwsh = Get-Command -Name 'pwsh' -ErrorAction SilentlyContinue $wasInstalled = $false $skippedInstall = $false if (-not $existingPwsh) { if ($PSCmdlet.ShouldProcess($packageId, 'Install PowerShell 7 using winget')) { Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] PowerShell 7 is not installed. Installing with winget..." -ForegroundColor DarkGray & $winget.Source install --id $packageId -e -h --override $installerOverride --accept-source-agreements --accept-package-agreements if ($LASTEXITCODE -ne 0) { throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] PowerShell 7 installation failed with exit code $LASTEXITCODE." } Update-OSDeploySessionEnvironment $existingPwsh = Get-Command -Name 'pwsh' -ErrorAction SilentlyContinue if (-not $existingPwsh) { $fallbackPwshPath = Join-Path -Path ${env:ProgramFiles} -ChildPath 'PowerShell\7\pwsh.exe' if (Test-Path -Path $fallbackPwshPath) { $existingPwsh = Get-Command -Name $fallbackPwshPath -ErrorAction SilentlyContinue } } if (-not $existingPwsh) { throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] PowerShell 7 was installed but pwsh was not found in PATH. Open a new PowerShell session and run the command again." } $wasInstalled = $true } else { $skippedInstall = $true } } else { $installedVersion = (& $existingPwsh.Source -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()').Trim() Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] PowerShell 7 is already installed: $installedVersion" -ForegroundColor Green } $finalVersion = $null if ($existingPwsh) { $finalVersion = (& $existingPwsh.Source -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()').Trim() } [pscustomobject]@{ ProductId = $packageId Version = $finalVersion WasInstalled = $wasInstalled CommandPath = if ($existingPwsh) { $existingPwsh.Source } else { $null } WingetCommand = $winget.Source InstallerOverride = $installerOverride SkippedInstall = $skippedInstall } } |