4

For example, my script can be called like this:

.\MyScript.ps1 -s <hostname1>

If I call it without passing an argument with the -s parameter, I receive an error:

.\MyScript.ps1 -s

C:\MyScript.ps1 : Missing an argument for parameter 'sql'. Specify a pa
rameter of type 'System.String' and try again.
At line:1 char:18
+ .\MyScript.ps1 -s <<<<
    + CategoryInfo          : InvalidArgument: (:) [MyScript.ps1],     ParameterBindingException
    + FullyQualifiedErrorId : MissingArgument,MyScript.ps1

Is there any way to suppress this error, or make a custom error appear:

.\MyScript.ps1 -s

Please pass a hostname with the s argument:
.\MyScript.ps1 -s <hostname>
Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
EGr
  • 2,072
  • 10
  • 41
  • 61

5 Answers5

1

You could do 1 of 2 things.

Mark the parameter as mandatory, then powershell will automatically query the user for it:

PARAM(  [Parameter(Mandatory=$true)][string]$sql )
PROCESS
{
    "You entered: " + $sql
}

which gives:

# C:\Temp> .\prompt.ps1 
cmdlet prompt.ps1 at command pipeline position 1
Supply values for the following parameters:
sql: asdsaa
You entered: asdsaa

or you could provide an expression as a default parameter that queries the input from the user:

PARAM(  [string]$sql = (read-host "Enter a value for sql parameter") )

PROCESS
{
    "You entered: " + $sql
}

which gives:

# C:\Temp> .\prompt.ps1 
Enter a value for sql parameter: hello
You entered: hello

Edit:

In response to your comment. The only workarounds I can think of to get the behaviour you want are to either not specify the parameters and process the $args argument yourself. Or you could employ a hack that pushes the job to parsing the arguments to a separate function and then trap any errors that may occur when calling that function. So, your script would look like this:

function parsePrompt ( [string]$sql)
{
    $sql
}

$cmd = "parsePrompt $($args -join " ")"
try
{
    $sql = invoke-expression $cmd
}
catch [System.Management.Automation.ParameterBindingException]
{
    $sql = read-host "Enter a value for sql parameter"
}
"You entered: " + $sql

which gives:

# C:\Temp> .\Prompt.ps1 -s
Enter a value for sql parameter: dsfds
You entered: dsfds


# C:\Temp> .\Prompt.ps1 -s dfds
You entered: dfds
zdan
  • 28,667
  • 7
  • 60
  • 71
  • The solutions do not work. If the script is passed like this ".\prompt.ps1" it works; but I am trying to suppress the alerts that appear when the script is run like this ".\prompt.ps1 -s" – EGr Jan 25 '13 at 14:17
  • @EGr See the alternative I posted. – zdan Jan 25 '13 at 18:33
0

You might try using a trap handler to provide custom messages when an argument isn't passed and then go on from there. Trap handlers work for the current scope so you can just define it at the top of your script to handle your errors.

e.g:

trap [ArgumentException] {
    write-host "Please pass a hostname with the s argument"
    break
}

You could also tell PowerShell not to warn you when an error occurs in this script by setting

$ErrorActionPreference = SilentlyContinue

This will make PowerShell quietly suppress the error and attempt to continue with script execution. However, for obvious reasons, it's probably not the best idea to suppress your errors.

malgca
  • 2,707
  • 2
  • 16
  • 9
0

Param([parameter(mandatory =$true, helpmessage= "you silly goat.")] $SQL)

excuse the terseness, on a phone ;)

x0n
  • 51,312
  • 7
  • 89
  • 111
0

If I read your intentions right you want error, not prompt... so:

# MyScript
param (
    $sql = $(throw @"
    Oops!
    Dude, this script requires SQL parameter!
    Run it like that: .\MyScript -s <hostname>
"@)
)
    "Got $sql"
}

You can use v1 "mandatory" parameter.

BartekB
  • 8,492
  • 32
  • 33
0

A simple way to MyScript.ps1:

Param( [switch]$sql, [string]$_ValueSql )
if ($_ValueSql){​​​​​​​
    [String]$sql=$_ValueSql
}​​​​​​​ else {​​​​​​​
    [String]$sql=""
}​​​​​​​
"sql=$sql"


Results:

.\MyScript.ps1
sql=

.\MyScript.ps1 -s
sql=

.\MyScript.ps1 -s abcd
sql=abcd