【问题标题】:Running PowerShell as another user, and launching a script以其他用户身份运行 PowerShell,并启动脚本
【发布时间】:2015-03-11 14:47:25
【问题描述】:

我不会详细说明我为什么需要它,但用户必须能够将 PowerShell 作为服务帐户启动,并且当 PowerShell 加载时它需要运行脚本。我已经可以使用存储的凭据(存储为安全字符串)启动 PowerShell,但是对于我来说,我无法让脚本(位于 $args 中)运行。我尝试了很多东西,下面是我目前的位置。任何帮助将不胜感激。

$user = "domain\service.account" 
$pwd1 = "big long huge string of characters"
$pwd = ($pwd1 | ConvertTo-SecureString)
$Credential = New-Object System.Management.Automation.PSCredential $user, $pwd
$args = "\\domain.local\location\location\location\Script\script.ps1"
Start-Process powershell.exe -Credential $Credential -ArgumentList ("-file $args")

【问题讨论】:

  • 当我尝试以其他用户身份运行时,没有任何反应。我的服务器中是否有某种针对此的政策?

标签: powershell runas


【解决方案1】:

您可以像这样在指定的用户凭据下打开一个新的 powershell 窗口:

start powershell -credential ""

【讨论】:

  • 不知何故,当我使用这种方法时,我无法在新打开的 powershell 窗口中输入任何内容。不过,使用来自stackoverflow.com/a/44797801/1108916 的技巧是可行的。叹息。
  • 哦,奇怪,如果关闭父powershell窗口,新的子窗口可以接收键盘输入
  • 因为,这是windows默认的特性。
【解决方案2】:

我发现这对我有用。

$username = 'user'
$password = 'password'

$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Start-Process Notepad.exe -Credential $credential

更新:改为使用单引号以避免 Paddy 指出的特殊字符问题。

【讨论】:

  • 我必须将密码放在单引号中,因为它包含“特殊”字符。您可以通过在提示符处写入$password来检查密码是否已正确存储,它将打印存储在变量中的内容
  • 在实践中可能最好默认使用单引号。有助于避免意外问题的出现——在您打算将双引号用于特定目的时保存它们。
  • 我觉得这应该是人们因执行限制而面临的所有“运行方式”问题的首选解决方案。就个人而言,我在 SO 上尝试了很多解决方案,发现这是唯一可行的解​​决方案。
  • 安全说明 这会将密码以纯文本形式存储在脚本中,这通常是个坏主意。
  • @user202729 很好。确保不要将密码存储在脚本中!从环境变量或其他数据存储中提取它们。
【解决方案3】:

这也是通过 UI 实现此目的的好方法。

0) 在任务栏上右键单击 PowerShell 图标

1) Shift + 右键单击​​ Windows PowerShell

2) “以不同用户身份运行”

