0

Bottom Line Up Front

I'm looking for a method to validate powershell (v1) command line parameters without propagating exceptions back to the command line.

Details

I have a powershell script that currently uses param in conjunction with [ValidateNotNullOrEmpty] to validate command line paramaters:

param(
   [string]
   [ValidateNotNullOrEmpty()]$domain = $(throw "Domain (-d) param required.")
)

We're changing the paradigm of error handling where we no longer want to pass exceptions back to the command line, but rather provide custom error messages. Since the param block can not be wrapped in a try catch block, i've resorted to something like the following:

param(
   [string]$domain = $("")
)
Try{
   if($domain -like $("")){
      throw "Domain (-d) param required."
    }
...

}Catch{
#output error message 
}

My concern is that we're bypassing all of the built-in validation that is available with using param. Is my new technique a reasonable solution? Is there a better way to validate command line params while encapsulating exceptions within the script? I'm very much interested in see how PowerShell professionals would handle this situation.

Any advice would be appreciated.

xelco52
  • 5,257
  • 4
  • 40
  • 56
  • 1
    TBH more I read your description, more I come to the conclusion that you should not worry about "bypassing all built-in validation". Why? Because that's *exactly* your target. You want to bypass it's default behavior, so if that's what you need and have to do - than just do it. ;) – BartekB Jun 14 '12 at 07:51
  • @BartekB, If you add this comment as an answer, I'd be inclined to accept it as the answer that most helped me. – xelco52 Jun 25 '12 at 21:11

3 Answers3

2

You can write a custom validation script. Give this parameter a try.

Param(
    [ValidateScript({
        If ($_ -eq $Null -or $_ -eq "") {
            Throw "Domain (-d) param required."
        }
        Else {
            $True
        }
    })][string]$Domain
)
1

One way is to use default parameters like this [from msdn] -

Function CheckIfKeyExists 
{ 
    Param( 
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)] 
        [String] 
        $Key = 'HKLM:\Software\DoesNotExist' 
    ) 
    Process 
    { 
        Try 
        { 
            Get-ItemProperty -Path $Key -EA 'Stop' 
        } 
        Catch 
        { 
            write-warning "Error accessing $Key $($_.Exception.Message)"   
        } 
    } 
}

So, here, if you try calling the function without passing any parameters, you will get warning what you have defined in your try/catch block. And, you are not using any default validation attributes for that. You should always assume that you will encounter an error, and write code that can survive the error. But the lesson here is if you implement a default value, remember that it is not being validated.

Read more here

Angshuman Agarwal
  • 4,796
  • 7
  • 41
  • 89
  • 'A' for effort. Ignoring that this includes powershell 2.0 features, this looks as I would expect for a function - however, i'm validating command line parameters, so it's not possible to wrap the upstream call in a try/catch block to handle the exceptions this example would throw. – xelco52 Jun 13 '12 at 20:54
  • Only the `last link` related to advanced parameters is Powershell 2.0. Main theme is the use of default parameters in error handling without using any validation attribute. That is achievable in V1 too. You may remove the extra attributes too. _In above example if user forgets to pass any parameter then he will receive a `warning`_ – Angshuman Agarwal Jun 14 '12 at 08:38
  • +1 You're making sense. The more I work on this, the better this is looking. There are some v2 constructs in there, but I see the point. – xelco52 Jun 19 '12 at 20:26
1

As I mentioned in a comment: more I read your description, more I come to the conclusion that you should not worry about "bypassing all built-in validation". Why? Because that's exactly your target. You want to bypass it's default behavior, so if that's what you need and have to do - than just do it. ;)

BartekB
  • 8,492
  • 32
  • 33