0

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)
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
  • 1
    Maybe this is just a typo, but you are missing the second `}` on the last `Select-Object`. After adding the missing `}`, the code works for me in a console where everything is defined within that console. – AdminOfThings Jul 03 '19 at 17:27

1 Answers1

1

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)
        }
    }
}
AdminOfThings
  • 23,946
  • 4
  • 17
  • 27
  • As an aside, even though the missing `}` fixed the issue at hand; I ended up taking your code snippet advice. It became apparent that the piping was adding overhead to the *final* operation of a renaming of the files. Because the `if` statement demonstrated it could be easily switched out from creating the custom object to doing the actual rename operation with the info at hand. Thanks for your help and the suggestion. – ΩmegaMan Jul 05 '19 at 12:59