Powershell prompts for parameters even if supplied

by gbritton at 2013-04-15 08:45:32

If I save the following script as bar.ps1 and run it from the command line supplying both parameters, Powershell prompts for the parameters anyway.

script:


[CmdletBinding()]
param(
[Parameter(Mandatory=$true,Position=1)]
[ValidateScript({Test-Path $_ -PathType Leaf})]
[string]
$cmd
,
[Parameter(Mandatory=$false,Position=2)]
[string]
$log
)

write-host "cmd: $cmd"
write-host "log: $log"



e.g.
C:\temp>bar.ps1 bar.ps1 foo

cmdlet bar.ps1 at command pipeline position 1
Supply values for the following parameters:
cmd: bar.ps1
cmd: bar.ps1
log:

C:\temp>


So, why does powershell prompt for the parameter ‘cmd’ even when I give it on the command line? What am I missing?
by poshoholic at 2013-04-15 09:33:12
I’m not able to reproduce this problem. I took your script as is listed here, saved it as C:\test.ps1, then invoked the following:
C:\test.ps1 C:\test.ps1 foo
The results were as expected, outputting the cmd and log parameter values via Write-Host.

If you are doing something different regarding the invocation, you’ll need to share the specific details about how you invoke your script in order to figure out why it isn’t getting parameters properly. Also, you should probably identify your version of PowerShell as well, as reported in $PSVersionTable.
by gbritton at 2013-04-15 09:39:35
No, I’m not doing anything different than you did. My results are not the same however. I actually posted the exact results I received. Powershell prompts for the "cmd" argument, even though it has been supplied. Here is my $PSVersionTable:

Name Value
---- -----
PSVersion 2.0
PSCompatibleVersions {1.0, 2.0}
BuildVersion 6.0.6002.18111
PSRemotingProtocolVersion 2.1
WSManStackVersion 2.0
CLRVersion 4.0.30319.296
SerializationVersion 1.1.0.1
by poshoholic at 2013-04-15 09:59:32
Here are some other possible tests worth trying:

1. Invoke PowerShell using the -noprofile parameter so that nothing extra is loaded and try again in that environment.
2. Test whether using the relative path or absolute path for the parameters makes a difference.
3. Use quotes around the parameters, see if it makes a difference.
4. Try on another system you have access to, see if the way you are invoking the script works as expected there.

I don’t see any logic problems with your script, so something else seems to be going on.
by gbritton at 2013-04-15 10:06:22
Here’s one thing I found: If I explicitly invoke powershell, it works as expected. That is:


C:\temp>powershell -file bar.ps1 bar.ps1 foo
cmd: bar.ps1
log: foo
C:\temp>


works but:


C:\temp>bar.ps1 bar.ps1 foo

cmdlet bar.ps1 at command pipeline position 1
Supply values for the following parameters:
cmd: bar.ps1
cmd: bar.ps1
log:


doesn’t though it certainly uses the default file assocation of .ps1 to powershell.

Also, quoting and/or fully qualifying the -cmd argument didn’t change anything for me. Unfortunately, this is the only system that I have access to tha has powershell installed.
by poshoholic at 2013-04-15 10:12:04
Ok, so what if you invoke the following:
Get-Command bar.ps1 | Format-List *
Does the output from that command give you what you would expect (only one command called bar.ps1 with the proper file, path, and script block contents)?
by happysysadm at 2013-04-15 10:18:23
Hi,
my opinion is that you are messing around with the way you load the script.

This:
[code2=powershell]C:\temp>bar.ps1 bar.ps1 foo[/code2]
shouldn’t work in Powershell V2 or V3, because scripts are loaded this way:
[code2=powershell]cd c:\temp
.\bar.ps1 bar.ps1[/code2]
or this way:
[code2=powershell]c:\temp\bar.ps1 c:\test\bar.ps1 cmd[/code2]
Can you give it a try?
Carlo
by gbritton at 2013-04-15 10:20:47
Well, that’s interesting! Check this out:


PS C:\temp> dir bar.ps1


Directory: C:\temp


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a— 4/15/2013 12:45 PM 272 bar.ps1


PS C:\temp> Get-Command bar.ps1 | Format-List *


Get-Command : The term ‘bar.ps1’ is not recognized as the name of a cmdlet, function, script file, or operable program
. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:13
+ Get-Command <<<< bar.ps1 | Format-List *
+ CategoryInfo : ObjectNotFound: (bar.ps1:String) [Get-Command], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand



though If I include that path, I get good results:


PS C:\temp> Get-Command c:\temp\bar.ps1 | Format-List *




HelpUri :
Path : C:\temp\bar.ps1
Definition : C:\temp\bar.ps1
Visibility : Public
ScriptBlock :
param(
[Parameter(Mandatory=$true,Position=1)]
# [ValidateScript({Test-Path $MyInvocation.MyCommand.Path\ $_ -PathType Leaf})]
[string]
$cmd
,
[Parameter(Mandatory=$false,Position=2)]
[string]
$log
)

