简体   繁体   English

具有存储凭据的Start-Process PowerShell无法正常工作

[英]Start-Process PowerShell with stored credentials is not working

I have a script that must be run as an elevated user. 我有一个必须作为提升用户运行的脚本。 I'm using the code from the question " Running a PowerShell script as administrator without typing in passwords " but my 2nd script is not being called. 我正在使用问题“ 以管理员身份运行PowerShell脚本而不输入密码 ”中的代码,但我的第二个脚本未被调用。 The first script gets triggered by a system process (my ticketing system getting an email, then it calls my elevation script with the subject line as a parameter), and simply using a scheduled task is not an option. 第一个脚本由系统进程触发(我的票务系统收到一封电子邮件,然后它以主题行作为参数调用我的提升脚本),并且只是使用计划任务不是一个选项。

The calling script: 调用脚本:

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"

The called script: 被调用的脚本:

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"

And this is what gets put in the log file: 这是放在日志文件中的内容:

I am running as DOMAIN\COMPUTER$
Trying to call the script with the parameter: Tim
Calling script

It never seems to actually start the 2nd powershell process, or at least if it does, the 2nd powershell process isn't writing to the log file. 它似乎永远不会真正启动第二个PowerShell进程,或者至少如果它实际上,第二个PowerShell进程没有写入日志文件。 I specifically granted the LocalAdminAccount full rights to the log file and password.bin file, and the LocalAdminAccount is in the administrators group on the computer. 我特别授予LocalAdminAccount对日志文件和password.bin文件的完全权限,LocalAdminAccount在计算机上的administrators组中。

And in case it matters, my powershell version is: 如果重要,我的powershell版本是:

PS C:\> $PSVersionTable.PSVersion
Major  Minor  Build  Revision
-----  -----  -----  --------
4      0      -1     -1

Update: If I log in to the computer and run the script as myself, Here's is what the log file shows: 更新:如果我以自己的身份登录计算机并运行脚本,则以下是日志文件显示的内容:

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: 

Update: I did find this article: https://www.pdq.com/blog/secure-password-with-powershell-encrypting-credentials-part-2/ which shows I need to provide a decryption key for the password since I made the password file under my account but it is being decrypted by NT SYSTEM. 更新:我确实找到了这篇文章: https//www.pdq.com/blog/secure-password-with-powershell-encrypting-credentials-part-2/ ,这表明我需要提供密码的解密密钥,因为我在我的帐户下创建了密码文件,但NT SYSTEM正在对其进行解密。 That didn't fix my issue though. 但这并没有解决我的问题。

I did more testing by simply trying to call notepad. 我只是试着打电话给记事本做了更多的测试。 It fails if I try to open it as a different user, but if I just try to open it I can see it in Task Manager running under the SYSTEM user name. 如果我尝试以不同的用户身份打开它,它会失败,但如果我只是尝试打开它,我可以在SYSTEM用户名下运行的任务管理器中看到它。

My issue really seems to be that SYSTEM (DOMAIN\\COMPUTER$) does not have the ability to run a process as a different user? 我的问题似乎是SYSTEM(DOMAIN \\ COMPUTER $)没有能力以不同的用户身份运行进程?

Run the main script commands from interactive PowerShell window as System (see: Run PowerShell as System . 从交互式PowerShell窗口以系统身份运行主脚本命令(请参阅:将PowerShell作为系统运行)

This will reveal the error: 这将揭示错误:

This command cannot be run due to the error: Access is denied. 由于错误,无法运行此命令:拒绝访问。

This issue has been described at: Powershell Start-Process : This command cannot be executed due to the error: Access is denied and is defined by the local policy: 此问题已在以下位置进行了描述: Powershell Start-Process:由于错误,此命令无法执行:访问被拒绝并由本地策略定义:

Security Settings
    Local Policies
        User Rights Assignment
            Impersonate a client after authentication

To run a script in another process, remember PowerShell always runs in the context for the user who started it, thus you need to set your script to auto-elevate / at minimu use the RunAs verb. 要在另一个进程中运行脚本,请记住PowerShell始终在启动它的用户的上下文中运行,因此您需要将脚本设置为自动提升/最小化使用RunAs动词。

Start-Process PowerShell -verb RunAs -Cred $cred -ArgumentList '-noexit','-File','path-to-script' 

or say in a notepad or other script use case... 或者在记事本或其他脚本用例中说...

Start-Process powershell -Credential mydomain\mydomainAdmin -ArgumentList '-noprofile -command &{Start-Process notepad -verb runas}'

… as the pointer you are using shows. ...作为你正在使用的指针显示。 You are not using that anywhere in the code you posted. 您没有在发布的代码中的任何位置使用它。 You must start another process separate to run as another user. 您必须单独启动另一个进程以作为另一个用户运行。

As a work around, I've created a scheduled task that runs as my serviceadmin. 作为一种解决方法,我创建了一个作为我的serviceadmin运行的计划任务。 Now when the ticketing system triggers a script that calls the scheduled task, and the scheduled task runs the second script which requires elevation. 现在,当票务系统触发调用计划任务的脚本时,计划任务运行需要提升的第二个脚本。 This is not ideal, but it does work as desired. 这并不理想,但确实可以正常工作。

The Scheduled Task (named Step 2) 计划任务(命名为步骤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 (The calling script) 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 (the called script) 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"

I am not going to mark this as the answer because it solves my problem using a work around, but it does not answer my question. 打算将此标记为答案,因为它解决了我使用解决方法的问题,但它没有回答我的问题。

My suggestion is to grant the computer account access to the directory objects in question (the most obvious way being to add the computer's account to a group that has the necessary permissions in the directory) and run the script on that computer using the SYSTEM account. 我的建议是授予计算机帐户访问相关目录对象的权限(最明显的方法是将计算机的帐户添加到目录中具有必要权限的组),并使用SYSTEM帐户在该计算机上运行脚本。 This seems to me to be the most straightforward and least complex solution for your scenario. 在我看来,这对于您的场景来说是最简单,最简单的解决方案。

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

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