Search code examples
powershellvalidateset

ValidateSet with 3001 elements causes long pause


Here's a simple function that uses ValidateSet:

function TestLongValidateSet
{
    param
    (
        [ValidateSet(...)]
        $abc
    )

    $abc
}

My version has 3001 items instead of the ....

If you'd like to follow along at home, here's a way to generate a 3001 element list suitable for placing in there:

(0..3000 | foreach { (Get-Random -Count 30 (65..90 | ForEach-Object { [char]$_ })) -join '' } | ForEach-Object { "`"$_`"" }) -join ', ' | Out-File test.txt

Anyway, the above function loads into PowerShell just fine. However, the first attempt at using IntelliSense with it triggers a multi-minute delay. PowerShell ISE also proceeds to consume a couple of gigabytes of RAM. After this delay, the RAM usage drops back to normal, IntelliSense works, and everything's responsive. Even the completion on the $abc variable is responsive.

Is there anyway to avoid the long initial delay?


Solution

  • Try this. It creates a custom enum type, and uses that instead of ValidateSet

    0..3000 | foreach { (Get-Random -Count 30 (65..90 | ForEach-Object { [char]$_ })) -join '' } | sv enumarray
    
    $i=0
    $enumlist = ($enumarray | foreach {'{0} = {1}' -f $_,$i++}) -join ', '
    
     $enum = " 
    namespace myspace 
    { 
    public enum myenum 
    { 
     $enumlist
    } 
    } 
    " 
    Add-Type -TypeDefinition $enum -Language CSharpVersion3
    

    You can put that inside the function, but on my system, creating the enum takes about 200ms. If you're going to run this inside a loop, I'd create it in the parent scope so the function doesn't have to do it every time it runs.

    function TestLongValidateSet
    {
    param
    (
        [myspace.myenum]$abc
    )
    
    $abc
    }