6

I'm working with a GitHub action step on a Windows runner. One of the requirements of the executable I'm trying to run is that it can't be run as an administrator.

It's there any way I can create and become a different user to the default administrator account that actions use on Windows runners?

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
Alexander Trauzzi
  • 7,277
  • 13
  • 68
  • 112

2 Answers2

6

Inspired by the link in VonC's answer I went down a few rabbit holes over the past few days. TLDR:

  • Options using runas, including Powershell Start-Process, don't work and I'm convinced can't work.
  • An option using paexec, an open source version of SysInternals psexec, effectively accomplishes the task of executing the program under another user's login. The program itself needs to output to a log to be read later, as no program output is received from the paexec command itself. It is likely psexec would also work; view the EULA/license for both to decide which you prefer.

This answer does not check exit codes, which would be needed to read the output files on failure. VonC's answer gives some alternatives for that part of the process.

Here's the working GHA steps using PAExec to run "mvnw test" on my project:

- name: Download PaExec
  run: |
    choco install wget --no-progress 
    wget -q https://www.poweradmin.com/paexec/paexec.exe -P C:\Windows\System32
- name: Create new user
  run: |
    net user foo p@ssw0rd /add
- name: Test with Maven
  run: |
    paexec -u foo -p p@ssw0rd -lo $pwd\output.txt -w $pwd $pwd\mvnw.cmd test -l $pwd\mvntest.txt 
    cat output.txt
    cat mvntest.txt

I suspect it would also work with psexec (without the -lo switch, but with an -accepteula switch).


Earlier answer to preserve investigative steps:

I'm convinced such a thing is possible but elusive. I've determined it's possible to lower permission and execute commands if one doesn't need the output from stdout/stderr, but in my use case (CI testing) I need that output.

The quoted Start-Process -Verb Runas 'yourUser' -Wait is an interesting start to a long investigation. GitHub Actions on Windows runners are actually executing in a PowerShell environment so this can be called directly. However, some notes:

  • Runas actually elevates a process, the corresponding RunasUser lowers the elevation, the goal of this exercise
  • I thought I got it working with RunasUser, but the command swallows all output to stderr/stdout, and later research indicated that when running as Administrator with UAC disabled, the permissions restriction simply doesn't apply, so running as another user is essentially the only option.
    • I've tried various workarounds to try to extract the output, without success.
    • The closest I got was this, which provides output:
$process = Start-Process -FilePath mvnw.cmd -ArgumentList "clean test -B" -Wait -RedirectStandardOutput stdout.txt -RedirectStandardError stderr.txt
cat stderr.txt
cat stdout.txt
$process.ExitCode

However, adding -Verb RunasUser results in an error message:

Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used together or an insufficient number of parameters were provided.

I haven't been able to combine that verb and the output printing simultaneously. Answers to this question outline various other options which I've been unsuccessful in applying. It seems that with UAC disabled, de-elevating without assigning to another user doesn't work.

Another option at the link in VonC's answer suggested using psexec from the Windows Sysinternals. This also got me tantalizingly close to a solution, but the lack of output failed it. (Note that I've later discovered I can output internally and collect the log later.)

I was able to download and install psexec through the github action and attempt to use it, like this:

- name: Download Sysinternals PsTools
  run: |
    choco install -y --no-progress sysinternals
- name: Create batch file to wrap execution
  run: |
    echo "cd $pwd" > mvnTest.bat
    echo "mvnw.cmd clean test -B >CON:" >> mvnTest.bat
- name: Test with Maven
  run: |
    PsExec64 -accepteula -l $pwd\mvnTest.bat

I think I was able to execute with lower permissions (and could have executed as another user easily) but only without accessing program output.

  • The program appears designed to execute commands remotely on another server
  • You can execute locally without output
  • You can get output by executing via localhost or 127.0.0.1; however, this limits you to only using built-in commands and doesn't work well with batch files
Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
1

That does not seem supported at the moment.

As this discussion (Oct. 2022) illustrates:

This is an issue we are facing on the windows-latest runner where all commands are run as admin.

It seems like the correct approach to use would be:

net user "username" "<password>" /add
runas /user:username ".\bin\program.bat"

But runas is designed to prompt for password input and there is no way to supply a password. passwordless is also unsupported.

You can try one of the methods proposed in "Run as a different user without a password from an elevated prompt in Windows", like a:

Start-Process -Verb Runas 'yourUser' -Wait

From Daniel Widdis's answer, that would work but would not provide the exit status.

I would for that make sure the command executed (mvnw.cmd) is a wrapper which:

  • executes what you want
  • get the exit status
  • write the exit status in a separate file

You can the use action/core to set the exit code for your action.
Or check the outcome of a previous step, and set the final exit status in a separate step.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Figured it out! See my answer; opportunity for you to earn the bounty by completing the solution with exit code handling. – Daniel Widdis Nov 03 '22 at 07:42
  • @DanielWiddis Sure. I don't have the opportunity/time to actually test it out, but I have edited the answer with some ideas. – VonC Nov 03 '22 at 07:54