3

I have a number of scenarios in which I need to pass parameters to command line exes.

I've seen a number of these answered to some extent on this site, but so far I have not seen solid, general purpose, description of how powershell deals with parameters - both being passed by cmd or start-process. Here's one trivial example which bugs me:

Here's the bat script:

CD /D %ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE
devenv /command "File.BatchNewTeamProject C:\stuff\Project51.xml"

What I do not understand, is how powershell is parsing these arguments. What does it consider a "parameter"?

Also, are the rules the same for start-process as they are for cmd.exe ?

svick
  • 236,525
  • 50
  • 385
  • 514
Hotrodmonkey
  • 2,924
  • 3
  • 20
  • 25
  • I'm not sure to grab your doubts. For example, to launch notepad, you simply type `notepad`. The way you pass parameters to an executable that will be launched from powershell does not change. You use executables and batch commands exactly as you were using the old `cmd.exe`. The family of cmdlets instead is totally another subject, that's proper of powershell, even the way parameters are managed. – Emiliano Poggi May 13 '11 at 15:00
  • PowerShell does something a little different than the NT conhost. I wrote a PS script that passes arguments to RRDtool, yet for some reason RRDtool complains that it "can't make sense" of a perfectly valid argument. The exact same arguments, when run from the NT console, work perfectly. No quotes are involved. There is something PowerShell is doing besides just passing arguments, I just don't know what it is. –  Nov 01 '11 at 14:56

2 Answers2

1

Try this function coming from PowerShell.com PowerTip it illustrate the usage of Invoke-Expression.

function Call {
  $command = $Args -join " "
  $command += " 2>&1"
  $result = Invoke-Expression($command)
  $result | 
    %{$e=""}{ if( $_.WriteErrorStream ) {$e += $_ } else {$_} }{Write-Warning $e}
}

That gives :

cd "${env:ProgramFiles(x86)}\Microsoft Visual Studio 10.0\Common7\IDE"
call .\devenv.exe /command "`"File.BatchNewTeamProject C:\stuff\Project51.xml`"

--- Edit ---

There are many things to say here.

First you can find a good help with "about" files try :

Get-help about-*

On the subject you are interested you've got:

Get-help about_Quoting_Rules
Get-Help about_Special_Characters
Get-Help about_Escape_Characters
Get-Help about_Parameters

Second CD, DIR, MD works, but they are just aliases on CmdLets which takes different arguments.

Third to get environment variable it's no longer %systemroot% it's $env:systemroot.

Fourth to start an executable file from powershell you can just type the name of the exe :

PS> notepad c:\temp\test.txt

The command line is first interpreted by powerShell so now if you write :

PS> "C:\Windows\System32\notepad.exe"
C:\Windows\System32\notepad.exe

It just interpret it as a string. So you can use the & operator and write

PS> & "C:\Windows\System32\notepad.exe" c:\test.txt

It works but :

PS> $a = "C:\Windows\System32\notepad.exe c:\test.txt"
PS> & $a

Fails and

PS> $a = "C:\Windows\System32\notepad.exe c:\test.txt"
PS> Invoke-Expression $a

Works

Christopher Bennage
  • 2,578
  • 2
  • 22
  • 32
JPBlanc
  • 70,406
  • 17
  • 130
  • 175
  • 1
    The above worked - but it is unsettling to have an expression eval'd to simply pass common string arguments. I'd really like to have a clearer understanding of how the PowerShell parser is interpreting these values – rather than having a “black box” like Invoke-Expression charge in to save the day. It should be noted that I’m something of a PS newb, but I’d really prefer not to guess as much as I am… – Hotrodmonkey May 13 '11 at 15:52
0

Just pass parameters like you would in your BAT file.

cd "$($env:ProgramFiles(x86))\Microsoft Visual Studio 10.0\Common7\IDE"
devenv /command "File.BatchNewTeamProject C:\stuff\Project51.xml"

That will pass two arguments to devenv.

Now, I have run into a few cases where an application requires that quotes be in the string you pass it. I had some trouble with this and thought that PowerShell was dropping the quotes. But it turns out that the real problem is that PowerShell does not escape the quotes. So you need to do this.

devenv /command '\"File.BatchNewTeamProject C:\stuff\Project51.xml\"'
JasonMArcher
  • 14,195
  • 22
  • 56
  • 52