PowerShell:Start-Process不向cmd.exe传递参数

xwbd5t1u  于 2023-06-06  发布在  Shell
关注(0)|答案(2)|浏览(444)

以下是在PowerShell控制台(Windows 10)中运行的命令:

$username = 'Username'
$password = 'Password'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Start-Process powershell.exe -Credential $credential -WindowStyle Hidden -ArgumentList "Start-Process cmd.exe -Verb RunAs -ArgumentList 'value'"

这些命令可以正常工作,但在您以管理员身份通过其他用户打开cmd.exe后,请运行以下命令:

echo %1

它给了我回报:

%1

字面上的意思。相反,我期望:

value

我做错了什么?

ebdffaop

ebdffaop1#

我只是answered a question,可以使用我在那里提供的脚本找到解决方案,进行一些修改,并以特定的方式调用命令链:

RunAsProxy.ps1

# First arg should be the script path
$script = $args[0]

# Rest of args should be any script parameters
$scriptArgs = $args[1..$args.Count] -join ' '

$startProcessArgs = @{
  Wait = $true
  Verb = 'RunAs'
  FilePath = 'cmd.exe'
  ArgumentList = "/c ""$script"" $scriptArgs"
}
Start-Process @startProcessArgs

exit $LASTEXITCODE

然后以运行用户的身份调用RunAsProxy.ps1如下,然后提升:

$command = "Command_you_want_to_run_from_cmd.exe"
$arguments = "any arguments to the program"
Start-Process -Cred $credential powershell.exe "-File ./RunAsProxy.ps1 $command $arguments"

它的工作方式与您尝试的差不多,但是使用预定义的脚本来处理提升。但是正如您所发现的,不能在Start-Process上的同一个调用中调用-Credential-Verb。因此,这比内联定义代码更容易:
1.以目标用户身份运行RunAsProxy.ps1

  1. RunAsProxy.ps1将使用提供的参数运行cmd.exe并提升进程。
    请注意,如果RunAsProxy.ps1不在当前目录中,则需要提供它的相对路径或完整路径。
hgtggwj0

hgtggwj02#

您的方法唯一的问题是您忘记将/c/kcmd.exe一起使用以便在启动时 * 执行命令 *:

*/ccmd /c $someCommandLine执行由$someCommandLine * 表示的命令,然后退出 *。

  • 注意,这意味着控制台窗口在退出时 * 自动关闭 *,如果cmd.exe进程拥有该窗口(这里就是这种情况);
  • & pause附加到命令字符串将使窗口保持打开状态,直到用户按下一个键,让他们有机会看到输出。
    */kcmd /k $someCommandLine执行命令 *,然后保持会话打开 *,即进入交互式会话。
  • 注意:如果您在命令前既不使用 * /c也不使用 * /k,则cmd.exe * 会忽略 * 它们并直接进入交互式会话(如果您完全不使用参数执行cmd.exe,则会这样做)。

假设代码中的'value'是您希望cmd.exe在提升会话中执行的命令的占位符。
这里有一个简单的例子(它使用一个here-string来避免对字符串中嵌入的引号进行转义),它使用cmd /c执行一个示例命令,然后使用pause来保持窗口打开,直到用户按下一个键(从安全的Angular 来看,使用/k会有更多问题,因为您将以管理员权限进入一个 * 交互式 * 会话)。

# Note: Prompts for the admin credentials first, then requires confirmation
#       of the UAC prompt when the elevated process is launched by the 
#       nested Start-Process call.
Start-Process -Credential (Get-Credential $username) powershell.exe `
  -WindowStyle Hidden `
  -ArgumentList @'
   Start-Process -Verb RunAs cmd.exe -ArgumentList '/c echo I am %USERNAME% & pause'
'@

因为对于其他人来说,为什么你的代码涉及 * 两个 * - nested -Start-Process调用并不明显,让我提供context

  • 您的代码使用 * 不同的用户身份 * 运行 elevated(run-as-admin)命令,可能是因为当前用户不是管理员,无法以他/她自己的身份请求提升。
  • 只是为了提供强制性的安全警告(我希望您的代码只是示例代码):在脚本中存储纯文本密码是不安全的,更不用说管理员的密码了。
  • 这样做需要 * 两个 * Start-Process调用-一个嵌套在另一个内部,因为-Credential参数(请求特定的用户身份)可以在语法上 * 不 * 与-Verb RunAs(请求提升)组合:
  • 外部的-Credential作为目标用户启动一个(总是)* 非提升 * 进程。这个进程是一个临时的辅助进程(这就是为什么你用-WindowStyle Hidden隐藏运行它)。
  • 内部进程,来自辅助进程,带有-Verb RunAs,然后启动一个提升的进程(可见)* 作为该用户 *。

相关问题