Not able to capture output by runas command - windows

I have to automate test cases.
Tasks:-
Step:-Open administrative command prompt from powershell.
Step:-Execute a batch file on the administrative command prompt.
Step:-Batch file includes some set of commands, including a execution of an exe.
For Example:- runas /user:administrator /savecred someCmd.exe >>D:\output.txt
Step:-Capture output of the exe in a variable for verification of the output.
i have used "
start-process -verb runas cmd.exe $param" cmdlet for opening administrative command prompt(Step 1).
Where $param contains the batch file to be executed.
Problem Statement:- When batch file executes the runas command mentioned above, it opens a new command prompt and the output is displayed in the prompt and it closes itself.
i am not able to capture the output(not getting written in the output.txt) based on which i have to do some verification.

you can use the the output redirection from the batch :
$params="/C ipconfig /all 2>&1 >>c:\temp\test.txt"
start-process -verb runas cmd.exe $params
gc c:\temp\test.txt

I ended up creating a wrapper batch file OutputWrapper.bat that takes at least two arguments:
1) output file
2) command
3) [optional] arguments
#ECHO OFF
IF "%2" == "" GOTO usage
SET OUTPUTFILE=%1
SET COMMAND=%2
SET ARGS=
SHIFT /2
:loop1
IF "%2"=="" GOTO exec
SET ARGS=%ARGS% %2
SHIFT
GOTO loop1
:exec
ECHO Command [%COMMAND%]
ECHO Arguments [%ARGS%]
ECHO Output file [%OUTPUTFILE%]
%COMMAND%%ARGS% > %OUTPUTFILE% 2>&1
GOTO end
:usage
ECHO Usage: %~nx0 outputfile command [arguments]
:end
and calling it from PowerShell like this:
$outFile = "C:\Temp\Deploy.out";
Start-Process -FilePath .\OutputWrapper.bat -ArgumentList "$outfile","whoami.exe","/priv" -Verb RunAs -Wait
Get-Content $outFile;

Solution
Open administrative command prompt from powershell.
executed a batch file in the runas command. For example: runas /user:administrator /savecred mybatch.bat
Batch file includes some set of commands, including a execution of an exe. For example someCmd.exe >>D:\output.txt
Capture output of the exe in a variable for verification of the output.
Now the output was captured and was written into a file. My target was to capture the output of the command and this was the solution through which I solved it.

I had the same problem and solved it by the use of gsudo. It let me run the elevated command and tunneled the output back from it.
gsudo {command-to-execute}

Improvement on Loïc MICHEL's answer, as without -Wait, it's likely that Get-Content will run before the process has finished. As the output isn't written until the process ends, Get-Content fails as the file does not exist.
$param = "ipconfig /all"
$args = "/C $param 2>&1 > C:\temp\test.txt"
Start-Process -FilePath cmd.exe -ArgumentList $args -Verb RunAs -Wait
Get-Content -Path C:\temp\test.txt
Alternatively, using powershell.exe instead and a random file in the temporary directory for the OS:
$CommandWithParameters = "gpresult /scope computer /z"
$OutputFile = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ([System.IO.Path]::GetRandomFileName())
$Arguments = ("{0} 2>&1 > {1}" -f $CommandWithParameters, $OutputFile)
Start-Process -FilePath powershell.exe -ArgumentList $Arguments -Verb RunAs -Wait
Get-Content -Path $OutputFile
Using powershell.exe will save the output file using UCS-2 LE BOM encoding. If you use cmd.exe, the encoding will be ANSI.

Related

Using a cmd command in powershell script?

I am trying to make a powershell script that automatically sets up this program and requires to use a cmd command to run do it.
I know that the cmd command work and I tried cmd.exe.
cmd.exe /c "java -jar fitnesse-standalone.jar -p 9090"
Error Message:
cmd.exe : The term 'cmd.exe' is not recognized
You can use start-process
Start-Process -FilePath "cmd.exe" -ArgumentList '/c "java -jar fitnesse-standalone.jar -p 9090"'
The /c and everything following it is just part of the one set of parameters being passed to cmd. If you want powershell to wait for the the Java app to close, add the -wait parameter.
There's also no real need to use CMD at all in this case (since your giving it /c to exit immediately anyway), you can call java directly:
Start-Process -FilePath "java.exe" -ArgumentList '-jar fitnesse-standalone.jar -p 9090'
and it should be the same.
Note: you'll need Java in your path or the current working directory, and fitnesse-standalone.jar in the current directory for either of these to work.

How to start PowerShell script from BAT file with proper Working Directory?

