6

I'm making a call to a powershell script:

powershell.exe -file basic.ps1 -User ""

I have other parameters, this is simplified.

The PS script accepts the params :

[CmdLetBinding()]
param(
   [Parameter(Mandatory=$true)]
   [AllowEmptyString()]
   [string]$User = 't'
)

When I run the command, I get:

Missing an argument for parameter 'User'. Specify a parameter of type 'System.String' and try again.

I was under the assumption that AllowEmptyString would allow this?

4
  • 1
    Why are you making the parameter mandatory if you want to allow it to be empty? What are you doing with the variable later in your script? Commented May 1, 2018 at 10:37
  • Don't run your script from cmd.exe. (Why?) Run it from a PowerShell prompt. Commented May 1, 2018 at 15:34
  • It is working from cmd.exe, doesnt work form powershell propmt. Commented May 2, 2018 at 9:47
  • It is mandatory because i dont have control of the calling script. It will always pass these values, I then need to know further down if it is an empty string - in this case empty string is a valid value. Its working now based on the answer from below Commented May 2, 2018 at 9:49

1 Answer 1

18

It doesn't sound like you want a mandatory parameter at all. Making it mandatory will require input which makes the default value useless. However, let's get back to the error your described.

The attribute works as expected. The problem is how you're calling your script. Lets try the following code as a function and a script:

[CmdLetBinding()]
param(
[Parameter(Mandatory=$true)]
[AllowEmptyString()]
[string]$User = 't'
)

"`$User has value '$user'. Is it null? $($user -eq $null). Type is $($user.GetType().Name)"

Demo:

#Inside a function
PS> t -User ""
$User has value ''. Is it null? False. Type is String

#Inside a script
PS> .\Untitled-5.ps1 -User ""
$User has value ''. Is it null? False. Type is String

#Running the following command from cmd
cmd> powershell.exe -file Untitled-5.ps1 -User "" 
$User has value ''. Is it null? False. Type is String

However, when you run the last line in a PowerShell-session, then PowerShell will parse the string which results in an empty value (no quotes) for the parameter.

PS> powershell.exe -file Untitled-5.ps1 -User "" 
D:\Downloads\Untitled-5.ps1 : Missing an argument for parameter 'User'. Specify a parameter of type 'System.String' and
 try again.
    + CategoryInfo          : InvalidArgument: (:) [Untitled-5.ps1], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingArgument,Untitled-5.ps1

Powershell.exe is not intended to be used inside a PowerShell-process. You can fix this by calling scripts directly inside a PowerShell-process (second example), run PowerShell.exe … from cmd/run/scheduled task ++ (anywhere else) or by making sure PS doesn't parse your arguments so it will actually input the quotes.

This can be done by escaping the quotes

PS> powershell -File Untitled-5.ps1 -User `"`"

Or by using --%

PS> powershell -File Untitled-5.ps1 --% -User ""
Sign up to request clarification or add additional context in comments.

3 Comments

It was running it from within a powershell session that was causing the issue. I was running it like that for testing, but when runing it from cmd it worked perfect
What does "--%" do? It doesn't seem to have any effect on the problem for me
It's a "stop parsing" symbol/operator (PS3+). It makes powershell treat the rest of command as literal string. In other words, and arguments++ after it will not use variables and expressions, but simply write e.g. $myvarname. --% will not be seen by the executed script/executable, it's just for the engine executing your command.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.