2

This creates a new directory as expected:

new-item "c:\newdir" -itemtype directory

This also works:

$arr = "one", "two"
$arr | new-item -name {$_} -itemtype directory

Resulting in two new folders: c:\one and c:\two (assuming current directory is c:).

This fails with the error "The given path's format is not supported."

$arr = "c:\one", "c:\two"
$arr | new-item -name {$_} -itemtype directory

How can I make this work with a drive letter in the path?

1
  • Note to future readers: {$_} looks like it should be ${_}, but it is - and is meant to be - a script-block argument, that effectively binds each input object passed through the pipeline as-is to the specified parameter. A - partially outdated - explanation of this approach can be found here; nowadays, the approach only works with parameters that are designed to take pipeline input in principle. Commented May 31, 2017 at 22:39

3 Answers 3

5

tl;dr:

  • Preferably, pass the paths array directly to the (implied) -Path parameter:

    $arr = 'c:\one', 'c:\two'
    # Positional use of $arr implies -Path
    New-Item $arr -ItemType Directory
    
  • Alternatively, via the pipeline and a script-block parameter value:

    $arr = 'c:\one', 'c:\two'
    $arr | New-Item -Path { $_ } -ItemType Directory
    
  • With directory names and their shared parent path specified separately:

    $arr = 'one', 'two'
    $arr | New-Item -Name { $_ } -ItemType Directory -Path C:\
    

If you do not specify a parameter name, New-Item binds the 1st positional argument to the -Path parameter.

Therefore,

new-item "c:\newdir" -itemtype directory

is the same as:

new-item -Path "c:\newdir" -itemtype directory

New-Item -? will tell you that -Path accepts an array of strings:

New-Item [-Path] <String[]> ...

Therefore, you don't even need the pipeline and can just pass your array of paths directly:

New-Item 'c:\one', 'c:\two' -ItemType Directory

Several of New-Item's parameters accept pipeline input, and the only one that accepts input by value (input object as-is) is -Value, which doesn't help here.

The remaining pipeline-binding parameters require binding by property name matching the parameter name.

To determine which parameters accept pipeline input, run Get-Help -full New-Item and search for instances of string Accept pipeline input? True. This approach works with all cmdlets.

Thus, in order to bind to parameter -Path, the input objects must have .Path properties:

$arr = [pscustomobject] @{ Path = 'c:\one' }, [pscustomobject] @{ Path = 'c:\two' }
$arr | New-Item -ItemType Directory

However, given that any pipeline-binding parameters can take script blocks as parameter values that are evaluated for each input object, this can be simplified to:

$arr = 'c:\one', 'c:\two'
$arr | New-Item -Path { $_ } -ItemType Directory

Automatic variable $_ reflects the pipeline object at hand, which in this case are the input strings in turn.

A - partially outdated - explanation of this approach can be found here; nowadays, the approach works solely with parameters that are designed to take pipeline input in principle.

The command at the top with -Name { $_ } and -Path C:\ - specifying the names separately from the shared parent path - works analogously.


As for what you tried:

-Name accepts directory names only; only -Path accepts paths.

Trying to bind the input paths to -Name results in error message:

The given path's format is not supported.

because the input paths contain characters such as : and \ that cannot be part of a directory / file name.

Sign up to request clarification or add additional context in comments.

Comments

2

You need to combine the -name with -path for new-item to work correctly.

New-Item -Name "Name" -itemType directory -path "C:\"

You could create an array of hashtable entries instead with the path as one entry and the name as another entry. Or, if the path is always going to be the same just pass it in as another variable.

1 Comment

This answer doesn't solve the OP's problem as stated. Presumably, it was accepted because it made the OP realize that you cannot pass paths to -Name and instead must pass mere directory names AND combine that with -Path set to the shared parent path in which to create the directories with the specified names.
0

When we do this:

new-item "c:\newdir" -itemtype directory

"C:\newdir" is automatically resolved to the Path parameter of New-Item because it's in position 1. That makes it work

When we do this:

$arr | new-item -name {$_} -itemtype directory

Each value of $arr is put through the pipeline by value, which resolves to the Value parameter of New-Item. Since it has a Value AND a Directory ItemType, it throws a fit.

The Help file for New-Item shows that Path is a string[]. This means you can just do this:

$arr = "c:\one", "c:\two"
new-item -Path $Arr -itemtype directory

And it will create directories for all the values in $Arr.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.