1

Using the code below is it possible to exclude any directories that have any characters A-Z in the directory name and just add directories with numerical values to the array. This was working fine until the developers starting adding new folders into the C:\Program Files\Tableau\Tableau Server\ directory with the latest versions. An example of the folder names is 10.0, 10.1, 10.2, 10.4, Install, Bin

$Array = Get-ChildItem "C:\Program Files\Tableau\Tableau Server" |
         ? { $_.PSIsContainer } |
         Sort-Object LastWriteTime -Descending |
         foreach { $_.Name }
$TABCMD = "C:\Program Files\Tableau\Tableau Server\" + $Array[0] + "\bin\tabcmd.exe"
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328

1 Answers1

2

A streamlined PSv3+ solution:

$array = (Get-ChildItem -Directory "C:\Program Files\Tableau\Tableau Server\[0-9]*" | 
          Sort-Object -Descending LastWriteTime).Name -match '^\d+\.\d+$'
  • -Directory - to limit matching to directories - takes the place of the separate ? { $_.PSIsContainer } pipeline segment.

  • Wildcard pattern [0-9]* limits matches to directories whose names start with a digit. Unfortunately, wildcard expressions aren't sophisticated enough to enforce that a variable-length filename be entirely composed of digits and periods - unless you're willing to assume a fixed length; e.g., [0-9][0-9].[0-9] to match something like 10.0.
    If you cannot make this assumption, the later regular expression-based filtering step via -match allows you to weed out false positives; you then don't strictly need the wildcard matching up front, but it's more efficient to limit the potential matches.

  • (...).Name uses member-access enumeration to collect the .Name property values of all objects returned by the enclosed command in an array.

  • -match '^\d+\.\d+$' then uses a regular expression to filter the array to only include names such as 10.0 - tweak this as necessary.


The PSv2 equivalent:

$array = (Get-ChildItem "C:\Program Files\Tableau\Tableau Server\[0-9]*" | 
          ? { $_.PSIsContainer } |
          Sort-Object -Descending LastWriteTime | % { $_.Name }) -match '^\d+\.\d+$'

Ansgar Wiechers suggests the following variant, which eliminates a separate -match operation and also matches names more simply by excluding folders that contain at least one (English) letter:

$array = Get-ChildItem "C:\Program Files\Tableau\Tableau Server\[0-9]*" | 
          ? { $_.PSIsContainer -and $_.Name -notmatch '[a-z]' } |
          Sort-Object -Descending LastWriteTime | % { $_.Name }
mklement0
  • 382,024
  • 64
  • 607
  • 775