2

I'm in the process of converting a Korn shell script to PowerShell. The existing script utilizes the getopt command and makes use of case sensitive command line arguments (e.g., v behaves differently than V).

set -- `getopt T:ZISedDACkpWhzLJMl:n:g:x:r:R:V:v:N:G:o:m:O: $*`

for c in $*
 do
   case $c in
    -h)        echo $USAGE
    --)       shift; break;;
    esac
done

For the PowerShell version, I would like to keep the parameter names and behavior exactly the same. I've been investigating Named Function Parameters as a possibility; however, PowerShell is case insensitive and will not allow the duplicate parameter names. So, this will not work.

function dowork ()
{
    param
    (
      [string]$V,
      [string]$v,
    )
    ...
}

I could utilize the automatic $args variable which contains an array of the undeclared parameters; however, I am not aware of a PowerShell equivalent for the getopt command. Is there another way to accomplish this without implementing my own getopt?

user2864740
  • 60,010
  • 15
  • 145
  • 220
javacavaj
  • 2,901
  • 5
  • 39
  • 66
  • If you declare the parameter using advanced syntax you can force it to not ignore case: http://becomelotr.wordpress.com/2012/01/31/case-sensitive-validateset/ – EBGreen Apr 11 '14 at 15:23
  • Good suggestion, but I still get: ERROR: Duplicate parameter $O in parameter list. ERROR: ERROR: + CategoryInfo : ParserError: (:) [], ParseException ERROR: + FullyQualifiedErrorId : DuplicateFormalParameter – javacavaj Apr 11 '14 at 15:31
  • To precisely copy getopt, you'll need to use $args. – Jason Shirk Apr 11 '14 at 16:12

2 Answers2

4

What getopt does is not directly possible in PowerShell and I'd rather advise against recreating it directly. As you already noticed, parameter capitalisation does not matter and parsing is also quite different, distinguishing not short and long options but rather allowing you to shorten any parameter as long as it remains unambiguous.

My advice would be to see whether you can give the options meaningful names that work with PowerShell's parameter parsing, not against it. You can then include documentation on how the getopt-style arguments map to PowerShell's (and perhaps provide a trivial script to translate between the two).

Joey
  • 344,408
  • 85
  • 689
  • 683
1

PowerShell variable and parameter names are case-insensitive.

[CmdletBinding()]
Param(
  [Parameter()]
  [Alias('F')]
  [string]$Foo
)

is the exact same as

[CmdletBinding()]
Param(
  [Parameter()]
  [Alias('f')]
  [string]$foo
)

Same goes for calling either of the script with the parameter:

.\script.ps1 -Foo
.\script.ps1 -FOO
.\script.ps1 -foO
.\script.ps1 -F
.\script.ps1 -f

All of the above do the same thing.

Bottom line: using PowerShell's built-in parameter handling you can't have an uppercase and a lowercase parameter (e.g. -A and -a) with different meanings. If case-sensitive parameters are a requirement you need to implement your own argument parser. I'd strongly advise against it, though, because it contradicts normal PowerShell behavior.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328