以其他用户身份运行 PowerShell 脚本并提升权限

以其他用户身份运行 PowerShell 脚本并提升权限

我知道这看起来像一个重复的问题,但我已经尝试过解决方案,但它们对我没有用。

我们需要使用域帐户运行脚本,但也要以提升权限执行它。这在大多数设备上都不是问题,因为快捷方式以管理员身份运行并提示我们输入凭据。但是,如果用户是本地管理员,则不会提示我们输入凭据(只是 UAC 提示是/否)。

我很困惑为什么这不起作用:

# Get identity of script user
$identity = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()

# Elevate the script if not already
if ($identity.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host -F Green 'ELEVATED'
} else {
    Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"& '$PSCommandPath'`""
    Exit
}

# Ensure the script has domain privileges
if ($identity.IsInRole('[domain]\[admin group]')) {
    Write-Host -F Green 'DOMAIN ADMIN'
} else {
    Start-Process PowerShell -Verb RunAsUser "-NoProfile -ExecutionPolicy Bypass -Command `"& '$PSCommandPath'`""
    Pause # required, otherwise the Exit below closes the UAC prompt
    Exit
}
Pause

当自提升脚本以用户身份运行并且输入了域凭据时,它会失去提升...即,当Start-Process -Verb RunAsUser powershell从提升的 PowerShell 运行时,它本身并没有提升。

我还尝试了以下操作:

Start-Process powershell -verb RunAs -argumentlist "Start-Process powershell.exe -Verb RunAsUser `"& path\to\script.ps1`""

这会失败,因为域管理员无权访问脚本目录...除非他们被提升。

答案1

您是否在自动化某些操作或只是偶尔运行脚本?脚本目录是在本地还是在网络上?

正如您所注意到的,使用 启动新的 powershell 实例不会runas更改用户,也runasuser不会提升进程。您需要以相反的顺序执行这两项操作。如果您以本地管理员身份登录,请使用 RunAsUser 启动 Powershell,或者通过:

  • Shift+右键单击 > 以不同用户身份运行 > 域管理员

然后执行 runas 来从那里提升(作为域管理员):

Start-Process PowerShell -Verb RunAs

您可以使用 检查您当前以哪个用户身份运行whoami。结果应该是您的域帐户,即使权限提升也是如此。

或者

如果您正在远程管理 PC 并且已经在使用 powershell,请改用 powershell 进行连接,因为会话将始终提升:

Enter-PSSession MyPCName -credential (get-credential -username domain\MyAdmin)
# remote session:
[MyPCName]: PS C:\WINDOWS\system32>

如果可能的话,我还建议不要使用本地管理员帐户。

答案2

另一个工具是免费的 sysinternals 工具 执行程序

该命令如下:

psexec -u domain\user -h -i command [arguments]

参数为:

  • -i:运行程序,使其与远程系统上指定会话的桌面交互。如果未指定会话,则进程在控制台会话中运行。
  • -h:如果目标系统是 Vista 或更高版本,则使用帐户的提升令牌(如果可用)运行该进程。

一种不安全的做法是指定密码:

-p:指定用户名的可选密码。如果省略此项,系统将提示您输入隐藏密码。

答案3

一个简单的解决方案是首先从需要域凭据的位置复制脚本您已作为以下用户登录到您需要从提升权限执行该脚本的机器的本地文件系统。然后从该本地副本中执行提升权限的脚本。

执行方式Start-Process Powershell与之前略有不同,以便它在运行提升时也能执行脚本逻辑的操作。添加参数ExecutionPolicy Bypass -NoProfile -File,然后运行脚本,使其正常工作。

笔记:下面两个示例 PowerShell 解决方案均使用C:\本地文件系统的“C”驱动器的根目录,但您可以相应地进行调整以适应。

PowerShell(解决方案 1)

Copy-Item "path\to\script.ps1" -Destination "C:\" -Force;
Start-Process Powershell -Argumentlist '-ExecutionPolicy Bypass -NoProfile -File "C:\script.ps1"' -Verb RunAs;

如果需要使用域凭据进行身份验证才能访问脚本路径位置最初,您可以使用invoke-command参数-credential来执行复制操作。然后,您可以通过这种方式执行提升权限的本地文件系统复制脚本。

PowerShell(解决方案 2)

$cred = Get-Credential "domain\username";
Invoke-Command -ScriptBlock {
    Copy-Item "path\to\script.ps1" -Destination "C:\" -Force;
    } -Credential $cred;

Start-Process Powershell -Argumentlist '-ExecutionPolicy Bypass -NoProfile -File "C:\script.ps1"' -Verb RunAs;

支持资源

答案4

在我看来,一般来说,当前进程的执行用户和权限在进程执行过程中是无法改变的,但它们是由操作系统内核在进程启动时设置的。
因此,您应该将要以提升权限运行的代码块分离出来,并使用 RunAs(或其验证)运行它。
如果可以在进程内更改权限,那么这将成为操作系统非常危险的安全漏洞。

此外,本地权限 ( local administrator) 和域权限 ( [domain]\[admin group]) 是单独定义的。
如果要DomainA\User01同时允许local administratorAND DomainA\AdminGroup,则必须同时执行以下两项操作:

  • 授予DomainA\User01本地计算机安全组权限local administrator,并且
  • 授予DomainA\User01进入域安全组DomainA\AdminGroup

然后使用 RunAs 执行脚本。

相关内容