Parameter Sets

Hi,

I’ve successfully used ParameterSetNames to limit the choices at runtime for scripts and functions, including using multiple parameter sets in the past.

I’m trying to get my head around the following use case:

I’ve written objects in the New-x, Get-x, Remove-x format and now I’m looking at the Update-x function. This object currently takes a name and a label parameter as these are the available properties for this object.

As part of my update, I want to limit the update of the object to an existing object, so I’m using a dynamic parameter (-Name) with a collection of the existing objects to ensure that the user can only update an object that exists.

What I’m trying to do define my parametersets to support the following input parameters:

Update-x -Name "List of available objects in a validateset as dynamicparameter" -NewName 'NewObjectName'
Update-x -Name "List of available objects in a validateset as dynamicparameter" -NewLabel 'NewObjectLabel'
Update-x -Name "List of available objects in a validateset as dynamicparameter" -NewName 'NewObjectName' -NewLabel 'NewObjectLabel'

Essentially, I want to
always provide an object name, with a newname or
always provide an object name, with a newlabel or
always provide an object name, with a new name and a new label

I can’t keep them all in the same parameter set and then force with Mandatory = $true because if I run:

update-x -Name ‘SomeName’ -NewName ‘SomeNewName’

that will force me to provide a new label when I want to keep the existing label in place.

When I use ParameterSet and cover my multiple parameter sets, because newname and newlabel can be updated, there seems to be no way to distinguish if I just provide a newname or a newlabel.

Is there a way around this that I’m missing?

I’m aware I could validate within my function, but this object is a base object for multiple objects which will have much more properties to update, so I’m trying to handle this with parameter sets rather than in-function validation as I think that scales better.

Thanks for any assistance

So you really only need to validate when both -NewName and -NewLabel are missing - and the ParameterSet logic doesn’t really do that. The only thing I could think of would be to…

-NewInformation @{Name=‘whatever’;Label=‘whatever’}

Because you could validate that in a ValidateScript. But it’s a little ugly.

I suppose you could also have sets for:

-NewName -UseExistingLabel
-NewLabel -UseExistingName
-NewLabel -NewName

And let the switches throw you out of the set with both new name and label. Not super-elegant, though. But ParameterSets can’t “activate” based on missing parameters, which is essentially what you’re wanting.

Thanks for the pointers.

I’d considered using switches to force the ParameterSet but -NewInformation would work better I guess for the later functions I want to write that have more than 2 properties. I guess one issue I can think of is as more properties are added to objects, its not clear what properties an object exposes for update.

I guess what I’m doing in my update, is using my New-x function to regenerate the object by instantiating a new instance of the object class and removing the original object.

This got me thinking, is there a way to take the constructors from a class and use those as the input parameters for a function? I don’t think I’ve seen that before, I’m reasonably new to classes as we didn’t have v5 throughout our entire server estate until recently, but is it possible?

Thanks for your help

“This got me thinking, is there a way to take the constructors from a class and use those as the input parameters for a function?”

I’m not sure I follow what you’re asking.

If you have a PowerShell class, the default constructor will just instantiate the object without any overloads.

If you have other constructors available, you can use [ClassName]::New to show the overloads required when instantiating the object. I wondered if there was a way to expose the overloads as function parameters.

I think I’m massively over complicating things and I should just take -NewObject and strongly type that to be the same type as the object type I want to update.

I agree with the latter statement ;). And no, there’s no way to directly expose class methods (which is all a constructor is, in the end) as function parameters. You’d have to code that “connection” yourself.

Yeah, that seems much better, -NewObject I guess is less work and more consistent for the later functions.

Thanks for the help!

Cheers,

AJ