Update-PowerShellCore.ps1
<#
.SYNOPSIS Update PowerShell Core to the specified version. #> function Update-PowerShellCore { [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Default')] param ( [Parameter(ParameterSetName = 'Default')] [Switch]$Latest, [Parameter(ParameterSetName = 'Version')] [SemVer]$Version, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Version')] [Switch]$Silent, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Version')] [hashtable]$InstallOptions, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Version')] [Switch]$NotExitConsole, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Version')] [Switch]$IncludePreRelease = $false, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Version')] [string]$Token, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Version')] [Switch]$Force ) # currently, supports windows only if (-not ($IsWindows -or $IsMacOS)) { Write-Warning $Messages.Update_PowerShellCore_001 return } # find update version $newVersion = $null $specifiedToken = $Token if ([string]::IsNullOrEmpty($specifiedToken)) { $specifiedToken = GetPowerShellCoreApiTokenImpl } switch ($PSCmdlet.ParameterSetName) { 'Version' { $newVersion = Find-PowerShellCore -Version $Version -Token $specifiedToken -IncludePreRelease:$IncludePreRelease } Default { $newVersion = Find-PowerShellCore -Latest -Token $specifiedToken -IncludePreRelease:$IncludePreRelease } } if ($null -eq $newVersion) { Write-Warning $Messages.Update_PowerShellCore_002 return } if ($newVersion.Version -lt $PSVersionTable.PSVersion -and (-not $Force)) { Write-Warning $Messages.Update_PowerShellCore_003 return } if ($newVersion.Version -eq $PSVersionTable.PSVersion -and (-not $Force)) { Write-Warning $Messages.Update_PowerShellCore_004 return } WriteInfo ($Messages.Update_PowerShellCore_005 -f $newVersion.Version) # Download asset $downloadURL = @() if ($IsWindows) { $downloadURL = GetMSIDownloadUrl -Release $newVersion } elseif ($IsMacOS) { $downloadURL = GetPKGDownloadUrl -Release $newVersion } else { # TODO : update Write-Warning $Messages.Update_PowerShellCore_001 return } if (@($downloadURL).Length -eq 0) { Write-Error $Messages.Update_PowerShellCore_006 return } if (@($downloadURL).Length -gt 1) { Write-Warning $Messages.Update_PowerShellCore_007 return } $fileName = Join-Path -Path ([IO.Path]::GetTempPath()) -ChildPath $downloadURL.split("/")[-1] if ($PSCmdlet.ShouldProcess('Download asset')) { DownloadFile -Uri $downloadURL -OutFile $fileName -Token $specifiedToken } else { Write-Warning $Messages.Update_PowerShellCore_008 } # Install WriteInfo ($Messages.Update_PowerShellCore_009 -f $newVersion.Version) $shouldProcess = $PSCmdlet.ShouldProcess('Install PowerShell Core') if (-not $shouldProcess) { Write-Warning $Messages.Update_PowerShellCore_010 } if ($IsWindows) { InstallMSI -NewVersion $newVersion.Version -MsiFile $fileName -Silent $Silent -InstallOptions $InstallOptions -ShouldProcess $shouldProcess } elseif ($IsMacOS) { InstallPKG -PkgFile $fileName -Silent $Silent -InstallOptions $InstallOptions -ShouldProcess $shouldProcess } else { # TODO : implement Write-Warning $Messages.Update_PowerShellCore_001 return } # Exit PowerShel Console if ((-not $NotExitConsole) -or $Silent) { WriteInfo $Messages.Update_PowerShellCore_011 Start-Sleep -Seconds 1 exit } } function GetMSIDownloadUrl ([PowerShellCoreRelease]$Release) { if (IsCurrentProcess64bit) { return ($Release.Assets | Where-Object { $_.Architecture -eq [AssetArchtectures]::MSI_WIN64 }).DownloadUrl.OriginalString } return ($Release.Assets | Where-Object { $_.Architecture -eq [AssetArchtectures]::MSI_WIN32 }).DownloadUrl.OriginalString } function GetPKGDownloadUrl ([PowerShellCoreRelease]$Release) { switch (GetDarwinVersion) { 15 { # OSX El Capitan (10.11) $asset = $Release.Assets | Where-Object { $_.Architecture -eq [AssetArchtectures]::PKG_OSX1011 } if ($null -ne $asset) { return $asset.DownloadUrl.OriginalString } return } {$_ -in (16, 17)} { # macOS Sierra (10.12) # macOS High Sierra (10.13) $asset = $Release.Assets | Where-Object { $_.Architecture -eq [AssetArchtectures]::PKG_OSX } if ($null -ne $asset) { return $asset.DownloadUrl.OriginalString } $asset = $Release.Assets | Where-Object { $_.Architecture -eq [AssetArchtectures]::PKG_OSX1012 } if ($null -ne $asset) { return $asset.DownloadUrl.OriginalString } return } Default { $asset = $Release.Assets | Where-Object { $_.Architecture -eq [AssetArchtectures]::PKG_OSX } if ($null -ne $asset) { return $asset.DownloadUrl.OriginalString } return } } } function GetDarwinVersion () { return [System.Environment]::OSVersion.Version.Major } function InstallMSI ([SemVer]$NewVersion, [string]$MsiFile, [bool]$Silent, [hashtable]$InstallOptions, [bool]$ShouldProcess) { $args = @('/i', $MsiFile) if ($Silent) { $args += '/passive' } # Set the default install options if not specified. # Note : These options are valid only for silent installation. if ($null -eq $InstallOptions) { if ($NewVersion -ge '6.1.0-preview.2') { $InstallOptions = @{ ADD_PATH = 1; REGISTER_MANIFEST = 1; } } } if ($null -ne $InstallOptions) { # Currently following parameters are allowed. # INSTALLFOLDER = "C:\PowerShell\" : Install folder # ADD_PATH = [0|1] : Add PowerShell to Path Environment Variable # REGISTER_MANIFEST = [0|1] : Register Windows Event Logging Manifest # ENABLE_PSREMOTING = [0|1] : Enable PowerShell remoting # ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL = [0|1] : Add 'Open here' context menus to Explorer foreach ($key in $InstallOptions.Keys) { $args += ('{0}={1}' -f $key, $InstallOptions[$key]) } } WriteInfo ('msiexec.exe {0}' -f ($args -join ' ')) if ($ShouldProcess) { Start-Process -FilePath 'msiexec.exe' -ArgumentList $args } } function InstallPKG ([string]$PkgFile, [bool]$Silent, [hashtable]$InstallOptions, [bool]$ShouldProcess) { $targetVolume = '/' if ($null -ne $InstallOptions) { # Install volume if ($InstallOptions.ContainsKey('target')) { $targetVolume = $InstallOptions['target'] } } if ($Silent) { WriteInfo "/usr/bin/sudo /usr/sbin/installer -pkg ""$PkgFile"" -target $targetVolume" if ($ShouldProcess) { /usr/bin/sudo /usr/sbin/installer -pkg "$PkgFile" -target $targetVolume } return } WriteInfo "Invoke-Item $PkgFile" if ($ShouldProcess) { Invoke-Item $PkgFile } } |