我有一个必须以提升用户身份运行的脚本。我正在使用问题“ Running a PowerShell script as administrator without typing in passwords”中的代码 但是我的第二个脚本没有被调用。第一个脚本是由系统进程触发的(我的票务系统收到电子邮件,然后以主题行作为参数调用我的海拔脚本),而仅使用计划任务是不可行的。
调用脚本:
param(
[Parameter(Mandatory=$true)]
[String]$MyParam
)
$LogFile = "c:\temp\log.txt"
$encpwd = Get-Content c:\temp\password.bin
$passwd = ConvertTo-SecureString $encpwd
$cred = new-object System.Management.Automation.PSCredential 'domain\LocalAdminAccount',$passwd
Add-Content $LogFile "I am running as $env:userdomain\$env:username"
Add-Content $LogFile "Trying to call the script with the parameter: $MyParam"
try {
Add-Content $LogFile "Calling script"
Start-Process PowerShell -WorkingDirectory 'C:\Windows\System32' -Cred $cred -ArgumentList '-File', "c:\temp\TargetScript.ps1 $MyParam"
Add-Content $LogFile "Script called"
} catch {
$msg = $Error[0].Exception.Message
Add-Content $LogFile "Error caught: $msg"
}
Add-Content $LogFile "Error caught: $msg"
被调用的脚本:
param(
[Parameter(Mandatory=$true)]
[String]$PassedParam
)
$LogFile = "c:\temp\log.txt"
Add-Content $LogFile "I am running as $env:userdomain\$env:username"
if ($PassedParam) {
try {
#stuff
if ($?) {
Add-Content $LogFile "$PassedParam worked"
} else {
Add-Content $LogFile "Failed"
}
} catch {
$msg = $Error[0].Exception.Message
Add-Content $LogFile "Error caught: $msg"
}
}
Add-Content $LogFile "Error caught: $msg"
这是放在日志文件中的内容:
I am running as DOMAIN\COMPUTER$
Trying to call the script with the parameter: Tim
Calling script
似乎从来没有真正启动过第二个Powershell进程,或者至少启动了第二个Powershell进程,但它没有写入日志文件。我专门授予了LocalAdminAccount对日志文件和password.bin文件的完全权限,而LocalAdminAccount在计算机的管理员组中。
如果有关系,我的powershell版本是:
PS C:\> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
4 0 -1 -1
更新: 如果我登录计算机并以自己的身份运行脚本,则日志文件将显示以下内容:
I am running as DOMAIN\TIM
Trying to call the script with the parameter: Tim
Calling script
Script called
I am running as DOMAIN\LocalAdminAccount
Tim worked
Error caught:
更新: 我确实找到了这篇文章:https://www.pdq.com/blog/secure-password-with-powershell-encrypting-credentials-part-2/,它表明我需要提供密码的解密密钥,因为我使用自己的帐户制作了密码文件,但该文件正在被NT SYSTEM解密。但这并不能解决我的问题。
我只是通过尝试调用记事本进行了更多测试。如果我尝试以其他用户身份打开它,它将失败,但是如果我只是尝试打开它,则可以在以SYSTEM用户名运行的任务管理器中看到它。
我的问题确实似乎是SYSTEM(DOMAIN \ COMPUTER $)无法以其他用户身份运行进程吗?
答案 0 :(得分:2)
从交互式PowerShell窗口作为系统运行主要脚本命令(请参阅:Run PowerShell as System。
这将显示错误:
由于错误,该命令无法运行:访问被拒绝。
此问题已在Powershell Start-Process : This command cannot be executed due to the error: Access is denied中进行了描述,并由本地策略定义:
Security Settings
Local Policies
User Rights Assignment
Impersonate a client after authentication
答案 1 :(得分:0)
要在另一个进程中运行脚本,请记住PowerShell始终在启动该脚本的用户的上下文中运行,因此您需要将脚本设置为自动提升/至少使用RunAs动词。
Start-Process PowerShell -verb RunAs -Cred $cred -ArgumentList '-noexit','-File','path-to-script'
或在记事本或其他脚本用例中说...
Start-Process powershell -Credential mydomain\mydomainAdmin -ArgumentList '-noprofile -command &{Start-Process notepad -verb runas}'
…显示您正在使用的指针。您没有在发布的代码中的任何地方使用它。您必须单独启动另一个进程才能以另一个用户身份运行。
答案 2 :(得分:0)
作为一种变通办法,我创建了一个计划任务,该任务以我的serviceadmin运行。现在,当售票系统触发调用计划任务的脚本,并且计划任务运行需要提升的第二个脚本时。这不是理想的方法,但是确实可以正常工作。
计划任务(名为步骤2)
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2019-08-01T09:12:24.7058452</Date>
<Author>Tim</Author>
<Description></Description>
</RegistrationInfo>
<Triggers />
<Principals>
<Principal id="Author">
<UserId>Domain\ServiceAccount</UserId>
<LogonType>Password</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
all defaults. Removed for brevity.
</Settings>
<Actions Context="Author">
<Exec>
<Command>%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe</Command>
<Arguments>-file "C:\Temp\Step2.ps1"</Arguments>
</Exec>
</Actions>
</Task>
Step1.ps1(调用脚本)
param(
[Parameter(Mandatory=$true)]
[String]$MyParam
)
$LogFile = "c:\Temp\Actions.log"
$ParamFile = "c:\Temp\Params.txt"
Remove-Item $ParamFile
$MyParam | Out-File -FilePath $ParamFile
Add-Content $LogFile "$MyParam written to file."
Add-Content $LogFile "Calling Step 2 task."
Start-ScheduledTask -TaskName "Step 2"
Step2.ps1(称为脚本)
$LogFile = "c:\temp\log.txt"
$ParamFile = "c:\Temp\Params.txt"
$PassedParam = Get-Content $ParamFile
Add-Content $LogFile "I am running as $env:userdomain\$env:username"
if ($PassedParam) {
try {
#stuff
if ($?) {
Add-Content $LogFile "$PassedParam worked"
} else {
Add-Content $LogFile "Failed"
}
} catch {
$msg = $Error[0].Exception.Message
Add-Content $LogFile "Error caught: $msg"
}
}
Add-Content $LogFile "Step 2 complete"
我不将其标记为答案,因为它可以通过变通解决我的问题,但不能回答我的问题。
答案 3 :(得分:0)
我的建议是授予计算机帐户访问所涉及目录对象的权限(最明显的方法是将计算机帐户添加到在目录中具有必需权限的组中),然后使用SYSTEM
个帐户。在我看来,这是针对您的情况的最直接,最简单的解决方案。