I won't get into all the details of why I need this, but users must be able to launch PowerShell as a service account and when PowerShell loads it needs to run a script. I already can launch PowerShell with the stored credentials (stored as a secure string), but for the life of me I cannot get the script (located in $args) to run. I have tried a variety of things, and below is where I am currently. Any help would be greatly appreciated.
$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")
You can open a new powershell window under a specified user credential like this:
start powershell -credential ""
I found this worked for me.
$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
Updated: changed to using single quotes to avoid special character issues noted by Paddy.
Here's also nice way to achieve this via UI.
0) Right click on PowerShell icon when on task bar
1) Shift + right click on Windows PowerShell
2) "Run as different user"
Try adding the RunAs option to your Start-Process
Start-Process powershell.exe -Credential $Credential -Verb RunAs -ArgumentList ("-file $args")
In windows server 2012 or 2016 you can search for Windows PowerShell and then "Pin to Start". After this you will see "Run as different user" option on a right click on the start page tiles.
You can get a credential popup that will get the username and password as strings like this:
#Get credentials
$credential = Get-Credential
$username = $credential.Username
$password = $credential.GetNetworkCredential().Password
Then you can use in your script the variables $username and $password
This command works for me:
Start-Process powershell.exe -Credential $Credential -ArgumentList "-file $FILE"
If the $FILE is on network, make sure the run-as user can access the file.
Script
I just created a script to make it easier for automation:
<#
.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
}
Copy the content and save to a *.ps1 file, like run_as.ps1.
Document
Show build-in doucment:
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
......
Examples
01
Current user is administrator, run batch command as user01 with password
Note: Please DO NOT use plain password in production environment. You can use it for testing.
In a production environment, you can use -Credential option instead.
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
Current user is administrator, run PowerShell command as user02 with password
Note: Please DO NOT use plain password in production environment. You can use it for testing.
In a production environment, you can use -Credential option instead.
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
Current user is administrator, run PowerShell command as user02 with its credential
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
Current user is user01, run PowerShell command as administrator
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:\>
This worked for me. This is helpful in remote servers where you just a have remote command line tool available to use.
runas /user:Administrator "powershell Start-Transcript -Path C:\Users\m\testlog.txt;import-module 'C:\Users\m\script.ps1';Stop-Transcript"
This will also ensure that you can get the output of the command in testlog.txt
Related
I've got a bug on some of my users computers and I need my users to launch a .ps1 from their computer to fix the problem so i can access to their computer when they need it through NetSupport.
Problem is that they don't have administrator rights on their computer.
So this is what I did already :
Encrypt an admin password in a .txt (this one will be launch by me with administrative rights)
Function RandomKey {
$RKey = #()
For ($i=1; $i -le 16; $i++) {
[Byte]$RByte = Get-Random -Minimum 0 -Maximum 256
$RKey += $RByte
}
$RKey
}
$Key = RandomKey
$key |Out-File "$path\Key.txt"
Read-Host "Enter one admin Password" -assecurestring | ConvertFrom-SecureString -key $Key | Out-file "$path\EncKey.txt"
This part seems to work fine.
Now, come the working "client" part :
$PassKey = get-content "$Path\Key.txt"
$Password = get-content "$Path\EncKey.txt" | Convertto-SecureString -Key $PassKey
$User = Read-Host "Enter the ID given by your administrator"
$credentials = New-Object System.Management.Automation.Pscredential `
-Argumentlist $User,$Password
And the not working one (I tried a lot of things here some exemple) :
1 : When I set the local administrator (.\administrator) a new powershell Windows start with administrator rights but doesn't do what the file.ps1 is supposed to do, and if I set domain\adminaccount it just start a new posershell windows but without admin rights.
Start-Process powershell -Credential $credentials -ArgumentList '-noprofile -command &{Start-Process powershell -ArgumentList "-file "\\serveur\path\file.ps1" "}'
2 : When I set the local administrator (.\administrator) a new powershell Windows start with administrator rights but only half of the script (file.ps1) works, and if I set domain\adminaccount : same as above.
Invoke-Item (Start-Process powershell.exe -Credential $credentials ((Split-Path $MyInvocation.InvocationName) + "\\serveur\path\file.ps1" ))
3 and so on
Start-Process powershell -ArgumentList '-executionpolicy, bypass, -file "\\serveur\path\file.ps1", -Credential $credentials, -verb RunAs'
Start-Process -filepath "\\serveur\path\file.ps1" -Credential $credentials -ArgumentList '-noprofile -noexit -command -verb runas}'
Start-Process powershell -Credential $credentials -ArgumentList '-noprofile -command &{Start-Process powershell -ArgumentList "-file "\\serveur\path\file.ps1" "}'
But nothing works as expected...
If you guys have an idea it'll be wonderfull !!
--------------------- EDIT ----------------
I did a mistake in my file.ps1, so
Invoke-Item (Start-Process powershell.exe -Credential $credentials ((Split-Path $MyInvocation.InvocationName) + "\\serveur\path\file.ps1" ))
This work fine with local admin (.\administrator), the script does start with admin rights and works as expected.
BUT... it doesn't work with domaine admin (domain\admin) : the script does start, but without admin rights...
Can you try using this script ?
I was able to call this as below and get an elevated session.
Invoke-Elevated -FilePath \\server\share\file.ps1
If someone interested by the solution I found to make it work with local administrator account here it is :
Couldn't make it work with the file.ps1 I wanted to execute on a UNC path.
So I had to copy it 1st on the local computer executing the script.
$path="[...]\temp"
$source= "[...]file.ps1"
$destination = "c:\users\$env:USERNAME\documents"
if (!(Test-Path "$destination\Netlogon_Firewall.ps1")){Copy-Item -Path $source -Destination $destination}
Then I import my credentials :
$PassKey = get-content "$Path\Key.txt"
$Password = get-content "$Path\EncKey.txt" | Convertto-SecureString -Key $PassKey
$User = Read-Host "Enter the ID given by your administrator"
$credentials = New-Object System.Management.Automation.Pscredential `
-Argumentlist $User,$Password
And finaly i can start the file.ps1 script with administrator rights :
Start-Process -Credential $Credentials "$PSHOME\powershell.exe" -WorkingDirectory "C:\Users\$env:USERNAME" -ArgumentList "-ExecutionPolicy Bypass & '$destination\file.ps1'"
I'm trying to invoke discrete CLI commands on a series of remote systems via a script, and I can't get any PowerShell commands to accept them. Rather than try to explain the specifics of the issue, I'll provide some pseudocode of what I'm trying to do below.
Please note that this is just a simple example. Using the stop-service command is not an option. These are explicit commands used via CLI with via the Splunk program that I need to run in this order.
In short, I just can not figure out how to tell PowerShell to run a CLI command verbatim on a remote machine.
foreach ($server in $list)
cd C:\Program Files\SplunkUniversalForwarder\bin
splunk stop
splunk clone-prep-clear-config
splunk start
Bunch of ways you can do this. Using WMI c/o Powershell:
Starting,Stopping and Restarting Remote Services with PowerShell
You can also use Windows remoting, but I'd start here.
You could try...
Foreach($server in $list)
{
Invoke-command -computername $server -scripblock {
$splunkpath = 'c:\program files\splunkuniversalforwarder\bin\splunk.exe'
Start-process -filepath $splunkpath -argumentlist 'stop' -wait -nonewwindow
Start-process -filepath $splunkpath -argumentlist 'clone-prep-clear-config' -wait -nonewwindow
Start-process -filepath $splunkpath -argumentlist 'start' -wait -nonewwindow
}
}
Note: you may need to remove the -wait and/or -nonewwindow from the commands depending on how your process behaves.
There are also output redirection parameters checkout the docs below for more.
Invoke-command
Start-process
I literally just did this this morning. This is the main part I came up with.
foreach($server in $servers){
Write-Host "From " -nonewline; Write-Host "$server" -ForegroundColor Yellow
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe stop } -Credential $cred
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe clone-prep-clear-config } -Credential $cred
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe start } -Credential $cred
}
my full code is below:
#Author: Christopher Boillot
#Clear config of Splunk Forwarder
[CmdletBinding()]
Param ([Parameter(Mandatory=$False,Position=0)]
[String[]]$servers = (Get-Content C:\ClearConfig.txt))
Set-Location $PSScriptRoot
#User login
$User = "user.txt"
$FileExists = Test-Path $User
If ($FileExists -eq $False) {
Write-Host "Enter your user name. This will be saved as $User"
read-host | out-file $User
}
$Pass = "securepass.txt"
$FileExists = Test-Path $Pass
If ($FileExists -eq $False) {
Write-Host "Enter your password. This will be saved as an encrypted sting as $Pass"
read-host -assecurestring | convertfrom-securestring | out-file $Pass
}
$username = cat $User
$password = cat $Pass | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $password
#go through each server in list
foreach($server in $servers){
Write-Host "From " -nonewline; Write-Host "$server" -ForegroundColor Yellow
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe stop } -Credential $cred
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe clone-prep-clear-config } -Credential $cred
Invoke-Command -ComputerName $server -ScriptBlock { C:\SplunkUniversalForwarder\bin\splunk.exe start } -Credential $cred
}
I need a help
I have trouble to set a script in powershell that give DOMAIN adminsitrator rights to an User to an executable . Because I need to install a program in many desktops, plus I need to check if the program is already installed.
This seams to be easy but I know how to program in shell script not much powershell.
$SPAdmin = "DOMAIN\ADMIN"
$Password="FooBoo"|ConvertTo-SecureString -AsPlainText -Force
$Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $SPAdmin, $Password
Get-WmiObject -Class Win32_Service -ComputerName "Server" -Filter "Name='ServiceName'" -Credential $Credential
$name = "CagService"
if (Get-Service $name -ErrorAction SilentlyContinue)
{
Write-Host "O Servico do Agente conhecido como $name ja esta Instalado na Maquina com Hostname: $env:computername"
sleep 5
}
Else
{
$storageDir = $pwd
$source = "https://source"
$destination = "$storageDir\agent.exe"
Invoke-WebRequest $source -OutFile $destination
$exec = New-Object -com shell.application
$exec.shellexecute($destination);
}
Is there any reason that you can't simply do:
Start-Process powershell -Verb runAs
From a PS console? That launches a new ps window with admin privileges....
PowerShell: Running a command as Administrator
I won't get into all the details of why I need this, but users must be able to launch PowerShell as a service account and when PowerShell loads it needs to run a script. I already can launch PowerShell with the stored credentials (stored as a secure string), but for the life of me I cannot get the script (located in $args) to run. I have tried a variety of things, and below is where I am currently. Any help would be greatly appreciated.
$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")
You can open a new powershell window under a specified user credential like this:
start powershell -credential ""
I found this worked for me.
$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
Updated: changed to using single quotes to avoid special character issues noted by Paddy.
Here's also nice way to achieve this via UI.
0) Right click on PowerShell icon when on task bar
1) Shift + right click on Windows PowerShell
2) "Run as different user"
Try adding the RunAs option to your Start-Process
Start-Process powershell.exe -Credential $Credential -Verb RunAs -ArgumentList ("-file $args")
In windows server 2012 or 2016 you can search for Windows PowerShell and then "Pin to Start". After this you will see "Run as different user" option on a right click on the start page tiles.
You can get a credential popup that will get the username and password as strings like this:
#Get credentials
$credential = Get-Credential
$username = $credential.Username
$password = $credential.GetNetworkCredential().Password
Then you can use in your script the variables $username and $password
This command works for me:
Start-Process powershell.exe -Credential $Credential -ArgumentList "-file $FILE"
If the $FILE is on network, make sure the run-as user can access the file.
Script
I just created a script to make it easier for automation:
<#
.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
}
Copy the content and save to a *.ps1 file, like run_as.ps1.
Document
Show build-in doucment:
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
......
Examples
01
Current user is administrator, run batch command as user01 with password
Note: Please DO NOT use plain password in production environment. You can use it for testing.
In a production environment, you can use -Credential option instead.
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
Current user is administrator, run PowerShell command as user02 with password
Note: Please DO NOT use plain password in production environment. You can use it for testing.
In a production environment, you can use -Credential option instead.
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
Current user is administrator, run PowerShell command as user02 with its credential
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
Current user is user01, run PowerShell command as administrator
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:\>
This worked for me. This is helpful in remote servers where you just a have remote command line tool available to use.
runas /user:Administrator "powershell Start-Transcript -Path C:\Users\m\testlog.txt;import-module 'C:\Users\m\script.ps1';Stop-Transcript"
This will also ensure that you can get the output of the command in testlog.txt
I have a script for remotely executing commands on other machines, however... when using windows cmd.exe commands It does not write to the file on the remote server. Here is the code.
$server = 'serverName'
$Username = 'userName'
$Password = 'passWord'
$cmd = "cmd /c ipconfig"
########################
########################
$ph = "C:\mPcO.txt"
$rph = "\\$server\C$\mPcO.txt"
$cmde = "$cmd > $ph"
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$mycred = new-object -typename System.Management.Automation.PSCredential -argumentlist "$Username",$pass
Invoke-WmiMethod win32_process -name create -ComputerName $server -ArgumentList $cmde Credential $mycred
cmd /c net use \\$server\C$ $password /USER:$username
Get-Content $rph
Remove-Item $rph
cmd /c net use \\$server\C$ /delete
As you can see we simply write
$cmde = "$cmd > $ph"
if I use a PowerShell command I use
$cmde = "$cmd | Out-File $ph"
and it works fine. Any advice Appreciated
Why are you doing it the hard way? You can use WMI to get the IP details of a remote computer.
Get-WMIObject -ComputerName "RemoteServer" Win32_NetworkAdapterConfiguration -Filter "IPEnabled=$true" | Out-File $env:TEMP\ipdetails.txt
Now, once you have that file, you can move it using the commands you had in your script.