如何从 PowerShell 运行 exe with/without 提升权限

How to run exe with/without elevated privileges from PowerShell

我想要一个简单的方法来 运行 具有来自同一用户的不同权限的进程,而无需询问或知道 his/her 密码。如有必要,可以进行对话。我不想启动 PowerShell 子进程来完成此操作。

场景 1: PowerShell 脚本 运行ning 在管理模式下。我想在没有管理员权限但在同一用户上启动脚本或 .exe。

场景 2: PowerShell 脚本 运行ning 在正常模式下。我想在同一用户上启动具有管理员权限的脚本或 .exe。

让我们把它分成三个部分。

首先判断当前会话是否为运行管理员权限:

$CurrentID = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$CurrentPrincipal = new-object System.Security.Principal.WindowsPrincipal($CurrentID)
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator

# Check to see if session is currently with admin privileges

if ($CurrentPrincipal.IsInRole($adminRole)) {
    write-host "Yes we are running elevated."
}else{
    write-host "No this is a normal user session."
}

现在,如果我们 运行 或没有提升权限,您可以像这样启动一个具有提升权限的新进程:

$newProc = new-object System.Diagnostics.ProcessStartInfo "PowerShell"
# Specify what to run
$newProc.Arguments = "powershell.exe"
# If you set this, process will be elevated
$newProc.Verb = "runas"
[System.Diagnostics.Process]::Start($newProc)

最后,如果我们有提升的权限,但想在没有...的情况下启动一个新进程...

我不知道。将不得不尝试找到这个问题的答案,但由于这不是常见的情况,到目前为止我没有运气。

编辑: 我现在看到了针对这种情况的几个“解决方案”。在 .NET/PowerShell 中没有执行此操作的本机方法。有些相当复杂(调用大约 12 个 COM 对象)。这个 vista-7-uac-how-to-lower-process-privileges 是一个很好的参考。

对我来说最优雅的是利用 explorer.exe 中的一个“错误”。 只需使用 explorer.exe 启动 .exe,生成的进程将再次运行而无需提升权限。

$newProc = new-object System.Diagnostics.ProcessStartInfo "PowerShell"
# Specify what to run, you need the full path after explorer.exe
$newProc.Arguments = "explorer.exe C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
[System.Diagnostics.Process]::Start($newProc)

编辑 #2: 另一种方法我刚刚发现开始一个新的 non-elevated 来自 已提升 环境的进程将使用具有 0x20000(基本用户)信任级别的 runas.exe:

C:\> runas /showtrustlevels The following trust levels are available on your system: 0x20000 (Basic User) C:\> runas /trustlevel:0x20000 devenv

我将此作为所有需要提升模式的脚本中的第一个命令,如果我忘记以管理员身份启动,它会将脚本传输到另一个提升的进程。您必须确认它不适合自动化任务

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {   
    $arguments = "& '" + $myinvocation.mycommand.definition + "'"
    Start-Process powershell -Verb runAs -ArgumentList $arguments
    Break }