Quoted strings in Dynamic ValidateSet


Recently I ran into the problem with validate set and strings containing spaces.
Found this great post by Rohn Edwards with a solution using a C# class.

I’m wondering if it would be possible to use a native approach instead?
Tried the following code, but the overloaded ToString() from a PSCustomObject does not seem to be called when the ValidateSet is enumerated.

Does it have something to do with ToString() being overloaded by a ScriptMethod?

Function _New-CustomObjForQuotedString {
    $obj = [PSCustomObject]@{
                        Value = $InputString
                        QuoteCharacter = $QuoteCharacter

    $obj | Add-Member -MemberType ScriptMethod -Name ToString -Value {
        if ( ($this.Value).contains(' ') ) {
            return $($this.QuoteCharacter)+$($this.Value)+$($this.QuoteCharacter)
        } else {
            return $this.Value
    } -Force

    return $obj

function TestDynamicSetWithSpace_PSNative {

    dynamicparam {
		# from https://powershell.org/forums/topic/dynamic-parameter-question/#post-22381
        $ParamDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $Attributes = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Attributes.Add( (New-Object System.Management.Automation.ParameterAttribute) )

        # Convert each object into a DynParamQuotedString:
        $Attributes.Add( (New-Object System.Management.Automation.ValidateSetAttribute($__DynamicParamValidateSet | % { _New-CustomObjForQuotedString -InputString $_ })) )

        $ParamDictionary.$__DynamicParamName = New-Object System.Management.Automation.RuntimeDefinedParameter (
            [PSCustomObject],    # Notice the type here

        return $ParamDictionary

    process {
        $ParamValue = $null
        if ($PSBoundParameters.ContainsKey($__DynamicParamName)) {
            # Get the original string back:
            $ParamValue = $PSBoundParameters.$__DynamicParamName

        "$__DynamicParamName = $ParamValue"

Overridden, not overloaded, actually. An overload is when you have multiple copies of a method, each with a different signature (parameters). And in this case, it’s possible, yes, that the ScriptMethod is not being called. I’m not sure what happens under the hood, but if it happens “outside” PowerShell proper, then it’d be calling the base class ToString(), not the tacked-on ToString() from the ETS. I think a custom class might be the only way to do that.