windows 在 powershell 脚本中以不同用户的身份在本地运行代码块

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25600870/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 18:40:47  来源:igfitidea点击:

Run code block locally as a different user in powershell script

windowspowershell

提问by wrieedx

This is something incredibly simple, but I just can't get anything to work. I want to run a block code in a powershell script under a specific user. The keyword is locallyand I'm using powershell 2.0.

这是非常简单的事情,但我无法完成任何工作。我想在特定用户下的 powershell 脚本中运行块代码。关键字是本地的,我使用的是 powershell 2.0。

Invoke-Command seems to require a remote host? I run the following and the error message that I see seems to suggest as much:

Invoke-Command 似乎需要远程主机?我运行以下命令,我看到的错误消息似乎暗示了很多:

$strScriptUser = "DOMAIN\USER"
$strPass = "PASSWERD"
$PSS = ConvertTo-SecureString $strPass -AsPlainText -Force
$cred = new-object system.management.automation.PSCredential $strScriptUser,$PSS
Invoke-Command -ComputerName "." -scriptblock {
write-output "HI!"
} -Credential $cred

Start-Job with -ScriptBlock isn't supported with powershell 2.0? I run the following and the error message that I see seems to suggest as much:

powershell 2.0 不支持使用 -ScriptBlock 启动作业?我运行以下命令,我看到的错误消息似乎暗示了很多:

$strScriptUser = "DOMAIN\USER"
$strPass = "PASSWERD"
$PSS = ConvertTo-SecureString $strPass -AsPlainText -Force
$cred = new-object system.management.automation.PSCredential $strScriptUser,$PSS
Start-Job -ScriptBlock {
write-output "HI!"
} -Credential $cred

Am I doing something wrong, or is there an alternative way?

我做错了什么,还是有其他方法?

Added: Here is what I'm trying to do in the first place. I'm making a scheduled task that runs when a user logs into/unlocks a terminal that writes logon information to a file. The scheduled task runs as the local user in order to get at the username, profile, etc. information. The logon information is then written to a log file using a different user account, which is the only account that can modify the file. To deter access to the logon credentials in the script I convert the script to an EXE using PS2EXE.

补充:这是我首先要做的。我正在制作一个计划任务,当用户登录/解锁将登录信息写入文件的终端时运行该任务。计划任务以本地用户身份运行,以获取用户名、配置文件等信息。然后使用不同的用户帐户将登录信息写入日志文件,该帐户是唯一可以修改文件的帐户。为了阻止访问脚本中的登录凭据,我使用 PS2EXE 将脚本转换为 EXE。

回答by Nathan Hartley

Here is another way.

这是另一种方式。

# Get the other user's credentials
$credential = Get-Credential

# Execute a scriptblock as another user
$commands = @'
    $env:username
    # ... more commands ...
'@
Start-Process -FilePath Powershell -LoadUserProfile -Credential $credential -ArgumentList '-Command', $commands

# Execute a file as another user 
$script = '.\path\name.ps1'
Start-Process -FilePath Powershell -LoadUserProfile -Credential $credential -ArgumentList '-File', $script

With the -LoadUserProfile switch, this has the added benefit of creating the user's profile if it does not already exist.

使用 -LoadUserProfile 开关,这具有创建用户配置文件(如果尚不存在)的额外好处。

回答by briantist

It would help to see the error messages you're not showing us, but I think the answer to your question is to use PowerShell Remoting as you tried with Invoke-Command. The computer name .is fine as is localhostbut you do have to have remoting enabled on your machine to do it.

查看您没有向我们展示的错误消息会有所帮助,但我认为您的问题的答案是在您尝试使用Invoke-Command. 计算机名称.没有问题,localhost但您必须在计算机上启用远程处理才能执行此操作。

To enable remoting, run Enable-PSRemotingwithin powershell, or run winrm quickconfigin a regular command prompt.

要启用远程处理,请Enable-PSRemoting在 powershell 中运行,或winrm quickconfig在常规命令提示符中运行。

If you already have remoting enabled, then you might be trying to do the remoting with a non-administrative user. If that's the case, take a look at the output of Get-PSSessionConfiguration. You'll get a list of endpoints and the permissions that are applied.

如果您已经启用了远程处理,那么您可能正在尝试与非管理用户进行远程处理。如果是这种情况,请查看Get-PSSessionConfiguration. 您将获得端点列表和应用的权限。

The endpoint you're connecting to by default is called Microsoft.Powershelland you could change the permissions with Set-PSSessionConfiguration(be sure to use the -ShowSecurityDescriptorUIparameter unless you want to mess with SDDL).

默认情况下Microsoft.Powershell,您连接到的端点被调用,您可以更改权限Set-PSSessionConfiguration(请务必使用该-ShowSecurityDescriptorUI参数,除非您想弄乱 SDDL)。

But instead of doing that, there should already be a group given access called BUILTIN\Remote Management Userswhich you can add your limited user to.

但不是这样做,应该已经有一个被称为访问权限的组BUILTIN\Remote Management Users,您可以将您的受限用户添加到该组中。

If none of this helps, give more details and error messages.

如果这些都没有帮助,请提供更多详细信息和错误消息。

Edit

编辑

After seeing the explanation of what you're ultimately trying to accomplish, I have another suggestion for you.

在看到你最终想要完成的事情的解释后,我有另一个建议给你。

  1. Your existing scheduled task writes the information to a known location.
  2. A different scheduled task running under the privileged user account picks up that information and puts it into the file that the limited user cannot access.
  3. Bonus:start the second task from the first task.
  1. 您现有的计划任务将信息写入已知位置。
  2. 在特权用户帐户下运行的不同计划任务获取该信息并将其放入受限用户无法访问的文件中。
  3. 奖励:从第一个任务开始第二个任务。

This could be a quick compromise to do what you want without remoting and without exposing the credentials of the privileged user.

这可能是一种快速妥协,可以在不进行远程处理且不暴露特权用户的凭据的情况下执行您想要的操作。

Issues with the current approach:

当前方法的问题:

The major problem I have with your original idea is that you're going to need to embed the credentials into the script, so the limited user will have access to the credentials of the account that can modify the file anyway.

我对您的原始想法的主要问题是您需要将凭据嵌入到脚本中,因此受限用户将有权访问无论如何都可以修改文件的帐户凭据。

Ideally:

理想情况下:

You would have a web service that you could invoke with your limited-user powershell script in which you can only give it the login information and not get anything back. So you'd hit a URL and do a POSTor whatever with the data that you want to log, but that user can't ever retrieve any info. It might be a bit beyond what you're willing to do for this.

您将拥有一个 Web 服务,您可以使用受限用户的 powershell 脚本调用该服务,在该脚本中,您只能向其提供登录信息而无法返回任何信息。因此,您可以点击一个 URL 并POST使用您想要记录的数据执行任何操作,但该用户永远无法检索任何信息。这可能有点超出您愿意为此做的事情。

回答by olegk

Another approach is impersonation, it is good option if you are not willing to enable remoting.

另一种方法是模拟,如果您不愿意启用远程处理,这是一个不错的选择。

Check thisand thisout.

检查这个这个

You should just put your code between

你应该把你的代码放在

Push-ImpersonationContext $credential

Push-ImpersonationContext $credential

and

Pop-ImpersonationContext

Pop-ImpersonationContext