write-host "cmd: $cmd"
write-host "log: $log"
OutputType : {}
ScriptContents :
param(
[Parameter(Mandatory=$true,Position=1)]
# [ValidateScript({Test-Path $MyInvocation.MyCommand.Path\ $_ -PathType Leaf})]
[string]
$cmd
,
[Parameter(Mandatory=$false,Position=2)]
[string]
$log
)

write-host "cmd: $cmd"
write-host "log: $log"
OriginalEncoding : System.Text.UTF8Encoding
Name : bar.ps1
CommandType : ExternalScript
ModuleName :
Module :
Parameters : {[cmd, System.Management.Automation.ParameterMetadata], [log, System.Management.Automation.Paramete
rMetadata], [Verbose, System.Management.Automation.ParameterMetadata], [Debug, System.Management.Au
tomation.ParameterMetadata]...}
ParameterSets : {[-cmd] <String> [[-log] <String>] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-WarningA
ction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [-OutVariable <Stri
ng>] [-OutBuffer <Int32>]}




by happysysadm at 2013-04-15 10:22:18
Same here. use:
Get-Command .\test1.ps1
by gbritton at 2013-04-15 10:25:23
[quote="happysysadm"]Hi,
my opinion is that you are messing around with the way you load the script.

This:
[code2=powershell]C:\temp>bar.ps1 bar.ps1 foo[/code2]
shouldn’t work in Powershell V2 or V3, because scripts are loaded this way:
[code2=powershell]cd c:\temp
.\bar.ps1 bar.ps1[/code2]
or this way:
[code2=powershell]c:\temp\bar.ps1 c:\test\bar.ps1 cmd[/code2]
Can you give it a try?
Carlo[/quote]

OK, so here’s what I have (just ran it in a command window and copy/pasted the results):


C:\temp>.\bar.ps1 .\bar.ps1 foo

cmdlet bar.ps1 at command pipeline position 1
Supply values for the following parameters:
cmd: asd
cmd: asd
log:


As you can see, it still prompts me for the arguments, even though they are supplied. However, if I explicitly invoke powershell, it works:


C:\temp>powershell .\bar.ps1 .\bar.ps1 foo
cmd: .\bar.ps1
log: foo
C:\temp>


I thought it would (should?) work both ways, but there is an annoying difference.
by happysysadm at 2013-04-15 10:33:43
There is for sure something weird because your initial code:
[code2=powershell]C:\temp>bar.ps1 bar.ps1 foo[/code2]
should not work. If I run it I get:

[code2=powershell]PS C:\test> bar.ps1 bar.ps1 cmd
The term 'bar.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the s
pelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:10
+ bar.ps1 <<<< bar.ps1 cmd
+ CategoryInfo : ObjectNotFound: (bar.ps1:String) , CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Suggestion [3,General]: The command bar.ps1 was not found, but does exist in the current location. Windows PowerShell
doesn't load commands from the current location by default. If you trust this command, instead type ".\bar.ps1". See "
get-help about_Command_Precedence" for more details.[/code2]

So I don’t get how is it that you don’t have an error shown…
by gbritton at 2013-04-15 11:46:41
Well, there is a lot that I don’t get either. However, see my last post. It includes ".&quot; in the path names. Even so, the weirdness continues.
by happysysadm at 2013-04-15 12:18:08
Hi,
have you tested your script on another computer and see how it does?
Carlo
by gbritton at 2013-04-15 12:37:01
I’m afraid that I don’t have another computer that I can use that has powershell installed on it. So I’m kinda stuck.
by poshoholic at 2013-04-15 12:51:51
Just to rule out more possibilities, have you tried restarting PowerShell or restarting your computer entirely? And just to confirm, you’re using the native PowerShell host and not something else? Did you try it by opening a new PowerShell host using the -noprofile switch (not invoking powershell with the command, just opening a host with -noprofile and then trying it there)? What about using the full path (absolute, not relative)? This definitely seems environmental, and maybe one of these might get you back into a working state.
by gbritton at 2013-04-16 08:43:32
I restarted my computer, started powershell from the a cmd window with the -noprofile switch and used both full and relative paths. (is that what you meant by "open a host with -noprofile"?)

Same results as before.
by poshoholic at 2013-04-16 13:59:05
That is what I meant by "open a host with -noprofile", yes. With those options out of the way, I’m not sure what to suggest next. If you’re on a system that didn’t come with PowerShell 2 preinstalled, perhaps you should roll back the KB article installation for WMF 2.0 and re-install it. Or see if you can work around it by invoking PowerShell from within PowerShell (thinking this might work because you indicated you could get the correct results when invoking the command as part of a powershell.exe command invocation). Other than that I don’t see many additional troubleshooting steps to try right now.