Enable PowerShell to run command line commands

IT Guy
IT Guy used Ask the Experts™
on
Is there any way of enabling PowerShell to run command line commands?

By default, I have found that while some command line commands are able to be run in PowerShell I have found that not all commands can be successfully run.

Is there any way of changing this?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Consultant
Commented:
Hi IT Guy,

Are you referring to 'DOS shell' commands?

If so, they should run from PowerShell, although you might need to use full name for the command if there is a conflict between the old DOS command, and a PowerShell command.

To do that, use the full DOS name, including the EXE extension.  For example, one common 'issue' that comes up all the time for PowerShell is with the old DOS 'Service Control' (SC) command, so you use:

SC.exe

rather than just using 'SC' in PowerShell since SC is an alias for Set-Content in PowerShell.


Another option is to enclose the DOS command in quotes, and call it via Cmd /c like this from PowerShell:

Cmd /c "SC Query ServiceName"



Also, there is often a PowerShell command that takes the place of the old DOS command (such as Get-Service for SC) - if so, use that instead if you can.


There are a number of other ways around the problem but I would use one of the above generally, with a longer term preference to use the pure PowerShell command unless you know that you want the script to be able to run in both PowerShell and CMD.

Hope that helps,


Alan.
Jose Gabriel Ortega CastroTop Rated Freelancer on MS Technologies
Awarded 2018
Distinguished Expert 2018
Commented:
IT will depend on what commands you want to run.

it should be

& dir

Open in new window

Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
If above said is not sufficient, please post an example of a non working line.
Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
PowerShell does its best to interpret the command line, especially when variables are involved.
This works most of the times, but obviously has its limits.
For example, PS "removes" (it actually doesn't pass them along) double quotes it finds unnecessary, while adding them when it thinks they are (that is, whenever there's a space in the variable).
That's best shown with the good old "find.exe", because it insists on the search string being surrounded by quotes.
Very simple command, and not really what you'd expect as result:
PS C:\> "IT Guy" | find.exe /i "T"
FIND: Parameter format not correct
PS C:\> $t = 'T'
PS C:\> "IT" | find.exe /i $t
FIND: Parameter format not correct

Open in new window

Here, PS decided that the double quotes were not required, so it removed them before passing the arguments to find.exe, and find.exe didn't like it at all.
So for comparison, let's see what happens when a space is involved:
PS C:\> "IT Guy" | find.exe /i "T G"
IT Guy
PS C:\> $tg = 'T G'
PS C:\> "IT Guy" | find.exe /i $tg
IT Guy

Open in new window

Workaround 1: force the quotes, either by embedding the argument (including the double quotes) in single quotes, or by embedding escaped double quotes:
PS C:\> "IT Guy" | find.exe /i '"T"'
IT Guy
PS C:\> "IT Guy" | find.exe /i "`"T`""
IT Guy
PS C:\> $t = 'T'
PS C:\> "IT Guy" | find.exe /i "`"$t`""
IT Guy

Open in new window

Workaround 2 (requires PS 3.0 or later): tell PowerShell to mind its own business and let you do the thinking, by telling it to stop parsing the command line at "--%". Everything following that string will be taken literally.
This is pretty much what you asked for initially.
Note that the "stop parsing" means exactly that: you can't use variables after that signal anymore, either:
PS C:\> "IT Guy" | find.exe /i --% "T"
IT Guy
PS C:\> $t = "T"
PS C:\> "IT Guy" | find.exe /i --% "'"$t`""
File not found - '$T`
PS C:\> "IT Guy" | find.exe /i --% "$t"
## No output, because now it's looking for the literal string "$t"
PS C:\> '$T' | find.exe /i --% "$t"
$T

Open in new window

Now, did I just say you can't use variables anymore? That's not the whole truth. There's a workaround for that, too. After the "--%" (and only after that), PS will expand environment variables enclosed in percent signs, just like cmd.exe does. So set an environment variable to whatever you need, and it looks nearly like good old cmd.exe:
PS C:\> $env:T = "T"
PS C:\> "IT Guy" | find.exe --% /i "%T%"
IT Guy

Open in new window

Finally, if the path to an external command requires quotes because it contains spaces, or if you want to define the path in a variable, you have to use the "&" operator to tell PS that you want to invoke the string, not just send it to the pipeline.
Personally, I usually use the "&" when calling external programs, whether required or not, to make it clear what's happening, and always add the extension as well.
PS C:\> $env:T = "T"
PS C:\> "IT Guy" | & "C:\Windows\system32\find.exe" --% /i "%T%"
IT Guy
PS C:\> $find = "C:\Windows\system32\find.exe"
PS C:\> "IT Guy" | & $find --% /i "%T%"
IT Guy

Open in new window

See Get-Help about_Parsing as well
About Parsing
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing?view=powershell-5.1

If all that doesn't help, there's still Start-Process, where you can build your own command line arguments just like in VBScript.

Edit: added information about the "&" operator.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial