这个命令对我有用:
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:\>