cmdletbinding issues

Good afternoon;

I’m attempting figure out the best way to handle a null or empty entry and validate accuracy of $servername. ValidateNotNullorEmpty displays an error message would like validateNotNullorEmpty to inform the user their entry must contain a value, validatescript does not like multiple entries, ideally get-vm would allow multiple entries.

Any input would be greatly appreciated.

Norm

 

 

[CmdletBinding()]
Param ([parameter(mandatory,
HelpMessage="Enter one or more VM names separated by commas. Value should not be null or empty")]
[ValidateNotNullOrEmpty()]
[ValidateScript ({ get-Vm $servername })]
[String[]]$servername)

You can use more than just simple scripts in validation scripts - so if we treat the parameter as an array we can do a foreach in there.

[CmdletBinding()]
Param ([parameter(mandatory,
				  HelpMessage = "Enter one or more VM names separated by commas. Value should not be null or empty")]
	[ValidateNotNullOrEmpty()]
	[ValidateScript ({
			foreach ($item in $_)
			{
				try
				{
					get-Vm $item
				}
				catch
				{
					throw "The server name $($item) is invalid"
				}
			}
		})]
	[String[]]$servername)

It’s not that ValidateScript dislikes multiple entries, it’s just that passing an array directly to Get-VM like that may or may not be properly supported, and you need to be more careful in how you validate.

Here’s how I’d construct that:

https://gist.github.com/vexx32/a55d5f778cd4e115ed18d0e0a0958efd

For more details on this type of completion and validation, see my blog post here. Note that since you’re validating the parameter with the Get-VM command it’s essentially redundant to use [ValidateNotNullOrEmpty()] although if you wish to be extra sure, you can still include that just in case.

And, if you happen to be working with a recent version of PS Core, as I mention towards the end of the blog post, you can also use a lesser-known feature of [ValidateSet()] to make this happen cleanly. :slight_smile:

Hello Joel;
When a I run your response with a valid vm I get the following:
[3:33 PM]ndl@FWTS012:Powercli $ .\parm_help_prompt.ps1
cmdlet parm_help_prompt.ps1 at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
servername[0]: fwapp020
servername[1]:
D:\PowerShell_Test\Powercli\parm_help_prompt.ps1 : Cannot validate argument on parameter ‘servername’. The "
foreach ($Name in $_) {
if (-not (Get-VM $Name -ErrorAction SilentlyContinue)) {
throw “Please enter a valid VM Name.”
}
}
" validation script for the argument with value “fwapp020” did not return a result of True. Determine why the validation script failed, and then try the command again.
At line:1 char:1

  • .\parm_help_prompt.ps1
  •   + CategoryInfo          : InvalidData: (:) [parm_help_prompt.ps1], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,parm_help_prompt.ps1
    
    
    

Pardon my ignorance, I don’t what your doing with the following section:

param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
            if ($WordToComplete) {
                @((Get-VM).Name) -match "^$WordToComplete" 

What is the purpose of $command…etc, they look like variables that should be set,

Thank you for your help
Norm

Hello Paul;
Wanted to let you know your script worked, did follow Joel’s advice and remove ValidateNotNullOrEmpty() since it wasn’t accomplishing anything. Wondering if you could let me know how to assign points.

Thank you for your input
Norm

@Norm , for you current problem, you would not require the [ArgumentCompleter()] attribute, it’ll behave like a dynamic [ValidateSet()]

you could try changing it like below.

[ValidateScript(
        {
            foreach ($Name in $_) {
                if (-not (Get-VM $Name -ErrorAction SilentlyContinue)) {
                    throw "Please enter a valid VM Name."
                }
                $true
            }
        }
    )]

Hello kvprasoon

Your suggestion worked perfectly, thank you

Norm