【讨论】:

    【解决方案4】:

    尝试将RunAs 选项添加到您的Start-Process

    Start-Process powershell.exe -Credential $Credential -Verb RunAs -ArgumentList ("-file $args")
    

    【讨论】:

    • 谢谢,我终于看到了凭据提示的原因。使用的大量字符串太大,所以我需要查看用于存储和/或转换此密码的其他选项。
    • 添加 -Verb RunAs 给我一个 Parameter set cannot be resolved using the specified named parameters. 我的其他参数是 -Wait、-Credential $creds、-WorkingDirectory C:\ -ArgumentList "..." 这是使用 powershell 5。跨度>
    【解决方案5】:

    在 Windows Server 2012 或 2016 中,您可以搜索 Windows PowerShell,然后搜索“Pin to Start”。在此之后,您将在起始页图块上右键单击“以其他用户身份运行”选项。

    【讨论】:

      【解决方案6】:

      您可以获得一个凭据弹出窗口,它将用户名和密码作为字符串获取,如下所示:

      #Get credentials
      $credential = Get-Credential
      $username = $credential.Username
      $password = $credential.GetNetworkCredential().Password
      

      然后您可以在脚本中使用变量 $username 和 $password

      【讨论】:

        【解决方案7】:

        这个命令对我有用:

        Start-Process powershell.exe -Credential $Credential -ArgumentList "-file $FILE"
        

        如果$FILE 在网络上,请确保运行方式用户可以访问该文件。


        脚本

        我刚刚创建了一个脚本来简化自动化:

         <#
        
        .SYNOPSIS
        
        Run command as another user.
        
        .DESCRIPTION
        
        Run batch or PowerShell command as another user.
        
        .PARAMETER Command
        
        The batch command you'd like to execute as another user.
        
        .PARAMETER ScriptBlock
        
        The PowerShell command you'd like to execute as another user.
        
        .PARAMETER Username
        
        Run the command as what user.
        
        .PARAMETER Password
        
        Password of the user.
        
        .PARAMETER Credential
        
        PowerShell credential of the user, it can be generated by `Get-Credential`.
        
        .PARAMETER Wait
        
        Wait command to complete or not.
        Command output would not be displayed if it is not specified.
        
        #>
        
        Param (
            [Parameter(Mandatory = $true, ParameterSetName = "bat-user-password")]
            [Parameter(Mandatory = $true, ParameterSetName = "bat-credential")]
            [ValidateNotNullOrEmpty()]
            [String]
            $Command,
        
            [Parameter(Mandatory = $true, ParameterSetName = "ps-user-password")]
            [Parameter(Mandatory = $true, ParameterSetName = "ps-credential")]
            [ScriptBlock]
            $ScriptBlock,
        
            [Parameter(Mandatory = $true, ParameterSetName = "bat-user-password")]
            [Parameter(Mandatory = $true, ParameterSetName = "ps-user-password")]
            [ValidateNotNullOrEmpty()]
            [String]
            $Username,
        
            [Parameter(Mandatory = $true, ParameterSetName = "bat-user-password")]
            [Parameter(Mandatory = $true, ParameterSetName = "ps-user-password")]
            [ValidateNotNullOrEmpty()]
            [String]
            $Password,
        
            [Parameter(Mandatory = $true, ParameterSetName = "bat-credential")]
            [Parameter(Mandatory = $true, ParameterSetName = "ps-credential")]
            [PSCredential]
            $Credential,
        
            [Switch]
            $Wait
        )
        
        $IsCurrentAdminUser = $([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')
        
        # Find a dir that every user have full access to
        $TempDir = "$env:SystemDrive\Users\Public\run_as"
        if (-not (Test-Path -Path $TempDir)) {
            $null = New-Item -Path $TempDir -ItemType Directory
            attrib +h $TempDir
        }
        
        # Generate a uniq id for problem tracking
        $ExecId = Get-Random -Maximum 99999999 -Minimum 10000000
        
        # Temp files
        $UserScriptPrefix = "$TempDir\$ExecId-UserScript"
        $UserStdOut = "$TempDir\$ExecId-UserStdOut.log"
        $UserErrOut = "$TempDir\$ExecId-UserErrOut.log"
        $WaitFile = "$TempDir\$ExecId-Running"
        
        $ExecScript = "$TempDir\$ExecId-Exec.ps1"
        $CmdToExec = "Start-Process"
        
        if ($PsCmdlet.ParameterSetName.StartsWith('bat')) {
            $UserScript = $UserScriptPrefix + '.bat'
            $Command |Out-File -FilePath $UserScript -Encoding ascii
        
            $CmdToExec += " cmd.exe -ArgumentList '/c $UserScript'"
        } elseif ($PsCmdlet.ParameterSetName.StartsWith('ps')) {
            $UserScript = $UserScriptPrefix + '.ps1'
            $ScriptBlock |Out-File -FilePath $UserScript -Encoding ascii
        
            $CmdToExec += " PowerShell.exe -ArgumentList '-file $UserScript'"
        }
        
        if ($PsCmdlet.ParameterSetName.EndsWith('user-password')) {
            $SecPassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
            $Credential = New-Object -TypeName System.Management.Automation.PSCredential ($Username, $SecPassword)
        }
        
        $CmdToExec += " -WorkingDirectory $env:SystemDrive\"
        
        if ($Wait) {
            # Redirect output only if -Wait flag is set
            $CmdToExec += " -RedirectStandardError $UserErrOut"
            $CmdToExec += " -RedirectStandardOutput $UserStdOut"
        
            if ($IsCurrentAdminUser) {
                # -Wait parameter of Start-Process only works with admin users
                # Using it with non-admin users will get an "Access is denied" error
                $CmdToExec += " -Wait"
            }
        }
        
        $script = @'
        Param($Cred)
        "" | Out-File -FilePath {0}
        
        try {{
            {1} -Credential $Cred
        }} catch {{
            Write-Host $_
        }} finally {{
            Remove-Item -Path {0} -Force -Confirm:$false
        }}
        '@ -f $WaitFile, $CmdToExec
        
        $Script |Out-File -FilePath $ExecScript -Encoding ascii
        
        try {
            & $ExecScript -Cred $Credential
        } catch {
            Write-Host $_
        } finally {
            if ($Wait) {
                if (-not $IsCurrentAdminUser) {
                    # Impelment the wait by file monitoring for non-admin users
                    do {
                        Start-Sleep -Seconds 1
                    } while (Test-Path -Path $WaitFile)
            
                    # Wait output are write to files completely
                    Start-Sleep -Seconds 1
                }
        
                # Read command output from files
                if (Test-Path -Path $UserStdOut) {
                    Get-Content -Path $UserStdOut
                }
        
                if (Test-Path -Path $UserErrOut) {
                    Get-Content -Path $UserErrOut
                }
            }
        
            Remove-Item -Path "$TempDir\$ExecId-*" -Force -Confirm:$false -ErrorAction SilentlyContinue
        }
        

        复制内容并保存到*.ps1 文件,例如run_as.ps1

        文档

        显示内置文档:

        PS C:\> Get-Help C:\run_as.ps1 -detailed
        
        NAME
            C:\run_as.ps1
        
        SYNOPSIS
            Run command as another user.
        
        
        SYNTAX
            C:\run_as.ps1 -Command <String> -Credential <PSCredential> [-Wait] [<CommonParameters>]
        
            C:\run_as.ps1 -Command <String> -Username <String> -Password <String> [-Wait] [<CommonParameters>]
        
            C:\run_as.ps1 -ScriptBlock <ScriptBlock> -Credential <PSCredential> [-Wait] [<CommonParameters>]
        
            C:\run_as.ps1 -ScriptBlock <ScriptBlock> -Username <String> -Password <String> [-Wait] [<CommonParameters>]
        
        
        DESCRIPTION
            Run batch or PowerShell command as another user.
        
        
        PARAMETERS
        ......
        

        示例

        01

        当前用户是管理员,以user01身份运行批处理命令并输入密码

        PS C:\> whoami
        test-win-1\administrator
        PS C:\> .\run_as.ps1 -Command 'whoami' -Username 'user01' -Password 'password1'
        PS C:\> 
        PS C:\> # Add -Wait to get command output
        PS C:\> .\run_as.ps1 -Command 'whoami' -Username 'user01' -Password 'password1' -Wait
        
        C:\>whoami
        test-win-1\user01
        PS C:\> 
        PS C:\> # Add '@' to batch command to avoid the header lines
        PS C:\> .\run_as.ps1 -Command '@whoami' -Username 'user01' -Password 'password1' -Wait
        test-win-1\user01
        PS C:\>
        

        02

        当前用户是管理员,以 user02 身份运行 PowerShell 命令并输入密码

        PS C:\> $env:USERPROFILE
        C:\Users\Administrator
        PS C:\> .\run_as.ps1 -ScriptBlock {$env:USERPROFILE} -Username 'user02' -Password 'password2' -Wait
        C:\Users\user02
        PS C:\>
        

        03

        当前用户是管理员,以 user02 身份运行 PowerShell 命令及其凭据

        PS C:\> $env:USERPROFILE
        C:\Users\Administrator
        PS C:\> $cred = Get-Credential user02    # input user02's password in the pop-up window
        PS C:\> .\run_as.ps1 -ScriptBlock {$env:USERPROFILE} -Credential $cred -Wait
        C:\Users\user02
        PS C:\>
        

        04

        当前用户为user01,以管理员身份运行PowerShell命令

        PS C:\> $(Get-ChildItem C:\Users\Administrator\).FullName                                                                                 
        Get-ChildItem : Access to the path 'C:\Users\Administrator' is denied.                                                                    
        At line:1 char:3                                                                                                                          
        + $(Get-ChildItem C:\Users\Administrator\).FullName                                                                                       
        +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                                                 
            + CategoryInfo          : PermissionDenied: (C:\Users\Administrator\:String) [Get-ChildItem], UnauthorizedAccessException             
            + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand                                
                                                                                                                                                
        PS C:\> whoami                                                                                                                            
        test-win-1\user01                                                                                                                         
        PS C:\> # Standard user cannot access administrator user's home directory
        PS C:\> 
        PS C:\> .\run_as.ps1 -ScriptBlock {$(Get-ChildItem C:\Users\Administrator\).FullName} -Username Administrator -Password 'adminpasswd' -Wait  
        C:\Users\Administrator\.vscode                                                                                                            
        C:\Users\Administrator\3D Objects                                                                                                         
        C:\Users\Administrator\Contacts                                                                                                           
        C:\Users\Administrator\Desktop                                                                                                            
        C:\Users\Administrator\Documents                                                                                                          
        C:\Users\Administrator\Downloads                                                                                                          
        C:\Users\Administrator\Favorites                                                                                                          
        C:\Users\Administrator\Links                                                                                                              
        C:\Users\Administrator\Music                                                                                                              
        C:\Users\Administrator\Pictures                                                                                                           
        C:\Users\Administrator\Saved Games                                                                                                        
        C:\Users\Administrator\Searches                                                                                                           
        C:\Users\Administrator\Videos                                                                                                             
        PS C:\>                                                                                                                                   
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-30
          • 1970-01-01
          • 2012-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多