1

I am trying to test several paths and if any fail, create the paths.

$subFolders = "$sortByProject$projectName\Originals", "$sortByProject$projectName\Pulled", "$sortByProject$projectName\Retouched", "$sortByProject$projectName\Uploaded"
if(!(Test-Path -Path "$sortByProject$projectName", "$subFolders")){
  New-Item -ItemType Directory -Path "$sortByProject$projectName", "$subFolders"
}

The test finds "$sortByProject$projectName" exists but "$subFolders" fails, so output appears like:

True
False

I would think since a false is returned, it would move to the new-item command and build all four requested folders (.\originals, .\pulled, .\retouched and .\uploaded). All the variable are properly named and return the desired path when called independently. I think the mess up is because there are multiple items assigned to $subfolders, but I don't understand why.

I also think this code is sloppy and would love to learn a better way to do a multiple path test and create any of the missing paths.

mklement0
  • 382,024
  • 64
  • 607
  • 775
Garrett
  • 617
  • 12
  • 30
  • 2
    `$subfolders` is an array. If you surround it in quotes like `"$subfolders"` the array will be converted to string with all elements being space-delimited. – AdminOfThings May 14 '21 at 20:04
  • thanks, that was a typo. I think @jbsmith has offered a good & 'clean' solution. – Garrett May 14 '21 at 20:08

2 Answers2

3

You don't need to explicitly test the existence of your directory paths:

Just use New-Item's -Force switch in combination with -ItemType Directory, which will create the specified directories on demand - including parent directories - while leaving existing directories alone (and returning directory-info objects describing the preexisting / newly created directories).

New-Item -Force -ItemType Directory -Path $subFolders

As for what you tried:

  • Your Test-Path command returns an array of Booleans, and PowerShell considers any 2+-element array $true in a Boolean context - irrespective of its element values; see the bottom section of this answer for a summary of the PowerShell's to-Boolean coercion rules.

  • -Path "$sortByProject$projectName", "$subFolders" has two problems:

    • Not only is double-quoting variable values passed as command arguments never necessary in PowerShell, in the case of the array variable $subFolders using "$subFolders" turns the array into a single string containing the (stringified) elements separated with spaces.
    • If you correct this immediate problem - by using
      -Path $sortByProject$projectName, $subFolders - another problem is revealed: you aren then in effect passing a jagged array, whose first element is a string, and whose second element is a nested array, which would break the invocation.
      • Correcting this problem requires a perhaps non-obvious approach: you must use + rather than , in order to construct a flat array, which in turn requires that the LHS already be an array, which requires using the unary form of ,, the array constructor operator, and switching to an expression, enclosed in (...), the grouping operator:
        -Path (, $sortByProject$projectName + $subFolders)
mklement0
  • 382,024
  • 64
  • 607
  • 775
1
$subfolders | where {-not (Test-Path $_)} | Foreach-Object { New-Item -ItemType Directory -Path $_ }
jbsmith
  • 1,616
  • 13
  • 10
  • this is perfect, it fixes the issue and doesn't try to build parts of the variable that may already exist i.e. no errors. Great work, thanks. – Garrett May 14 '21 at 20:10
  • I thought this was working but i am getting an error stating the path is null, seems the $_ isnt maintaining the specific paths defined by $subfolders, any thoughts? – Garrett May 14 '21 at 20:17