具有存储凭据的启动过程PowerShell无法正常工作

时间:2019-07-24 14:15:50

标签: powershell uac

我有一个必须以提升用户身份运行的脚本。我正在使用问题“ 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 $)无法以其他用户身份运行进程吗?

4 个答案:

答案 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个帐户。在我看来,这是针对您的情况的最直接,最简单的解决方案。