excelvbapowershellelevated-privileges

Running Powershell from VBA with Administrator privileges


I have not been able to successfully run my PowerShell script from VBA with administrator privileges.

I have examined the various answers in this forum and attempted to adapt with no success.

When I execute the VBA script below, there is a window that will open for less than one second and then close (and I don't know if it is a Powershell or a Command window) and the script does not run as evidenced by not doing its job, and finishing immediately (not waiting the ten seconds). Also, there is nothing written to StdOut or StdErr

If the script is run from an elevated command window, or an elevated Powershell window, it runs as designed.

The script is designed to temporarily disconnect the network adapter. It is simplified at this stage and only works on an adapter named Ethernet.

Powershell Script

Disable-NetAdapter -name Ethernet -confirm:$false
Start-Sleep -Seconds 10
Enable-NetAdapter -name Ethernet -confirm:$false

Functioning elevated command window code:
C:\PowerShell Scripts>"disable network temporarily.ps1" enter image description here

Non-Functioning VBA Code

'Needs reference to Windows Script Host Object Model
Option Explicit
Sub TempNetworkDisable()
    Dim wshShell As wshShell
    Dim wshShellExec    As Object
    Dim strCommand      As String
    Dim strOutput

    strCommand = "pwsh.exe -c Start-Process -Verb RunAs pwsh.exe \"" -ExecutionPolicy Unrestricted -NoExit -f `\""C:\PowerShell Scripts\Disable Network Temporarily.ps1`\"""
    
    Set wshShell = New wshShell
    Set wshShellExec = wshShell.Exec(strCommand)
    strOutput = wshShellExec.StdOut.ReadAll()
    Debug.Print "StdOut:", strOutput

    strOutput = wshShellExec.StdErr.ReadAll()
    Debug.Print "StdErr:", strOutput
End Sub

Solution

  • ' Note the addition of -Wait to the Start-Process call, 
    ' the switch to -c in the nested call, 
    ' the use of & the call operator to invoke the script, the
    ' switch to '...' quoting around the script-file path,
    ' and the > and 2> redirections with sample output file names
    ' stdout.txt and stderr.txt
    strCommand = "pwsh.exe -c Start-Process -Wait -Verb RunAs pwsh.exe \""-ExecutionPolicy Unrestricted -NoExit -c & 'C:\PowerShell Scripts\Disable Network Temporarily.ps1' >stdout.txt 2>stderr.txt\"""
    
    ' ...
    
    ' After synchronous execution (due to -Wait), read the output files, stdout.txt and stderr.txt
    ' Without -Wait, you'd have to track the lifetime of the elevated
    ' process manually.
    

    [1] While your original code therefore had a syntax error, the way pwsh.exe quietly ignored it is actually a bug in the latter, as of PowerShell 7.4.x; a simple repro: pwsh -nop -c "\"hi" (from outside PowerShell; from PowerShell or a POSIX shell, use pwsh -nop -c '"hi'); see GitHub issue #14284.
    However, the failure is - abstractly - reflected in the process exit code, which is set to 1.