I'm trying to create bat script that can start PowerShell script named the same as bat file in proper working directotry.
This is what I got:
#ECHO OFF
PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -WorkingDirectory '%~dp0' -Verb RunAs}"
PAUSE
Passing working directory this way does not work.
How to make script that will pass proper working directroy and also command line arguments?
The -WorkingDirectory parameter doesn't work when using -Verb RunAs. Instead, you have to set the working directory by calling cd within a -Command string.
This is what I use: (cmd/batch-file command)
powershell -command " Start-Process PowerShell -Verb RunAs \""-Command `\""cd '%cd%'; & 'PathToPS1File';`\""\"" "
If you want to make a "Run script as admin" right-click command in Windows Explorer, create a new registry key at HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Run with PowerShell (Admin)\Command, and set its value to the command above -- except replacing %cd% with %W, and PathToPS1File with %1 (if you want it to execute the right-clicked file).
Result: (Windows Explorer context-menu shell command)
powershell -command " Start-Process PowerShell -Verb RunAs \""-Command `\""cd '%W'; & '%1';`\""\"" "
EDIT: There's an alternative way to have the script be run as admin from Explorer, by using the "runas" sub-key: https://winaero.com/blog/run-as-administrator-context-menu-for-power-shell-ps1-files
If you want to run your script as admin from an existing powershell, remove the outer powershell call, replace %W with $pwd, replace %1 with the ps1 file-path, and replace each \"" with just ".
Note: The \""'s are just escaped quotes, for when calling from the Windows shell/command-line (it's quote-handling is terrible). In this particular case, just \" should also work, but I use the more robust \"" for easier extension.
See here for more info: https://stackoverflow.com/a/31413730/2441655
Result: (PowerShell command)
Start-Process PowerShell -Verb RunAs "-Command `"cd '$pwd'; & 'PathToPS1File';`""
Important note: The commands above are assuming that your computer has already been configured to allow script execution. If that's not the case, you may need to add -ExecutionPolicy Bypass to your powershell flags. (you may also want -NoProfile to avoid running profile scripts)
A workaround is to let the PowerShell script change the directory to it's own origin with:
Set-Location (Split-Path $MyInvocation.MyCommand.Path)
as the first command.
As per mklement0s hint: In PSv3+ use the simpler:
Set-Location -LiteralPath $PSScriptRoot
Or use this directory to open adjacent files.
$MyDir = Split-Path $MyInvocation.MyCommand.Path
$Content = Get-Content (Join-Path $MyDir OtherFile.txt)

How to pass quoted arguments to elevated batch script via powershell Start-Process

I have a really hard time passing quotes to .bat files when elevating, binaries seem to work thou... steps to reproduce:
create a small test batch script %TEMP%\test.bat containing
echo.%* && pause
Fire up powershell and try those:
# both behave like expected, echoing hello and pausing
saps -filepath cmd -argumentlist '/c echo.hello && pause'
saps -filepath "$env:TEMP\test.bat" -argumentlist 'hello'
# both behave like expected, echoing "hello" and pausing
saps -filepath cmd -argumentlist '/c echo."hello" && pause'
saps -filepath "$env:TEMP\test.bat" -argumentlist '"hello"'
# both behave like expected, echoing an elevated hello and pausing
saps -verb runas -filepath cmd -argumentlist '/c echo.hello && pause'
saps -verb runas -filepath "$env:TEMP\test.bat" -argumentlist 'hello'
# cmd still echoes correctly "hell"no and pauses
saps -verb runas -filepath cmd -argumentlist '/c echo."hell"no && pause'
# tl;dr
# now this is where hell breaks loose
saps -verb runas -filepath "$env:TEMP\test.bat" -argumentlist '"hell"no'
# doesnt echo anything, window pops up and vanishes in an instant
# doesnt pause
The "runas" verb doesn't work if you invoke it directly on a batch file. You need to invoke it on the actual executable (i.e. cmd.exe) and pass the batch file as an argument.
$params = '/c', "$env:TEMP\test.bat", '"hell"no'
Start-Process -Verb Runas -FilePath $env:ComSpec -ArgumentList $params

powershell command output logging in batch script

I need to write this command to a bat file in a specific location:
echo PowerShell -Command "Set-ExecutionPolicy Unrestricted" >> "C:\Users\ADMINI~1\AppData\Local\Temp\2\StartupLog.txt" >> c:\myscript.bat
When I run this command it will only write PowerShell -Command "Set-ExecutionPolicy Unrestricted in myscript.bat.
I need to write the full command with the output file logging. Is this possible to do this?
Thanks!
Read Syntax : Escape Characters, Delimiters and Quotes and apply it as follows:
echo PowerShell -Command "Set-ExecutionPolicy Unrestricted" ^>^> "C:\Users\ADMINI~1\AppData\Local\Temp\2\StartupLog.txt" >> c:\myscript.bat
Proof (copy & paste from a cmd window, so lines are wrapped):
d:\bat> type myscript.bat
The system cannot find the file specified.
d:\bat> echo PowerShell -Command "Set-ExecutionPolicy Unrestricted" ^>^> "C:\Users\ADMINI~1\
AppData\Local\Temp\2\StartupLog.txt" >> myscript.bat
d:\bat> type myscript.bat
PowerShell -Command "Set-ExecutionPolicy Unrestricted" >> "C:\Users\ADMINI~1\AppData\Local\T
emp\2\StartupLog.txt"
d:\bat>

How to pass variable from Batch File to a Powershell Script

I have a batch file that copies user files from one computer to another networked computer.
#echo off
cls
#echo Type the old Computer Name
set /p asset=
REM robocopy.exe \\%asset%\c$\ C:\ /S /Z /XJD /XJ /XA:SH /XA:T /XD "Dir1" "Dir2" /XF *.dll *.log *.txt *.exe /log+:"\\server\path\%asset%-to-%computername%-Transfer.log" /NP /FP /V /TEE
PowerShell.exe -Command "& {Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -Verb RunAs}"
pause
This is my PowerShell script:
$source = "\\${env:asset}\C$\Temp\Source"
$dest = "C:\Temp\Dest"
Write-Output $source
Read-Host "Press ENTER to quit"
I then need to call a PowerShell script that invokes an admin login, then pass the %asset% and %useraiu% variables.
I can't seem to figure out how to pass the %asset% and %useraiu% from my batch file to the PowerShell script.
I have found that if you are calling the Powershell script from a batch file and need to have the Powershell script run with admin, you would need to use this syntax.
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File """"%~dpn0.ps1"""" """"%asset%"""" ' -Verb RunAs}"
The PowerShell script name and parameters need to be wrapped in 4 double quotes in order to properly handle paths/values with spaces
This is the only solution that worked for me so far.

Resources