Run as an Administrator

Run as an Administrator

When building out scripts, we must consider different ways they will fail. One of the ways I have seen them fail is through the UAC of a computer. The script needs to be run by an administrator. The question is, How do you check if you are running as an Administrator? Here are the two ways I like doing this check.

The Comment Requires it

Powershell has a handy little feature called #Requires. The idea is simple, you place a #Requires at the top of your script. I suggest looking at the official documentation because there is a lot you can do. As of PowerShell 4, #Requires -RunAsAdministrator is a thing. Having this requirement at the start will tell the shell to fail out.

Powershell Checks

The next method is using PowerShell to check if the current shell is administrator through the security protocols of windows. This method only uses two lines of code to produce a true or false statement. Thus, it’s best to keep it inside a function for later use.

function Test-Administrator {  
    $user = [Security.Principal.WindowsIdentity]::GetCurrent();
    (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)  
}

The first part is grabbing the current user of the terminal. We store that information and then create a new object. We create a security principal windows Principal object. Here we can check what the user’s role was and if it was the built-in administrator role.

There we have it, how to test if a script is running as admin.

Taking it an additional step forward

Let’s take this script to the next level by adding a restart in admin mode. The following code can be used to restart any terminal session into admin mode. However, it breaks in vs code.

$CurrentProcess = [System.Diagnostics.Process]::GetCurrentProcess()
$CurrentProcessID = New-Object System.Diagnostics.ProcessStartInfo $CurrentProcess.Path
$CurrentProcessID.Arguments = '-file ' + $script:MyInvocation.MyCommand.Path
$CurrentProcessID.Verb = "runas"
[System.Diagnostics.Process]::Start($CurrentProcessID) | Out-Null
[Environment]::Exit(0)

The first part of this script catches the current process information. Then we pass that information into a new system diagnostic object to find the process start information. Next, we change the arguments to start a file and the current script’s name. We also set the verb to runas to trigger a run as administrator call. Then we start the process that we created and close to this current process. Afterward, the script will run as admin.

The Script – Run as an Administrator

function Test-Administrator {  
    $user = [Security.Principal.WindowsIdentity]::GetCurrent();
    (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)  
}

function Invoke-RunAsAdministrator {
    [cmdletbinding()]
    param (
        [parameter(Mandatory = $true)][boolean]$Admin
    )

    if (!$Admin) {
        $CurrentProcess = [System.Diagnostics.Process]::GetCurrentProcess()
        $CurrentProcessID = New-Object System.Diagnostics.ProcessStartInfo $CurrentProcess.Path
        $CurrentProcessID.Arguments = '-file ' + $script:MyInvocation.MyCommand.Path
        $CurrentProcessID.Verb = "runas"
        [System.Diagnostics.Process]::Start($CurrentProcessID) | Out-Null
        [Environment]::Exit(0)
    }
    else {
        Write-Verbose "Admin Rights Present"
    }
}

Invoke-RunAsAdministrator -Admin (Test-Administrator)
Read-Host "Press any key to continue"

Now to make this more practical. Add the above code to the Citrix Workspace Installer. Then wrap the script up into an EXE with the PS1toExe program. Finally, add the little script program to your toolbox for future use.

Image by MidJourney AI