Public/Invoke-AsAdmin.ps1
|
#Requires -Version 5.1 <# .SYNOPSIS Launches an application with elevated privileges through the MakeMeAdminCLI service. .DESCRIPTION The Invoke-AsAdmin cmdlet launches an application with elevation by routing the request through the SYSTEM service. The service uses ServiceUI.exe to display the process on the user's interactive desktop session, bypassing UAC entirely. The user must have an active MakeMeAdminCLI elevation session (via Add-TempAdmin) before using this cmdlet. If the user is not currently elevated, the cmdlet will fail with a message suggesting Add-TempAdmin. .NOTES Author: MakeMeAdminCLI Version: 2.0.0 #> function Invoke-AsAdmin { <# .SYNOPSIS Launches an application with elevated privileges through the MakeMeAdminCLI service. .DESCRIPTION Routes process launching through the SYSTEM service using ServiceUI.exe. The service launches the process directly, and ServiceUI.exe bridges it to the user's interactive desktop session. No UAC prompt is displayed. Requires an active MakeMeAdminCLI elevation session (run Add-TempAdmin first). Program names that are not full paths are resolved from the system PATH using Get-Command, so you can type common names like 'powershell', 'notepad', or 'cmd.exe'. .PARAMETER Program The executable name or full path of the program to launch with elevation. If not a full path, the cmdlet will attempt to resolve it from PATH. .PARAMETER ArgumentList Optional arguments to pass to the program being launched. .PARAMETER WorkingDirectory Sets the working directory for the launched process. If not specified, the current directory is used. .OUTPUTS PSCustomObject Returns a result object with Success (bool) and Message (string) properties indicating whether the process was launched. .EXAMPLE Invoke-AsAdmin powershell Launches an elevated PowerShell window on the user's desktop. No UAC prompt is displayed. .EXAMPLE Invoke-AsAdmin cmd.exe Launches an elevated Command Prompt window. .EXAMPLE Invoke-AsAdmin notepad "C:\Windows\System32\drivers\etc\hosts" Launches Notepad with elevation to edit the hosts file, passing the file path as an argument. .EXAMPLE runas msiexec '/i', 'C:\Installers\setup.msi' Uses the 'runas' alias to launch an MSI installer with elevation. .EXAMPLE Invoke-AsAdmin -Program cmd.exe -WorkingDirectory 'C:\Projects' Launches an elevated Command Prompt with the working directory set to C:\Projects. .LINK Add-TempAdmin Get-TempAdminStatus Remove-TempAdmin #> [CmdletBinding(SupportsShouldProcess)] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, Position = 0)] [ValidateNotNullOrEmpty()] [string]$Program, [Parameter(Position = 1, ValueFromRemainingArguments)] [string[]]$ArgumentList, [Parameter()] [ValidateNotNullOrEmpty()] [string]$WorkingDirectory ) begin { # Check if service is running if (-not (Test-ServiceRunning)) { Write-Error "MakeMeAdminCLI service is not running. Run 'Install-MakeMeAdminCLI' as administrator to start the service." return } } process { # Resolve the program path if not a full path $resolvedProgram = $Program if (-not [System.IO.Path]::IsPathRooted($Program)) { Write-Verbose "Resolving program '$Program' from PATH..." $command = Get-Command -Name $Program -CommandType Application -ErrorAction SilentlyContinue | Select-Object -First 1 if ($command) { $resolvedProgram = $command.Source Write-Verbose "Resolved to: $resolvedProgram" } else { Write-Error "Program '$Program' was not found. Verify that the program is installed and the name is correct, or provide a full path." return } } else { # Validate that the specified full path exists if (-not (Test-Path $resolvedProgram)) { Write-Error "The specified program path '$resolvedProgram' does not exist." return } Write-Verbose "Using specified path: $resolvedProgram" } # Validate working directory if specified if ($WorkingDirectory) { if (-not (Test-Path $WorkingDirectory -PathType Container)) { Write-Error "The specified working directory '$WorkingDirectory' does not exist." return } Write-Verbose "Working directory: $WorkingDirectory" } # Build the exec request $execRequest = @{ action = "exec" program = $resolvedProgram } if ($ArgumentList -and $ArgumentList.Count -gt 0) { $execRequest.arguments = $ArgumentList -join ' ' Write-Verbose "Arguments: $($execRequest.arguments)" } if ($WorkingDirectory) { $execRequest.workingDirectory = $WorkingDirectory } # Build description for ShouldProcess $processDescription = $resolvedProgram if ($ArgumentList) { $processDescription += " $($ArgumentList -join ' ')" } if ($PSCmdlet.ShouldProcess($processDescription, "Launch with elevation via MakeMeAdminCLI service")) { Write-Verbose "Sending exec request to service..." $response = Send-PipeRequest -Request $execRequest if ($null -eq $response) { $result = [PSCustomObject]@{ Success = $false Message = "Failed to communicate with MakeMeAdminCLI service." } Write-Error $result.Message return $result } $result = [PSCustomObject]@{ Success = [bool]$response.success Message = $response.message } if ($result.Success) { Write-Verbose "Process launched successfully via service." } else { Write-Error $result.Message } return $result } } } # Export the function Export-ModuleMember -Function 'Invoke-AsAdmin' |