powershell equivalent of linux "mkdir -p"?

Viewed 16900

How can I get the powershell "mkdir" command to act exactly like Linux's mkdir -p command?

Under Linux, mkdir -p will create nested directories, but only if they don't exist already. For example, suppose you have a directory /foo that you have write permissions for. mkdir -p /foo/bar/baz creates bar and baz within bar under existing /foo. You run the same command over again, you will not get an error, but nothing will be created.

4 Answers

You can ignore errors in PowerShell with the -ErrorAction SilentlyContinue parameter (you can shorten this to -ea 0). The full PowerShell command is

New-Item /foo/bar/baz -ItemType Directory -ea 0

You can shorten this to

md /foo/bar/baz -ea 0

(You can also type mkdir instead of md if you prefer.)

Note that PowerShell will output the DirectoryInfo object it creates when using New-Item -ItemType Directory (or the md or mkdir aliases). If you don't want any output, you can pipe to Out-Null.

New-Item -Path "c:\some\folder\path" -ItemType Directory

The PowerShell equivalent of Unix
mkdir -p ... is
$null = New-Item -Type Directory -Force ...

-Force, like -p, implements desired-state logic, which ensures two things:

  • It creates intermediate directories in the target directory path that may not exist yet on demand (New-Item -Type Directory, unlike Unix mkdir, even does that by default).

  • It succeeds if the target directory already exists.

One crucial difference: Unless an error occurs:

  • mkdir -p produces no output.
  • By contrast, New-Item -Type Directory outputs a [System.IO.DirectoryInfo] instance representing the target directory. Thus, to emulate the behavior of mkdir -p, this output must be discarded, which is best done by assigning to $null ($null = New-Item ...)

Caveat:

  • On Windows, mkdir is a built-in wrapper function that passes arguments through to New-Item -Type Directory

  • On Unix-like platforms - in the cross-platform PowerShell [Core] v6+ edition - mkdir is not a built-in command, and instead defers to the platform-native external mkdir utility.

  • Thus, if your scripts need to be cross-platform, use New-Item explicitly.


Note: If you omit -Force and simply ignore errors, as shown in Bill Stewart's answer (with -ErrorAction SilentlyContinue or -ErrorAction Ignore), you get similar behavior, except that the output behavior will vary situationally:

  • If the target directory already exists, no output is produced (because an error occurs that is ignored), whereas if the target directory is created, a [System.IO.DirectoryInfo] instance representing it is returned.

  • A fundamental difference between New-Item -Type Directory and Unix mkdir is that only the former creates intermediate directories on demand by default.
    mkdir only does so with -p.

What about using mkdir with -Force? That seems to work for me, it will create all the directories from the specified path, and won't result in an error if they already exist.

mkdir path/to/my/target/dir -force

Results in:

PS > mkdir path/to/my/target/dir -force
    Directory: C:\Users\Sam\path\to\my\target

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          25/09/2020    13:18                dir

# We can check that all directories have been created
PS > tree path
C:\USERS\SAM\PATH
└───to
    └───my
        └───target
            └───dir

# Let's run again now that the directories already exist
PS > mkdir path/to/my/target/dir -force
    Directory: C:\Users\Sam\path\to\my\target

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          25/09/2020    13:20                dir


# And check the result of the previous command
PS > $?
True
Related