Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix WinUtil's self-elevation when running winutil.ps1 without administrator #2823

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 49 additions & 21 deletions scripts/start.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
Version : #{replaceme}
#>

# Define the arguments for the WinUtil script
param (
[switch]$Debug,
[string]$Config,
Expand All @@ -17,12 +18,13 @@ if ($Debug) {
$DebugPreference = "Continue"
}

# Handle the -Config parameter
if ($Config) {
$PARAM_CONFIG = $Config
}

$PARAM_RUN = $false
# Handle the -Run switch
$PARAM_RUN = $false
if ($Run) {
Write-Host "Running config file tasks..."
$PARAM_RUN = $true
Expand All @@ -39,38 +41,64 @@ $sync.version = "#{replaceme}"
$sync.configs = @{}
$sync.ProcessRunning = $false

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Output "Winutil needs to be run as Administrator. Attempting to relaunch."
$argList = @()
# Store elevation status of the process
$isElevated = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

$PSBoundParameters.GetEnumerator() | ForEach-Object {
$argList += if ($_.Value -is [switch] -and $_.Value) {
"-$($_.Key)"
} elseif ($_.Value) {
"-$($_.Key) `"$($_.Value)`""
}
}
# Initialize the arguments list array
$argsList = @()

$script = if ($MyInvocation.MyCommand.Path) {
"& { & '$($MyInvocation.MyCommand.Path)' $argList }"
} else {
"iex '& { $(irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1) } $argList'"
# Add the passed parameters to $argsList
$PSBoundParameters.GetEnumerator() | ForEach-Object {
$argsList += if ($_.Value -is [switch] -and $_.Value) {
"-$($_.Key)"
} elseif ($_.Value) {
"-$($_.Key) `"$($_.Value)`""
}
}

# Set the download URL for the latest release
$downloadURL = "https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1"

# Download the WinUtil script to '$env:TEMP'
try {
Write-Host "Downloading latest stable WinUtil version..." -ForegroundColor Green
Invoke-RestMethod $downloadURL -OutFile "$env:TEMP\winutil.ps1"
} catch {
Write-Host "Error downloading WinUtil: $_" -ForegroundColor Red
break
}

$powershellcmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" }
$processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { $powershellcmd }
# Setup the commands used to launch the script
$powershellCmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh.exe" } else { "powershell.exe" }
$processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { $powershellCmd }

Start-Process $processCmd -ArgumentList "$powershellcmd -ExecutionPolicy Bypass -NoProfile -Command $script" -Verb RunAs
# Setup the script's launch arguments
$launchArguments = "-ExecutionPolicy Bypass -NoProfile -File `"$env:TEMP\winutil.ps1`" $argsList"
if ($processCmd -ne $powershellCmd) {
$launchArguments = "$powershellCmd $launchArguments"
}

# Relaunch the script as administrator if necessary
try {
if (!$isElevated) {
Write-Host "WinUtil is not running as administrator. Relaunching..." -ForegroundColor DarkCyan
Start-Process $processCmd -ArgumentList $launchArguments -Verb RunAs
} else {
Write-Host "Running the latest stable version of WinUtil." -ForegroundColor DarkCyan
Start-Process $processCmd -ArgumentList $launchArguments
}
break
} catch {
Write-Host "Error launching WinUtil: $_" -ForegroundColor Red
break
}

# Start WinUtil transcript logging
$dateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"

$logdir = "$env:localappdata\winutil\logs"
[System.IO.Directory]::CreateDirectory("$logdir") | Out-Null
Start-Transcript -Path "$logdir\winutil_$dateTime.log" -Append -NoClobber | Out-Null

# Set PowerShell window title
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Admin)"
clear-host
$Host.UI.RawUI.WindowTitle = $MyInvocation.MyCommand.Definition + "(Admin)"
Clear-Host