gpt4 book ai didi

powershell - 从Powershell启动Elevated CMD.exe

转载 作者:行者123 更新时间:2023-12-01 09:48:32 24 4
gpt4 key购买 nike

我正在尝试从PowerShell启动提升的CMD窗口,但遇到一些问题。以下是我现在拥有的代码。计算机上有一个管理员帐户,其用户名为“test”,密码为“test”

$username = "test"
$password = ConvertTo-SecureString "test" -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
Start-Process "cmd.exe" -Credential $cred

对于从用户配置文件运行该应用程序时,如果没有此脚本所处的管理员权限,这一切都可以正常工作,但是在调用cmd.exe时,它将以提升的权限按预期启动,然后立即关闭。

我也尝试用以下命令调用它:
Start-Process "cmd.exe" -Credential $cred -ArgumentList '/k'

这也不起作用。
我通过传递一个参数来测试提升的权限,如下所示,它可以正常工作。
Start-Process "cmd.exe" -Credential $cred -ArgumentList 'dir > dir.txt'

这会将dir.txt文件写到C:\ Windows \ System32 \ WindowsPowerShell \ v1.0目录,该目录在用户帐户上被阻止,但对于管理员帐户测试则未被阻止。

任何帮助获得持久的cmd窗口显示的帮助将不胜感激。

谢谢

最佳答案

注意:SomeShinyObject在his answer中提出了该方法的基本原理,但是他的参数传递技术并不可靠(更新:已更正)-请勿使用脚本块代替字符串-参见底部。

  • -Verb RunAs 是什么使Start-Process 启动提升了的进程。
  • 但是, -Verb RunAs不能与-Credential参数结合使用,因此您不能直接控制在哪个用户帐户下进行海拔升高-但这通常不是必需的:
  • 如果当前用户是管理员,则在该用户的上下文中总是会发生海拔升高,GUI提示仅要求确认。
  • 否则,将显示GUI对话框,询问管理员的用户名和密码(用户名字段为空白)。

  • 安全警告:
  • 将密码存储为纯文本格式通常存在安全风险。
  • 此外,如果您让非管理用户使用存储的管理员凭据执行以下代码,则实际上是在授予他们管理权限。

  • 如果仍要按照指定的方式实现脚本,则 解决方法需要 嵌套2个Start-Process调用:
  • 第一个命令使用-Credential在指定用户(假定为管理用户)的上下文中不可见地运行(总是)非提升命令。
  • 因为指定的用户是管理员,所以这里不必担心,但是如果-Credential以非管理员用户为目标,则建议还指定一个-WorkingDir参数,该参数已知该指定的用户具有访问权限-否则,调用可能会失败(保留当前位置,并且可能不允许目标用户访问它)。
  • 第二个嵌入在第一个中,然后使用-Verb RunAs运行提升的目标命令,然后在指定用户的上下文中发生。
  • 注意:即使使用包含密码的凭据对象,您仍然会收到yes / no UAC提示,以确认升格的意图-除非已关闭UAC(不建议这样做)。
  • 工作目录始终是$env:SYSTEMROOT\Windows32-Verb RunAs甚至忽略-WorkingDirectory值;如果要更改到特定目录,请在传递给cd的命令中嵌入cmd.exe命令。

  • 此命令完全符合您的要求- ,请注意安全注意事项:
    # Construct the credentials object
    $username = "jdoe"
    # CAVEAT: Storing a password as plain text is a security risk in general.
    # Additionally, if you let non-administrative users execute this
    # code with a stored password, you're effectively giving them
    # administrative rights.
    $password = ConvertTo-SecureString "test" -AsPlainText -Force
    $cred = New-Object PSCredential -Args $username, $password

    # Start an elevated Command Prompt (cmd) as user $username.
    Start-Process powershell.exe -Credential $cred -WindowStyle Hidden `
    '-noprofile -command "Start-Process cmd.exe -Verb RunAs"'

    请注意,嵌入的第二个命令将作为单个字符串传递给(隐含的) -ArgumentList(也称为 -Args)参数。

    在这种简单情况下,仅使用1级嵌入式引号(即 "字符串内的 '...'实例)并且无需扩展(字符串插值),传递单个字符串是可行的选择,但是使用更复杂的命令引号会变得棘手。

    -ArgumentList定义为[string[]] 类型,即字符串参数数组。 如果您传递多个由,分隔的参数,则PowerShell会为您合成命令行,这通常使引用更容易,尤其是在涉及变量引用时:

    以下命令演示了此技术:它是一种变体,它传递命令以执行 cmd.exe,并在该命令中使用变量引用:
    $msg = 'This is an elevated Command Prompt.'

    Start-Process powershell.exe -Credential $cred -WindowStyle Hidden -Args `
    '-noprofile', '-command', "Start-Process cmd.exe -Verb RunAs -Args /k, echo, '$msg'"

    最终执行的 cmd.exe命令(带有高程)为: cmd /k echo This is an elevated Command Prompt.
    可选阅读:为什么不建议使用脚本块代替字符串

    tl;博士
  • 不要养成在需要字符串的地方使用脚本块的习惯。虽然方便,但它并不可靠,记住何时以及为什么它将失败并不容易。

  • 乍一看,脚本块( { ... })似乎是一个方便的选择:
    Start-Process cmd -ArgumentList { /k echo hi! }

    上面按预期在新的控制台窗口中执行 cmd /k echo hi!
    语法很方便,因为 { ... }似乎提供了易于引用的上下文:您可以自由使用嵌入式 "'实例来构建命令行。

    但是,在幕后发生的事情是脚本块被转换为字符串,因为这是 -ArgumentList所期望的参数类型,而脚本块被转换为字符串时则为 ,其字面量是{}-使用
    这意味着不会进行字符串内插,因此您不能使用变量或子表达式。

    尝试通过变量传递命令:
     Start-Process cmd -ArgumentList { /k echo Honey, I`'m $HOME! }

    这将执行的是: cmd /k echo Honey, I'm $HOME!- $HOME未扩展。

    相比之下,传递插值字符串或参数分别按预期工作:
    # As a single string (argument list):
    Start-Process cmd -ArgumentList "/k echo Honey, I'm $HOME!"

    # As an array of arguments:
    Start-Process cmd -ArgumentList /k, echo, "Honey, I'm $HOME!"

    两种情况下 $HOME都被扩展(内插),类似 cmd /k echo Honey, I'm C:\Users\jdoe被执行。

    关于powershell - 从Powershell启动Elevated CMD.exe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43267766/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com