Private/Test-ElevationCapability.ps1
|
function Test-ElevationCapability { <# .SYNOPSIS Decides, before anything is attempted, whether this run can become Administrator. .DESCRIPTION Returns IsElevated, CanElevate, Reason, and Caution. Only two conditions refuse outright, and both are certain rather than probable: UAC switched off, and a packaged PowerShell with no MSI build beside it. In each case Windows will not grant elevation to anybody, so raising a prompt would waste a person's time and then report the failure as though they had declined it. Not being in the local Administrators group is a Caution, not a refusal. Machines running a privilege-management broker -- BeyondTrust, CyberArk EPM, Admin By Request and others -- keep the account out of that group and elevate it anyway, often per application, so membership does not settle whether elevation is available. A prompt that then fails costs one refusal, which Invoke-SelfElevation reports and Get-ElevationPolicyNote explains. .EXAMPLE $elevation = Test-ElevationCapability if (-not $elevation.CanElevate) { Write-Warning $elevation.Reason } #> [CmdletBinding()] [OutputType([pscustomobject])] param() if (Test-IsAdministrator) { return [pscustomobject]@{ IsElevated = $true CanElevate = $true Reason = 'Already running as Administrator.' Caution = $null } } if (-not (Test-UacEnabled)) { return [pscustomobject]@{ IsElevated = $false CanElevate = $false Reason = 'UAC (EnableLUA) is disabled, so this session cannot request elevation. Sign in with an elevated session, or use -SkipElevation.' Caution = $null } } # An MSIX PowerShell cannot be elevated at all: Windows does not run packaged # apps elevated, and the app execution alias that also reaches it is a # zero-byte reparse point rather than a program. The result does not depend # on who is asking. The MSI build, if it is installed alongside, can # elevate, and Invoke-SelfElevation relaunches through it. if ((Test-PackagedProcess) -and -not (Test-Path -LiteralPath (Join-Path $env:ProgramFiles 'PowerShell\7\pwsh.exe'))) { return [pscustomobject]@{ IsElevated = $false CanElevate = $false Reason = 'This session is the MSIX build of PowerShell (the Store and winget default), and Windows does not run packaged apps elevated. Install the MSI build with "winget install --id Microsoft.PowerShell --exact --source winget --installer-type wix", start an elevated session yourself, or use -SkipElevation.' Caution = $null } } # $false is a definite "not in the group" and is worth saying. $null means # the answer could not be determined -- a filtered token hides the SID -- # and neither is grounds for refusing. $caution = $null if ((Test-AdministratorGroupMember) -eq $false) { $caution = 'This account is not in the local Administrators group, so the prompt may be refused. Machines using a privilege-management broker elevate without that membership, so it is worth attempting. If it fails, -SkipElevation runs the steps that do not need admin.' } [pscustomobject]@{ IsElevated = $false CanElevate = $true Reason = 'Elevation can be requested.' Caution = $caution } } |