Search code examples
powershellscriptblock

Expression on Column Addition To Object Receives Error Hash Literal Incomplete


Why am I able to do a command outside the script block, but not inside it?

My final goal is to sort a directory listing based on predefined categories. The code creates a dynamic object from the directory listing and adds two columns. The first column created is a category derived from the name, the second column that is based on the first is an index for later sorting.


Actual Error

The hash literal was incomplete.
At line:0 char:0

Stand Alone Working Code

$importance = "Hierarchy", "Item", "UPC", "Color", "Price"
$importance.IndexOf('UPC') # returns 2

Failure Code

The overall task is to do a directory listing and ultimately sort the list by $importance. By creating dynamic columns, it will be sorted (not shown) on that new column named Index.

$match = "UPC|Item|Color|Price|Hierarchy"

gci $incrementalTargetDir `
| Select-Object Name, @{label="Category"; Expression= {[regex]::match($_.BaseName, $match).Groups[0].Value}} `
| Select-Object Name, @{label="Index"; Expression= { $importance.IndexOf($_.Category) } 

Fails on the second Select-Object


First select successfully returns this data:

Name                        Category
----                        --------
ColorStyleSize.txt          Color
Item.txt                    Item
FieldProductHierarchy.txt   Hierarchy
UPC.txt                     UPC
PriceAdjust.txt             Price

Also tried adding scoping script: with the same result:

 …. Expression= { $script:importance.IndexOf($_.Category)

Solution

  • I was able to replicate the problem by running this code as a script. The missing closing } for the hash table in the second Select-Object throws this error. Once the missing } is added, I was able to run the code without issues.

    An alternative approach is to use a foreach loop and custom object output. You can remove the if statement if you do not want to exclude non-matched items.

    $incrementalTargetDir = 'Drive:\Folder1\Folder2'
    $importance = "Hierarchy", "Item", "UPC", "Color", "Price"
    $match = "UPC|Item|Color|Price|Hierarchy"
    
    foreach ($file in (Get-ChildItem $incrementalTargetDir)) {
        $Category = $null
        $Category = [regex]::match($file.BaseName, $match).Groups[0].Value
    
        if ($Category) {
            [pscustomobject]@{
                Name = $file.Name
                Category = $Category
                Index = $importance.IndexOf($Category)
            }
        }
    }