简体   繁体   English

Powershell 以管理员用户身份运行命令行

[英]Powershell Running Command Line as Admin User

So I have automation that logs into a Windows Server 2019 machine as one user, but then needs to run a command ( Invoke-AdminCommand is application specific, not a built-in Windows cmdlet) as an admin user (and I do not want to add the logged in user as an Admin).所以我有自动化作为一个用户登录到 Windows Server 2019 机器,但随后需要运行命令( Invoke-AdminCommand是特定于应用程序的,而不是内置的 Windows cmdlet)作为管理员用户(我不想将登录用户添加为管理员)。 I've followed answers from here (if you think this is a duplicate question) and none have worked.我已经按照这里的答案(如果您认为这是一个重复的问题)并且没有一个有效。 In the script I do a "whoami" to be sure the session is the correct user, and it is.在脚本中,我做了一个“whoami”以确保 session 是正确的用户,而且确实如此。 But the command returns an application specific error stating the user does not have the correct permissions.但是该命令会返回一个特定于应用程序的错误,说明用户没有正确的权限。 If I RDP into the same machine as the admin user and run the same command through a Powershell CLI - it works fine.如果我 RDP 进入与管理员用户相同的机器并通过 Powershell CLI 运行相同的命令 - 它工作正常。

$username = "domain\adminUser"
$password = "**********" | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$password
$s = New-PSSession -credential $cred
$sc = {
    whoami
    Invoke-AdminCommand -Register -Verbose
}
Invoke-Command -Session $s -Scriptblock $sc
Remove-PSSession $s

You may be hitting the double-hop problem.您可能遇到了双跳问题。 You are remoting to another server to run another command which itself requires authentication.您正在远程连接到另一台服务器以运行另一个本身需要身份验证的命令。 If you can't lean on CredSSP (security risk) or proper account delegation (potentially high overhead in effort to maintain delegations at volume but this is the correct way to go about it).如果您不能依靠CredSSP (安全风险)或适当的帐户委派(可能需要大量开销来维持委派,但这是 go 的正确方法)。

Note: Basic auth will also work around this issue but I highly highly highly do not recommend using basic auth without at least setting up WinRM over SSL and removing non-HTTPS WinRM listeners.注意:基本身份验证也可以解决此问题,但我非常强烈不建议在没有至少在 SSL 上设置 WinRM并删除非 HTTPS WinRM侦听器的情况下使用基本身份验证。

Whether you are using Kerberos (without proper delegation or CredSSP ) or NTLM (at all as NTLM cannot forward tokens) as the authentication scheme you can work around this by passing the credential information into Invoke-Command and building the credential in that script block, and using Start-Process to start it as a different user.无论您是使用 Kerberos(没有适当的委派或CredSSP )还是 NTLM(因为 NTLM 无法转发令牌)作为身份验证方案,您都可以通过将凭证信息传递到Invoke-Command并在该脚本块中构建凭证来解决此问题,并使用Start-Process以其他用户身份启动它。 Note that if you needed to elevate for UAC , the code would be different and this code will only work when you don't need UAC elevation:请注意,如果您需要提升UAC ,代码会有所不同,并且此代码仅在您不需要UAC提升时才有效:

# We will create the SecureString inside the Invoke-Command block
$password = "********"

# Use of a Disctionary instead of positional arguments and `param` in the block
# is a little trick you can use here.
Invoke-Command -Session $s -ArgumentList @{ Username = $username; Password = $password } {
  $cred =
    [PSCredential]::new($args.Username, ( $args.Password | ConvertTo-SecureString -AsPlainText -Force ))

  # Placeholder for next part
}

So this is the boilerplate for what you want.所以这是你想要的样板。 You send the credentials to the remote server and build it there.您将凭据发送到远程服务器并在那里构建它。 How you execute this at # Placeholder for next part will depend on what exactly you are running:您如何在# Placeholder for next part执行此操作将取决于您正在运行的具体内容:

  • External Command (executable)外部命令(可执行)

    • Use Start-Process to run the program as the other user使用Start-Process以其他用户身份运行程序
    Start-Process -Wait -Credential $cred program.exe -ArgumentList "arguments to the program here"
  • Any cmdlet which accepts a -Credential parameter or any command which accepts username and password arguments接受-Credential参数的任何 cmdlet 或接受用户名和密码 arguments 的任何命令

    • Pass the credential argument directly to the cmdlet/function, or pass $args.Username and $args.Password to an external command which has username/password parameters directly.将凭证参数直接传递给 cmdlet/函数,或将$args.Username$args.Password给直接具有用户名/密码参数的外部命令。 The below however exemplifies using this with a cmdlet and the -Credential parameter.然而,下面的示例通过 cmdlet 和-Credential参数来举例说明。
     # Note that some cmdlets don't take a credential for whatever reason # and may have -Username and -Password arguments instead. Invoke-AdminCommand -Credential $cred -Register -Verbose
  • Any Function or Cmdlet which does not accept a -Credential parameter or username/password arguments任何不接受-Credential参数或用户名/密码 arguments 的 Function 或 Cmdlet

    • This is similar to the first example, but this example specifically targets running a bit of PowerShell code as another user for the code you want.这与第一个示例类似,但此示例专门针对您想要的代码作为另一个用户运行一些 PowerShell 代码。
     # This can be invoked without splatting but am using splatting for readability $spArgs = @{ Credential = $cred FilePath = 'powershell.exe' # You can use `pwsh.exe` for PS Core if necessary ArgumentList = "-Command ""exampleProgram.exe -username $($args.Username) -password $($args.Password)""" Wait = $true NoNewWindow = $true } Start-Process powershell.exe

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM