34ea1eb4b2
- Implemented DefaultBrowser feature to notify users when the default browser does not match the configured app. - Added DynamicLock feature to disable Dynamic Lock while connected to a specific network and re-enable it after disconnecting. - Created SandwichReminder feature to prompt users to order a sandwich during work hours based on network and time settings. Introduced helper libraries for configuration, elevation, logging, network utilities, and toast notifications. - Config.ps1: Added functions for reading and writing configuration and state files. - Elevation.ps1: Added functions to check for administrator privileges and request elevation. - Logging.ps1: Implemented a shared logging utility for consistent logging across features. - NetworkUtils.ps1: Added a function to check for DNS suffix connectivity. - ToastHelper.ps1: Created a helper for displaying Windows toast notifications. Implemented runner.ps1 as the main entry point for executing features based on configuration.
161 lines
4.6 KiB
PowerShell
161 lines
4.6 KiB
PowerShell
# Elevation.ps1 — elevation helpers
|
|
# Requires $InternalRoot to be defined in the calling script's scope before dot-sourcing.
|
|
|
|
function Test-Administrator {
|
|
<#
|
|
.SYNOPSIS
|
|
Returns $true if the current process has administrator privileges.
|
|
#>
|
|
$id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
|
|
$principal = New-Object System.Security.Principal.WindowsPrincipal($id)
|
|
return $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
}
|
|
|
|
function Request-Elevation {
|
|
<#
|
|
.SYNOPSIS
|
|
If not running as admin, spawns an elevated PowerShell process to re-run the current script.
|
|
The calling script should exit after this call (the elevated process takes over).
|
|
Returns $true if elevation was requested (parent process should exit).
|
|
Returns $false if already elevated.
|
|
#>
|
|
param(
|
|
[Parameter(Mandatory)]
|
|
[string]$ScriptPath,
|
|
|
|
[string[]]$ScriptArguments = @(),
|
|
|
|
[string]$BootstrapLogPath = $null,
|
|
|
|
[switch]$Wait,
|
|
|
|
[int]$TimeoutSeconds = 120
|
|
)
|
|
|
|
if (Test-Administrator) {
|
|
return @{
|
|
Requested = $false
|
|
Completed = $true
|
|
ExitCode = 0
|
|
Error = $null
|
|
}
|
|
}
|
|
|
|
Write-Host ''
|
|
Write-Host ' Elevation required. Requesting administrator privileges...' -ForegroundColor Yellow
|
|
Write-Host ''
|
|
|
|
try {
|
|
$logPath = if ($BootstrapLogPath) {
|
|
$BootstrapLogPath
|
|
} else {
|
|
Join-Path (Split-Path $ScriptPath -Parent) 'internal\data\logs\elevated-bootstrap.log'
|
|
}
|
|
|
|
$scriptPathEsc = $ScriptPath.Replace("'", "''")
|
|
$logPathEsc = $logPath.Replace("'", "''")
|
|
|
|
$argInvocationText = if ($ScriptArguments.Count -gt 0) {
|
|
($ScriptArguments | ForEach-Object {
|
|
# Keep parameter-like tokens (e.g. -AutoRegisterRunner) unquoted so
|
|
# PowerShell binds them as named/switch parameters.
|
|
if ($_ -match '^-[A-Za-z]') {
|
|
$_
|
|
}
|
|
else {
|
|
"'" + $_.Replace("'", "''") + "'"
|
|
}
|
|
}) -join ' '
|
|
}
|
|
else {
|
|
''
|
|
}
|
|
|
|
$invokeLine = if ([string]::IsNullOrWhiteSpace($argInvocationText)) {
|
|
"& '$scriptPathEsc'"
|
|
}
|
|
else {
|
|
"& '$scriptPathEsc' $argInvocationText"
|
|
}
|
|
|
|
$bootstrap = @"
|
|
`$ErrorActionPreference = 'Stop'
|
|
function Write-BootstrapLog([string]`$message) {
|
|
try {
|
|
`$dir = Split-Path '$logPathEsc' -Parent
|
|
if (-not (Test-Path `$dir)) {
|
|
New-Item -Path `$dir -ItemType Directory -Force | Out-Null
|
|
}
|
|
`$line = "[{0}] {1}" -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), `$message
|
|
Add-Content -Path '$logPathEsc' -Value `$line -Encoding UTF8
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
Write-BootstrapLog "Elevated bootstrap started. ScriptPath=$scriptPathEsc"
|
|
try {
|
|
$invokeLine
|
|
`$code = if (`$LASTEXITCODE -is [int]) { `$LASTEXITCODE } else { 0 }
|
|
Write-BootstrapLog "Elevated bootstrap finished with ExitCode=`$code"
|
|
exit `$code
|
|
}
|
|
catch {
|
|
Write-BootstrapLog ("Elevated bootstrap unhandled error: " + `$_.Exception.Message)
|
|
Write-BootstrapLog ("Stack: " + `$_.ScriptStackTrace)
|
|
exit 1
|
|
}
|
|
"@
|
|
|
|
$encoded = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($bootstrap))
|
|
|
|
$proc = Start-Process `
|
|
-FilePath 'powershell.exe' `
|
|
-ArgumentList "-NoProfile -ExecutionPolicy Bypass -EncodedCommand $encoded" `
|
|
-Verb RunAs `
|
|
-PassThru `
|
|
-ErrorAction Stop
|
|
|
|
if ($Wait) {
|
|
if ($TimeoutSeconds -gt 0) {
|
|
$null = $proc.WaitForExit($TimeoutSeconds * 1000)
|
|
}
|
|
else {
|
|
$proc.WaitForExit()
|
|
}
|
|
|
|
if (-not $proc.HasExited) {
|
|
return @{
|
|
Requested = $true
|
|
Completed = $false
|
|
ExitCode = $null
|
|
Error = $null
|
|
}
|
|
}
|
|
|
|
return @{
|
|
Requested = $true
|
|
Completed = $true
|
|
ExitCode = $proc.ExitCode
|
|
Error = $null
|
|
}
|
|
}
|
|
|
|
return @{
|
|
Requested = $true
|
|
Completed = $null
|
|
ExitCode = $null
|
|
Error = $null
|
|
}
|
|
}
|
|
catch {
|
|
Write-Host " Failed to request elevation: $_" -ForegroundColor Red
|
|
return @{
|
|
Requested = $false
|
|
Completed = $false
|
|
ExitCode = $null
|
|
Error = $_
|
|
}
|
|
}
|
|
}
|
|
|