views:

14292

answers:

2

For years, I have used the cmd/dos/windows shell and passed command-line arguments to batch files. E.g., I have a file, "zuzu.bat" and in it, I access %1, %2, etc. Now, I want to do the same when I call a PowerShell script when I am in a Cmd.exe shell. I have a script "xuxu.ps1" (and I've added PS1 to my PATHEXT variable and associated PS1 files with PowerShell). But no matter what I do, I seem unable to get anything from the $args variable. It always has length 0.

If I am in a PowerShell shell, instead of Cmd.exe, it works (of course). But I'm not yet comfortable enough to live in the PowerShell environment full time. I don't want to type "powershell.exe -command xuxu.ps1 p1 p2 p3 p4". I want to type "xuxu p1 p2 p3 p4".

Is this possible, and if so, how?

The sample I cannot get to work is trivial, foo.ps1:

Write-Host "Num Args:" $args.Length;
foreach ($arg in $args)
{
  Write-Host "Arg: $arg";
}

The results are always like this:

C:\temp> foo
Num Args: 0
C:\temp> foo a b c d
Num Args: 0
c:\temp>
+2  A: 

Ok, so first this is breaking a basic security feature in PS. With that understanding, here is how you can do it:

  1. Open an explorer window
  2. Folder->Options->File Types
  3. Find the PS1 file type and click the advanced button
  4. Click the New button
  5. For Action put: Open
  6. For the Application put: "C:\WINNT\system32\WindowsPowerShell\v1.0\powershell.exe" "-file" "%1" %*

You may want to put a -NoProfile argument in there too depending on what your profile does.

EBGreen
I think the key is in your step 6 where you pass in the parameters to powershell.exe. Daniel says he has associated PS1 files with PowerShell but that doesn't pass arguments without the extra %1 %* specs. Also note that the -File parameter is not available in V1. It is new to V2.
Keith Hill
Good catch regarding the -file parameter I had forgotten that.
EBGreen
I'll have to install V2 before I can try your suggestion. Thanks. When you say this is breaking a basic security feature, what does "this" you mean? Calling a PowerShell script from Cmd.exe as though it were a .com/.bat/.exe file? Passing parameters to the script?
Daniel 'Dang' Griffith
Sorry I should have been more clear. The calling the script without explicitly calling powershell.exe. I'm not saying it is a significant security feature for you personally and it is security through obscurity which I am not always a fan of anyway.
EBGreen
To add to EBGreen's comment, the basic security problem that PowerShell's tries to avoid is folks double-clicking on PS1 files attached to email and having the script run. That's why PS1 files are only associated with an editor by default. Microsoft really doesn't want a PowerShell version of the ILoveYou virus e.g. "LOVE-LETTER-FOR-YOU.TXT.ps1"
Keith Hill
+1  A: 

Maybe you can wrap the PS invocation in a .bat file like so:

rem ps.bat
@echo off
powershell.exe -command "%*"

If you then placed this file under a folder in your PATH, you could call powershell scripts like this:

ps foo 1 2 3

Quoting can get a little messy, though:

ps write-host """hello from cmd!""" -foregroundcolor green
guillermooo