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).
Related
Here is the program. I am using dell command | configure. The command-line command is as follows:
"C:\Program Files (x86)\Dell\Command Configure\X86_64>cctk.exe" --wakeonlan
In Powershell you can navigate to the folder and run:
./cctk.exe --wakeonlan
I can pipe the above command into a variable and get the information I need. This requires my shell to cd into the folder accordingly and run accordingly.
$test = ./cctk.exe --wakeonlan
This will give you an output. However when you use start-process, you get no output as this is a command-line command. A cmd screen appears and runs the command. So, I added a -nonewwindow and -wait flags. The output now appears on the screen, but I can't seem to capture it.
$test = start-process "C:\Program Files (x86)\Dell\Command Configure\X86_64\cctk.exe" -ArgumentList #("--wakeonlan") -NoNewWindow -Wait
At this point test is empty. I tried using the Out-File to capture the information as well. No success. The command outputs to the screen but nowhere else.
I also tried the cmd method where you pipe the information in using the /C flag.
$test = Start-Process cmd -ArgumentList '/C start "C:\Program Files (x86)\Dell\Command Configure\X86_64\cctk.exe" "--wakeonlan"' -NoNewWindow -Wait
However, I have tried many variations of this command with no luck. Some say C:\Program is not recognized. Some just open command prompt. The above says --wakeonlan is an unknown command.
Any pointers would help greatly.
There are various ways to run this without the added complication of start-process.
Add to the path temporarily:
$env:path += ';C:\Program Files (x86)\Dell\Command Configure\X86_64;'
cctk
Call operator:
& 'C:\Program Files (x86)\Dell\Command Configure\X86_64\cctk'
Backquote all spaces and parentheses:
C:\Program` Files` `(x86`)\Dell\Command` Configure\X86_64\cctk
To elaborate on js2010's helpful answer:
In short: Because your executable path is quoted, direct invocation requires use of &, the call operator, for syntactic reasons - see this answer for details.
To synchronously execute console applications or batch files and capture their output, call them directly ($output = c:\path\to\some.exe ... or $output = & $exePath ...), do not use Start-Process (or the System.Diagnostics.Process API it is based on) - see this answer for more information.
If you do use Start-Process, which may be necessary in special situations, such as needing to run with a different user identity:
The only way to capture output is in text files, via the -RedirectStandardOutput / -RedirectStandardError parameters. Note that the character encoding of the output files is determined by the encoding stored in [Console]::OutputEncoding[1], which reflects the current console output code page, which defaults to the system's active legacy OEM code page.
By contrast, even with -NoNewWindow -Wait, directly capturing output with $output = ... does not work, because the launched process writes directly to the console, bypassing PowerShell's success output stream, which is the one variable assignments capture.
[1] PowerShell uses the same encoding to decode output from external programs in direct invocations - see this answer for details.
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).
We are migrating perl script to powershell script.
In Perl the code is as shown below
$rc='D:\\EmailConnector\\run.bat> $EmailConnector_log;';
I tried as shown below but not working
StartProcess "cmd.exe" "/c D:\EmailConnector\run.bat> $EmailConnector_log"
When I tried as shown below the .bat script ran, but I want to update the log file. Could you help me on this.
StartProcess run.bat -workingdirectory "D:\EmailConnector"
The .bat file consist of jar file for email functionality. But we want to get log in log file.
Use the call operator (&), like this:
& 'D:\EmailConnector\run.bat' > $EmailConnector_log
The return value of the batch script is automatically put into the variable $LastExitCode.
Is that what you mean?
Start-Process "cmd" -ArgumentList '/c','D:\EmailConnector\run.bat' -WorkingDirectory "D:\EmailConnector"
or this one if you need another argument for logfile
Start-Process "cmd" -ArgumentList '/c','D:\EmailConnector\run.bat','EmailConnector_log' -WorkingDirectory "D:\EmailConnector"
Or, since there are no spaces in the path, you can just execute the batch file directly from PowerShell:
D:\EmailConnector\run.bat > $EmailConnector_log
This is one of the advantages of PowerShell being both a "shell" and a "scripting language". Execution of batch, cmd, vbs, exe files is straightforward - usually. Parameter passing can be an issue but these days that is easily solved with the stop parsing operator: --%.
I created a small aws.bat script and then in PowerShell I navigated to the script directory.
But when I type aws then I get an error message and it does not execute the script. Is there a special thing I should be doing?
Here's what I have tried:
PS C:\G> .\aws.bat
C:\G>$BucketName = "ab-user"
'$BucketName' is not recognized as an internal or external command,
operable program or batch file.
The very first and every othre command has a similar message.
You can't just enter the name on its own, with or without file extension, you first have to tell powershell what to do with it.
You can call it as follows:
& .\aws.bat
If you need the LastExitCode returned in powershell to check if the bat file worked (0 usually means it worked, anything else usually means it didn't), use Start-Process as follows:
$batch = Start-Process -FilePath .\aws.bat -Wait -passthru;$batch.ExitCode
And if you want the batch file to be hidden when it is run by powershell do this:
$batch = Start-Process -FilePath .\aws.bat -Wait -passthru -WindowStyle Hidden;$batch.ExitCode
I am trying to invoke a command-line .exe tool (x264 to convert some videos) and print its output in PowerShell host.
There are a lot of parameters that need to be passed to the x264. So far I couldn't run it with the Invoke-Item cmdlet so I tried
[diagnostics.process]::start($com, $args).WaitForExit()
This works fine but it opens the old cmd window to show the output. Just out of curiosity I was wondering how can I show the output in the host.
I might be completely off, no PowerShell guru, but can't you just run the following?
$args = #("list", "of", "args", "here")
& x264.exe $args
When the cmd window opens, does it show the output? If so, maybe this can help.
Start-Process c:\x264.exe -ArgumentList $args -Wait -NoNewWindow