Starting non-elevated prompt from elevated session

2019-07-13 12:08发布

I have some tool that doesn't work if it runs from elevated session.

I am running elevated session (in the context of administrative intall so this is mandatory) so that is not changable.

Other then creating scheduled task and executing it, is there anything else that is faster or friendlier?

=== EDIT ===

This is the command that needs unelevated run: vboxmanage list runningvms

I tried

runas /trustlevel:0x20000 "powershell.exe -noprofile -noexit -command iex 'vboxmanage list runningvms'"

and it returns nothing

This code works:

function Run-NonElevated( [string] $cmd ) {
    $task_name = "Run-NonElevated-$(New-Guid)"
    schtasks /Create /RU $Env:USERNAME /TN $task_name /SC ONCE /ST 00:00 /F /TR $cmd
    schtasks /run /tn $task_name
    schtasks /delete /F /tn $task_name
}

Run-NonElevated "powershell -NoProfile -Command 'vboxmanage list runningvms | Out-File $Env:TEMP\re.out'"
cat C:\Users\majkinetor\AppData\Local\Temp\re.out
"test machine" {31409fff-c195-4a83-ab12-96bba020e051}

标签: powershell
2条回答
【Aperson】
2楼-- · 2019-07-13 12:20

Using this function at the end:

function Start-ProcessNonElevated( [string] $Cmd, [switch]$UsePowerShell ) {
    $svc = gsv Schedule -ea 0
    if ($svc -and $svc.Status -ne 'Running') { throw 'Start-ProcessNonElevated requires running Task Scheduler service' }

    $res = @{}

    $tmp_base  = [System.IO.Path]::GetTempFileName()
    $tmp_base  = $tmp_base -replace '\.tmp$'
    $tmp_name  = Split-Path $tmp_base -Leaf
    $task_name = "Start-ProcessNonElevated-$tmp_name"
    Write-Verbose "Temporary files: $tmp_base"

    if ($UsePowershell) {
        @(
            '$r = "{0}"' -f $tmp_base
            ". {{`n{0}`n}} >`"`$r.out.log`" 2>`"`$r.err.log`"" -f $Cmd
        ) -join "`n" | Out-String | Out-File "$tmp_base.ps1"
        $cmd = "powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -NoLogo -NonInteractive -File '$tmp_base.ps1'"
    }

    Write-Verbose "Creating scheduled task for command:`n$cmd"
    schtasks.exe /Create /RU $Env:USERNAME /TN $task_name /SC ONCE /ST 00:00 /F /TR $cmd *> "$tmp_base.schtasks.log"
    schtasks.exe /run /tn $task_name *>> "$tmp_base.schtasks.log"

    Write-Verbose 'Waiting for scheduled task to finish'
    do {
        $status = schtasks /query /tn $task_name /FO csv | ConvertFrom-Csv | select -expand Status
        sleep 1
    }
    until ($status -eq 'Ready')
    schtasks.exe /delete /F /tn $task_name *>> "$tmp_base.schtasks.log"

    if ($UsePowershell) {
        $res = @{
            out = cat "$tmp_base.out.log" -ea 0
            err = cat "$tmp_base.err.log" -ea 0
        }
    }

    return $res
}

Would still like to know solution without task scheduler.

查看更多
狗以群分
3楼-- · 2019-07-13 12:44
Function Run-NonElevated([string]$Cmd) {
    $Cmd | Out-File -Encoding AscII -FilePath "$Env:Temp\Run-NonElevated.cmd"
    Explorer "$Env:Temp\Run-NonElevated.cmd"
}

Run-NonElevated "vboxmanage list runningvms"
查看更多
登录 后发表回答