winutil/scripts/launcher.ps1

189 lines
6.5 KiB
PowerShell
Raw Normal View History

2024-08-20 17:27:44 -05:00
# Copyright (c) Chris Titus.
# Licensed under the MIT License.
<#
.Synopsis
Launch winutil with administrative privileges.
.DESCRIPTION
This script is used to launch winutil with administrative privileges.
It is intended to be deployed at https://christitus.com/win.
This script will check if the current user is an Administrator.
If the current user is an Administrator, it will run winutil in the current session.
If not, it will run winutil with elevated privileges in a new session.
.Parameter Preview
Launch the preview version of winutil.
.Parameter NoExit
Do not exit the newly spawned powershell after running the script. (for-debugging purposes)
.EXAMPLE
Launch the latest release of winutil.
.\launcher.ps1
.EXAMPLE
Launch the latest release of winutil. (one-liner)
Invoke-Expression "& { $(Invoke-RestMethod 'https://christitus.com/win') }"
iex "& { $(iwr 'https://christitus.com/win') }"
2024-08-20 17:27:44 -05:00
.EXAMPLE
Launch the latest preview release of winutil.
.\launcher.ps1 -preview
.EXAMPLE
Launch the latest preview release of winutil. (one-liner)
Invoke-Expression "& { $(Invoke-RestMethod 'https://christitus.com/win') } -preview"
iex "& { $(iwr 'https://christitus.com/win') } -preview"
2024-08-20 17:27:44 -05:00
#>
[CmdletBinding()]
param(
[Parameter()]
[switch] $Preview,
[Parameter()]
[switch] $NoExit
)
& {
$ErrorActionPreference = "Stop"
$IsAdmin = [bool](
[Security.Principal.WindowsPrincipal](
[Security.Principal.WindowsIdentity]::GetCurrent()
)
).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator
)
# Enable TLSv1.2 for compatibility with older clients for current session
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
2024-08-21 04:48:35 -05:00
# Function to redirect to the latest pre-release version
function Get-Latest-PreRelease-Url {
2024-08-21 05:45:51 -05:00
$repo = 'ChrisTitusTech/winutil'
2024-08-21 04:48:35 -05:00
2024-08-21 05:45:51 -05:00
$latestPreRelease = $null
2024-08-21 04:48:35 -05:00
2024-08-21 05:45:51 -05:00
try {
$releases = Invoke-RestMethod -Uri "https://api.github.com/repos/$repo/releases"
$latestRelease = $releases | Where-Object {$_.prerelease -eq $true} | Select-Object -First 1
$latestPreRelease = $latestRelease.tag_name
} catch {
Write-Host "Error fetching release data: $_" -ForegroundColor Red
$latestPreRelease = $latestRelease.tag_name
2024-08-21 04:48:35 -05:00
}
2024-08-21 05:45:51 -05:00
if ($latestPreRelease) {
return "https://github.com/$repo/releases/download/$latestPreRelease/winutil.ps1"
} else {
Write-Host 'Unable to determine latest pre-release version.' -ForegroundColor Red
Write-Host "Using latest Stable Release"
return "https://github.com/$repo/releases/latest/download/winutil.ps1"
}
2024-08-21 04:48:35 -05:00
}
2024-08-20 17:27:44 -05:00
$url = if (-not $Preview) {
2024-08-21 04:48:35 -05:00
# This must be pointing to the latest stable release (Chris-Hosted)
2024-08-21 05:31:44 -05:00
# FIXME: change me to the below url and host me here
"https://christitus.com/win"
# "https://christitus.com/win/stable"
2024-08-20 17:27:44 -05:00
} else {
2024-08-21 04:48:35 -05:00
# This must be pointing to the latest pre-release or the release (GitHub releases)
Get-Latest-PreRelease-Url
2024-08-20 17:27:44 -05:00
}
if ($IsAdmin) {
# If running as Administrator, run in the current session
& {
# Using iwr to show download progress
2024-08-21 05:45:51 -05:00
# TODO(psyirius): Check the output of Invoke-WebRequest and handle errors
2024-08-20 17:27:44 -05:00
Invoke-WebRequest $url | Invoke-Expression
}
exit
}
#============================================================================
# If not running as Administrator, run the script with elevated privileges
#============================================================================
# Use the modern 'PowerShell' if available, otherwise use 'Windows PowerShell'
$PwshExecutable = if (Get-Command "pwsh" -ErrorAction SilentlyContinue) {
"pwsh.exe"
}
else {
"powershell.exe"
}
# Using iwr to show download progress
2024-08-21 05:45:51 -05:00
# TODO(psyirius): Check the output of Invoke-WebRequest and handle errors
2024-08-20 17:27:44 -05:00
$PwshCommand = "iwr '$url' | iex"
# Elevate the script
$PwshArgList = @(
"-NoLogo", # Don't print PowerShell header in CLI
"-NoProfile", # Don't load PowerShell profile
"-Command", $PwshCommand # Command to execute
)
if ($NoExit) {
$PwshArgList = @(
"-NoExit" # Don't exit after running the command
) + $PwshArgList
}
$PwshArgList = $PwshArgList | ForEach-Object { "`"$_`"" }
$WorkingDirectory = Get-Location
$PwshExecutable = if (Get-Command "pwsh" -ErrorAction SilentlyContinue) {
"pwsh.exe"
}
else {
"powershell.exe"
}
$ProcessParameters = @{
FilePath = $PwshExecutable;
ArgumentList = $PwshArgList;
WorkingDirectory = $WorkingDirectory;
Verb = 'RunAs';
PassThru = $true;
}
# Use 'wt' if available
if (Get-Command "wt" -ErrorAction SilentlyContinue) {
$WtArgList = @(
"new-tab",
$ProcessParameters.FilePath
) + $PwshArgList
$ProcessParameters.FilePath = "wt.exe"
$ProcessParameters.ArgumentList = $WtArgList
}
$process = $null
try {
$process = Start-Process @ProcessParameters
}
catch {
$exception = $_.Exception
# Optional: Check for specific error messages or types
if ($exception.Message -like "*The operation was canceled by the user*") {
Write-Host "===========================================" -Foregroundcolor Red
Write-Host "---- This must be run as Administrator ----" -Foregroundcolor Red
Write-Host "------ Click 'Yes' in the UAC Prompt ------" -Foregroundcolor Red
Write-Host "------------------ (OR) -------------------" -Foregroundcolor Red
Write-Host "-- Right-Click Start -> Terminal(Admin) ---" -Foregroundcolor Red
Write-Host "===========================================" -Foregroundcolor Red
}
else {
$ErrorMessage = @(
"An unexpected error occurred:",
($exception.Message -split ":" | Select-Object -Index 1).Trim()
) -join "`n"
Write-Host $ErrorMessage -Foregroundcolor Red
$process.Kill()
}
}
finally {
exit
}
}