How to call batch from powershell so I can see realtime output in powershell console - powershell

I need to call batch from powershell with specific working directory. I don't want new console to be opened, but I would like to see the output of the batch as a part of the output from powershell script.
I could forward the standard output to file and then write it by Write-Host, but the batch takes time and I would like to see the output in realtime as it is processing.
I tried Process-Start, but I don't know how to redirect standard output of batch to standard output of powershell.

You can add 'cmd /c ' to your ps script, and to change directories, you can use #jisaak suggestion, so:
$wd = Get-Location;
Set-Location "batch file directory";
cmd /c "Your batch";
Set-Location $wd;
That will open a new cmd in the current console and all the output will be directed to it(when the batch will reach EOF the cmd terminates).

Related

How to execute .cmd file within powershell script?

I have cmd file, look like this
set Name=Joy
I want to execute that cmd file within my powershell script, then I want to see the value of cmd file from command line with command echo %Name% and It should show Joy.
But I can not figure it out, I tried this way, but its not working,
1st Way
$File = Get-Command .\TEST.cmd
& .\TEST2.cmd
2nd Way
Invoke-Expression ".\TEST.cmd"
3rd Way
&.\TEST.cmd

Running CMD command in PowerShell

I am having a bunch of issues with getting a PowerShell command to run. All it is doing is running a command that would be run in a CMD prompt window.
Here is the command:
"C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe" PCNAME
I have tried the following with no success (I have tried many iterations of this to try and get one that works. Syntax is probably all screwed up):
$TEXT = $textbox.Text #$textbox is where the user enters the PC name.
$CMDCOMMAND = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe"
Start-Process '"$CMDCOMMAND" $TEXT'
#iex -Command ('"C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe"' $TEXT)
The command will just open SCCM remote connection window to the computer the user specifies in the text box.
Try this:
& "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe" PCNAME
To PowerShell a string "..." is just a string and PowerShell evaluates it by echoing it to the screen. To get PowerShell to execute the command whose name is in a string, you use the call operator &.
To run or convert batch files externally from PowerShell (particularly if you wish to sign all your scheduled task scripts with a certificate) I simply create a PowerShell script, e.g. deletefolders.ps1.
Input the following into the script:
cmd.exe /c "rd /s /q C:\#TEMP\test1"
cmd.exe /c "rd /s /q C:\#TEMP\test2"
cmd.exe /c "rd /s /q C:\#TEMP\test3"
*Each command needs to be put on a new line calling cmd.exe again.
This script can now be signed and run from PowerShell outputting the commands to command prompt / cmd directly.
It is a much safer way than running batch files!
One solution would be to pipe your command from PowerShell to CMD. Running the following command will pipe the notepad.exe command over to CMD, which will then open the Notepad application.
PS C:\> "notepad.exe" | cmd
Once the command has run in CMD, you will be returned to a PowerShell prompt, and can continue running your PowerShell script.
Edits
CMD's Startup Message is Shown
As mklement0 points out, this method shows CMD's startup message. If you were to copy the output using the method above into another terminal, the startup message will be copied along with it.
For those who may need this info:
I figured out that you can pretty much run a command that's in your PATH from a PS script, and it should work.
Sometimes you may have to pre-launch this command with cmd.exe /c
Examples
Calling git from a PS script
I had to repackage a git client wrapped in Chocolatey (for those who may not know, it's a package manager for Windows) which massively uses PS scripts.
I found out that, once git is in the PATH, commands like
$ca_bundle = git config --get http.sslCAInfo
will store the location of git crt file in $ca_bundle variable.
Looking for an App
Another example that is a combination of the present SO post and this SO post is the use of where command
$java_exe = cmd.exe /c where java
will store the location of java.exe file in $java_exe variable.
You must use the Invoke-Command cmdlet to launch this external program. Normally it works without an effort.
If you need more than one command you should use the Invoke-Expression cmdlet with the -scriptblock option.

How to get Powershell result from inner start-processs

I have a ps script like:
Start-Process powershell -Verb runAs -ArgumentList "Get-WebApplication"
Because Get-WebApplication needs admin right, so I use "-verb runAs".
My question is: now the result only shows in the new powershell windows. How can I make my main powershell get/display the result?
You have two choices that I see:
Run your script as administrator and just run Get-WebApplication directly.
Capture the output from the powershell process you're starting with Start-process and then do whatever you want with the output in your script. To capture the output you can either redirect the output to a file and then read the file in your script, or you can use .NET [diagnostics.process]::start to redirect stdout and directly read the output stream in your script (no file is created).

VB equivalent to powershell

I am very new to powershell and sometimes this question may be so simple
Can please anybody please tell me what is the equivalent to the following(vbscript) in PowerShell
set obj = wscript.createobject( wscript.shell )
Obj.Run $smCmnd
What is the use of wscript.shell.
After a bit of search I found first line can be presented as;
$obj = New-Object -ComObject WScript.Shell
But have have no idea how to call Run method ($obj.run(...)???)
If I run cmd.exe with some commands as the smCmnd, How can I keep cmd.exe without close and to run another command later in same console??
EDIT
I am writing PS script and it will be call from another application. Basically it will do some folder creations and file coping etc. I would like to open CMD.exe and show all the commands running on that. How to use same cmd prompt through out my whole script.
Is smCmnd a string of shell commands? If so, you can call them directly from PowerShell, without trying to get a wscript.shell COM object to run them against like you'd need to do in VBScript.
VBScript wasn't a shell. Powershell is. You can write shell commands directly in .ps1 or .ps2 files, just like in a batch file.
I'm not a powershell expert here, but try doing
& $smCmnd
Try running $smCmnd directly. If that fails, use Invoke-Expression $smCmnd.
If you do need to use CMD.EXE (possibly because you want to run pre-existing BAT file), and you want all of the output in a single CMD window you can pipe all the input into cmd at once like this:
# Powershell script to execute existing BAT file
cmd.exe /k "cd c:\batchfiles & firstone.bat & second.bat & echo that's all folks"
# CMD will remain open (/k). User will have to type exit to return to powershell
# Or if you want user just to hit any key to leave CMD prompt:
cmd.exe /c "c:\batchfiles\mybatchfile.bat & pause"
# /C means CMD should close after is has executed the commands on the command line
However if you want to have something execute in CMD, then make a decision in your Powershell script about what to execute next in CMD then do something similar to the answer at the following link which pipes input and output between a powershell script and CMD.exe.
How to run interactive commands in another application window from powershell

How can I detect whether or not I am in powershell from a command line?

I am creating a standard windows BAT/CMD file and I want to make an IF statement to check whether or not this CMD file is run from PowerShell. How can I do that?
Edit: My underlying problem was that test.cmd "A=B" results in %1==A=B when run from CMD but %1==A and %2==B when run from PowerShell. The script itself is actually run as an old Windows Command line script in both cases, so checking for Get-ChildItem will always yield an error.
One way, it to see what your process name is, and then check its attributes:
title=test
tasklist /v /fo csv | findstr /i "test"
As long as you use a unique name in place of Test, there should be little room for error.
You will get back something like:
"cmd.exe","15144","Console","1","3,284
K","Running","GNCID6101\Athomsfere","0:00:00","test"
When I ran the above code from a bat file, my output was:
"powershell.exe","7396","Console","1","50,972
K","Running","GNCID6101\Athomsfere","0:00:00","
A potentially simpler approach that may work for you. If not, it may be suitable for others.
Create 2 separate script files: test.ps1 and test.cmd
Don't include extension when calling the script. I.e. call as <path>\test (or just test if folder is in the path environment variable.
This works because CMD prioritises which script to execute as: .bat > .cmd, whereas Powershell prioritises: .ps1 > .bat > .cmd.
The following is the output of a CMD session:
C:\Temp>copy con test.cmd
#echo cmd^Z
1 file(s) copied.
C:\Temp>copy con test.ps1
Write-Output "ps1"^Z
1 file(s) copied.
C:\Temp>.\test
cmd
C:\Temp>
And calling test from Powershell:
PS C:\Temp> .\test
ps1
PS C:\Temp>
Couldn't you try to execute a Get-ChildItem and then check %ERRORLEVEL% to see if it returns an exe not found?
http://ss64.com/nt/errorlevel.html