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
Run code block locally as a different user in powershell script
提问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 localhost
but you do have to have remoting enabled on your machine to do it.
查看您没有向我们展示的错误消息会有所帮助,但我认为您的问题的答案是在您尝试使用Invoke-Command
. 计算机名称.
没有问题,localhost
但您必须在计算机上启用远程处理才能执行此操作。
To enable remoting, run Enable-PSRemoting
within powershell, or run winrm quickconfig
in 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.Powershell
and you could change the permissions with Set-PSSessionConfiguration
(be sure to use the -ShowSecurityDescriptorUI
parameter 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 Users
which 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.
在看到你最终想要完成的事情的解释后,我有另一个建议给你。
- Your existing scheduled task writes the information to a known location.
- 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.
- Bonus:start the second task from the first task.
- 您现有的计划任务将信息写入已知位置。
- 在特权用户帐户下运行的不同计划任务获取该信息并将其放入受限用户无法访问的文件中。
- 奖励:从第一个任务开始第二个任务。
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 POST
or 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.
另一种方法是模拟,如果您不愿意启用远程处理,这是一个不错的选择。
You should just put your code between
你应该把你的代码放在
Push-ImpersonationContext $credential
Push-ImpersonationContext $credential
and
和
Pop-ImpersonationContext
Pop-ImpersonationContext