private/Install-SoftwareMicrosoftPwsh.ps1

function Install-SoftwareMicrosoftPwsh {
    <#
    .SYNOPSIS
        Installs Microsoft PowerShell using winget
 
    .DESCRIPTION
        Detects pwsh.exe and installs the package configured in OSDeploy module metadata when
        the command is unavailable. The default package is Microsoft.PowerShell. The function
        passes installer overrides that enable PATH registration, Microsoft Update, remoting,
        manifest registration, and Explorer context menu integration unless metadata supplies
        a different override.
 
        After installation, the function refreshes the current process environment and locates
        pwsh.exe. WhatIf and Confirm apply to the winget installation.
 
    .EXAMPLE
        PS> Install-SoftwareMicrosoftPwsh
 
        Installs the configured PowerShell package when pwsh.exe is unavailable.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        System.String. Returns native winget output when PowerShell is installed.
 
        System.Management.Automation.PSCustomObject. Returns package, version, command path,
        installer override, winget path, and operation status details.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 1.0.0
        Date: 2026-08-28
 
        Requires Windows and winget. The installed package ID and installer override can be
        supplied by $global:OSDeployModule.Software.pwsh.
 
    .LINK
        https://learn.microsoft.com/en-us/powershell/scripting/install/install-powershell-on-windows
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    [OutputType([pscustomobject])]
    param (
    )

    if (-not $IsWindows) {
        throw "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] Install-SoftwareMicrosoftPwsh 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)] 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)] 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
    }
}