'The specified wildcard pattern is not valid' thrown if -properties contain square brackets that violate PS wildcard rules #116

piers7 opened this Issue Jul 23, 2014 · 2 comments


None yet

2 participants

piers7 commented Jul 23, 2014

Get-Variable / Set-Variable and Test-Path attempt to support wildcarding on the name supplied. They all fail if you pass them a name as follows: a[b-a] because they see [b-a] as a broken wildcard range.

This bites psake when it attempts to push variables into child scopes for task execution, and apply supplied -properties arguments over the top of those in the script. Psake passes the name of the properties literally to Test-Path, which causes the error:

You can replicate this as follows:

.\psake.ps1 -file:AnyPsakeFileItDoesntMatter -properties:@{'a[b-a]'=1}

Or as follows (which is what psake ends up doing as a result):

Test-Path 'Variable:\a[b-a]'

I've raised a (Connect article for this)[https://connect.microsoft.com/PowerShell/feedback/details/926973/set-variable-throws-the-specified-wildcard-pattern-is-not-valid-if-variable-name-contains-or-chars-in-some-cases], because I feel existing PowerShell behavior is actually broken. However, there is a workaround that I think psake should implement till they fix it :-) which is to escape the names passed to set-variable / get-variable / test-path by prefixing the square brackets with backticks as follows (if I can get the markdown right :)

$safeKey = ($.Key -replace '[','[') -replace ']',']';
Set-Variable -Name:$safeKey -Value:$

This bit me with OctopusDeploy, because (in my case) it passes in properties of exactly that form which - just because of my role names - end up having backwards ranges within them. If interested, I blogged about this


@piers7, just in case if you did not find a workaround yourself, pass all such properties as an extra hashtable:

.\psake.ps1 -file:AnyPsakeFileItDoesntMatter -properties:@{props = @{'a[b-a]'=1; 'a[c-b-b]'=2; ...}}

Then you can access them in a script as $props['a[b-a]'], $props['a[c-b-b]'], ...

piers7 commented Jul 25, 2014

@nightroman nice. Unfortunately that's not going to work for me. Nesting the properties in that way would would bypass the reason for using properties in the first place (having defaults set in psake that can be overridden from the outside). It'd be 'pass them all or nothing'.

What instead I've ended up doing is pre-filtering the hashtable of variables that OctopusDeploy provides, prior to passing to PSake (since the properties that are causing problems aren't ones I care about anyway). Like this:

$psakeArguments = @{} 
foreach($item in $OctopusParameters.GetEnumerator()){
     if(!$item.Key -like 'Octopus.*'){
         $psakeArguments[$item.Key] = $item.Value;
 # ...
 .\psake.ps1 mybuildfile -properties:$psakeArguments

This way I still get to override any property in my psake script by creating a variable with the same name in Octopus, but I filter out the OctopusDeploy intrinsic/built-in ones (which are the ones causing the issue)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment