Powershell execute commands on newly started Command Prompt process - powershell

Trying to start a new process in a separate command prompt on Windows 10, but can't find how to execute commands in opened prompt. With Powershell, I could use -Command:
Start-Process PowerShell "-Command tasklist"
But how to do that in Command Prompt window? This, obviously, doesnt work:
Start-Process cmd '-Command tasklist'

You're using the PowerShell arguments for cmd.exe. cmd /? will give you the usage, but what you want is cmd /c COMMAND [ARGUMENTS]:
Start-Process cmd "/c ping -n 4 google.com"
#Jeff Zeitlin was kind enough to provide a link to the SS64 CMD usage.
Worth mentioning, you don't need to use Start-Process when running external commands unless:
You are running a GUI application and wait to use the -Wait parameter to wait until the program exits
You want to run something in a different process asynchronously and check the result later
In this case don't forget to use -PassThru and assign the process to a variable, so you can check the result when ready

Related

how to run several cmd command prompts from powershell

So I am trying to write a script that allows me to open several cmd command prompt and write in them the same command but with different variables.
The solution that I came with was to write a PowerShell script that calls inside a loop a cmd file and pass a variable each time to the cmd file but I'm stuck, the PowerShell script execute only one cmd.
Can someone help to figure this out ?
Thanks :)
You can use the following :
cmd.exe /c [command]
for example
$x = 1..100
foreach ($n in $x){cmd.exe /c ping 192.168.1.$n}
mohamed saeed's answer shows you to execute cmd.exe commands synchronously, in sequence in the current console window.
If, by contrast, you want to open multiple interactive cmd.exe sessions, asynchronously, each in its separate, new window, use cmd.exe's /k option and invoke cmd.exe via Start-Process:
# Open three new interactive cmd.exe sessions in new windows
# and execute a sample command in each.
'date /t', 'ver', "echo $PSHOME" | ForEach-Object {
# Parameters -FilePath and -ArgumentList implied.
Start-Process cmd.exe /k, $_
}
Note:
Unless your cmd.exe console windows have the Let the system position the window checkbox in the Properties dialog checked by default, all new windows will fully overlap, so that you'll immediately only see the last one opened.
The last new window opened will have the keyboard focus.
The commands passed to /k are instantly executed, but an interactive session is then entered.
If you would like to keep in purely batch, you can use the start command. The /k switch keeps the command line open. You would use /c if you want to carry out the command and terminate :
start "" %comspec% /k ping 192.168.1.1
From powershell, you can use the Start-Process command with an ArgumentList:
Start-Process cmd.exe -ArgumentList "/k ping 192.168.1.1"

Run executable in powershell without waiting for return

This is really basic, but I can't find the answer. The installer sets up my path so that I can just type the command:
ng serve
at the command prompt and the script runs. I don't want to wait for this program to finish (it's a server, after all). How do I launch the same script (it's a CMD script as far as I can tell) from Powershell without waiting for it to finish (and without having to find the source directory for the script)?
If it's acceptable to terminate the server when the PowerShell session exits, use a background job:
In PowerShell (Core) 7+
ng server &
In Windows PowerShell, explicit use of Start-Job is required:
Start-Job { ng server }
Both commands return a job-information object, which you can either save in a variable ($jb = ...) or discard ($null = ...)
If the server process produces output you'd like to monitor, you can use the Receive-Job cmdlet.
See the conceptual about_Jobs topic for more information.
If the server must continue to run even after the launching PowerShell session exits, use the Start-Process cmdlet, which on Windows launches an independent process in a new console window (by default); use the -WindowStyle parameter to control the visibility / state of that window:
Start-Process ng server # short for: Start-Process -FilePath ng -ArgumentList server
Note: On Unix-like platforms, where Start-Process doesn't support creating independent new terminal windows, you must additionally use nohup - see this answer.

Trying to run a headless executable command through Powershell that works on cmd line

I am trying to run an executable through powershell to run headless, to install a program onto a VM/LocalHost machine. I can get the wizard to open, but for whatever reason I cannot get it to run headless. Here is the cmd line that I run that works:
start /WAIT setup.exe /clone_wait /S /v" /qn"
This is my attempts in powershell
Start-Process .\setup.exe /S -Wait -PassThru
Start-Process .\setup.exe /S /v /qn -Wait -PassThru
Start-Process setup.exe -ArgumentList '/clone_wait /S /v /qn' -Wait
In the cmd line instance the application installs without issue - in the powershell instance the wizard opens and is on the first "Next" prompt. Any help would be appreciated!
I also attempted to add the additional parameters "/v" and "/qn" which return an error : Start-Process : A positional parameter cannot be found that accepts argument '/v'
The bottom attempt runs but it's not waiting for the installation to complete
You may be overthinking it. Remember that PowerShell is a shell. One of the purposes of a shell is to run commands that you type.
Thus: You don't need Start-Process. Just type the command to run and press Enter.
PS C:\> .\setup.exe /clone_wait /S /v /qn
Now if the executable (or script) you want to run contains spaces in the path or name, then use the call/invocation operator (&) and specify the quotes; for example:
PS C:\> & "\package files\setup.exe" /clone_wait /S /v /qn
(This behavior is the same no matter whether you are at the PowerShell prompt or if you put the command in a script.)
This worked for me. You need to quote the whole argumentlist, plus embed double quotes to pass what you want to /v.
start-process -wait SetupStata16.exe -ArgumentList '/s /v"/qb ADDLOCAL=core,StataMP64"'
Running the command normally and then using wait-process after might be a simpler alternative, if you're sure there's only one process with that name:
notepad
wait-process notepad
To follow-up to all that you have been given thus far. Running executables via PowerShell is a well-documented use case.
PowerShell: Running Executables
Solve Problems with External Command Lines in PowerShell
Top 5 tips for running external commands in Powershell
Using Windows PowerShell to run old command-line tools (and their
weirdest parameters)
So, from the first link provides more validation of what you've been given.
5. The Call Operator &
Why: Used to treat a string as a SINGLE command. Useful for dealing with spaces.
In PowerShell V2.0, if you are running 7z.exe (7-Zip.exe) or another command that starts with a number, you have to use the command invocation operator &.
The PowerShell V3.0 parser do it now smarter, in this case you don’t need the & anymore.
Details: Runs a command, script, or script block. The call operator, also known as the "invocation operator," lets you run commands that are stored in variables and represented by strings. Because the call operator does not parse the command, it cannot interpret command parameters
Example:
& 'C:\Program Files\Windows Media Player\wmplayer.exe' "c:\videos\my home video.avi" /fullscreen
Things can get tricky when an external command has a lot of parameters or there are spaces in the arguments or paths!
With spaces you have to nest Quotation marks and the result it is not always clear!
In this case it is better to separate everything like so:
$CMD = 'SuperApp.exe'
$arg1 = 'filename1'
$arg2 = '-someswitch'
$arg3 = 'C:\documents and settings\user\desktop\some other file.txt'
$arg4 = '-yetanotherswitch'
& $CMD $arg1 $arg2 $arg3 $arg4
# or same like that:
$AllArgs = #('filename1', '-someswitch', 'C:\documents and settings\user\desktop\some other file.txt', '-yetanotherswitch')
& 'SuperApp.exe' $AllArgs
6. cmd /c - Using the old cmd shell
** This method should no longer be used with V3
Why: Bypasses PowerShell and runs the command from a cmd shell. Often times used with a DIR which runs faster in the cmd shell than in PowerShell (NOTE: This was an issue with PowerShell v2 and its use of .Net 2.0, this is not an issue with V3).
Details: Opens a CMD prompt from within powershell and then executes the command and returns the text of that command. The /c tells CMD that it should terminate after the command has completed. There is little to no reason to use this with V3.
Example:
#runs DIR from a cmd shell, DIR in PowerShell is an alias to GCI. This will return the directory listing as a string but returns much faster than a GCI
cmd /c dir c:\windows
7. Start-Process (start/saps)
Why: Starts a process and returns the .Net process object Jump if -PassThru is provided. It also allows you to control the environment in which the process is started (user profile, output redirection etc). You can also use the Verb parameter (right click on a file, that list of actions) so that you can, for example, play a wav file.
Details: Executes a program returning the process object of the application. Allows you to control the action on a file (verb mentioned above) and control the environment in which the app is run. You also have the ability to wait on the process to end. You can also subscribe to the processes Exited event.
Example:
#starts a process, waits for it to finish and then checks the exit code.
$p = Start-Process ping -ArgumentList "invalidhost" -wait -NoNewWindow -PassThru
$p.HasExited
$p.ExitCode
#to find available Verbs use the following code.
$startExe = new-object System.Diagnostics.ProcessStartInfo -args PowerShell.exe
$startExe.verbs

Run a PowerShell method from cmd and don't wait for its return

In cmd I'm trying to run Method1 which is in a PowerShell script, script1.
Method1 is a method that takes a few hours, and I simply want to fire and forget.
The following is working for me:
c:\temp> powershell
PS c:\temp> . .\script1.ps1;Method1
When I do the lines above, everything is working fine as long as I keep the CMD of PS opened. once I close the PS window, it kills Method1.
So actually I want that from cmd, in one line, to somehow make Method1 work without the dependency of the PowerShell window, maybe create a new process.. I am not really sure.
I've tried:
c:\temp> cmd /c powershell . .\script1.ps1;Method1
It is running for a few seconds, but when the cmd gets closed, then Method1 also terminates.
I also tried
c:\temp>cmd /c powershell -noexit "& { . .\script.ps1;Method1 }"
Again, once I do this, it is working. However, a PowerShell window is opened and if I close it then it terminates Method1.
From you help, I've tried:
c:\temp> cmd /c powershell start-process cmd /c powershell . .\script1.ps1;Method1
But I get an exception:
Start-Process : A positional parameter cannot be found that accepts
argument 'powershell'.
But still, I am not able to make it work.
Alternatively if you want a pure PowerShell solution (note this needs to be running as Admin):
Invoke-Command LocalHost -Scriptblock $script -InDisconnectedSession
The InDisconnectedSession switch runs it in a separate PowerShell session that will not be terminated when you close the PowerShell window. You can also use Get-PSSession and pass the session to Enter-PSSession to interact with it during or after execution. Remember in this state if you close the window it -will- kill it, so you'll want to use Exit-PSSession to keep it alive.
There is however a problem - you can't do any remoting tasks, at least not easily. This incurs the wrath of the "double hop" where you remote to one computer (your own in this case), then to another, and for security PowerShell refuses to pass any credentials to the second remoting session so it can't connect, even if you put the credentials in manually. If you do need to do remoting I recommend sticking with launching a hidden PowerShell process.
You can use PowerShell jobs for that, so just:
Start-Job -FilePath somepath
And add a method call at the end of the script, or pass in a Scriptblock like:
Start-Job -ScriptBlock {. .\path_to_ps1; Method1}
Or perhaps use the hackish:
start-process cmd -WindowStyle Hidden -ArgumentList "'/c powershell . .\script1.ps1;Method1'"
Actually, you can just launch PowerShell, without CMD, and I am not sure why I was using a cmd approach:
start-process powershell -WindowStyle Hidden -ArgumentList ". .\script1.ps1;Method1"
Easy answer ya'll; Just paste "start" command into your PS window (whether in a remote session or not) and it works fine:
Start C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -file 'driverletter:\path\yourpowershellscript.ps1'

PowerShell and executable

Every time I run an application (.exe) in PowerShell, instead of executing it as it does with scripts, the program gets run in Command Prompt.
Invoke-Item MyProgram.exe
I thought PowerShell was supposed to replace the Command Prompt but instead PowerShell opens Command Prompt which then runs the program. Is there some way I can get PowerShell to completely replace the Command Prompt?
I thought PowerShell was supposed to replace the Command Prompt
It is, so why don't you just do MyProgram.exe
Your question is pretty vague, and in short, it will depend on the program because Invoke-Item uses the Windows default file association stuff by default.
I'm betting that using & MyProgram.exe instead of Invoke-Item MyProgram.exe will work though.
Did you try Start-Process Program.exe -NoNewWindow
I got the answer from another question:
Start-Process .\MyProgram.exe -NoNewWindow -Wait