cheat sheet

mkdir / md

Create one or more directories from the Windows command prompt. Covers single and nested directory creation, batch patterns, and common scripting idioms.

mkdir / md — Make Directory

What it is

mkdir (also md) is a built-in cmd.exe command that creates one or more new directories. Unlike the Unix mkdir, the Windows version automatically creates intermediate parent directories — there is no need for a -p flag. md is a shorthand alias; both forms are identical.

Availability

mkdir and md are built into cmd.exe on every Windows version. PowerShell equivalent: New-Item -ItemType Directory (or mkdir, which PowerShell aliases to New-Item).

cmd
mkdir /?

Output:

css
Creates a directory.

MKDIR [drive:]path
MD [drive:]path

Syntax

One or more directory paths, space-separated. Paths containing spaces must be quoted.

cmd
mkdir path [path ...]
md path [path ...]

Output: (none on success; error if path already exists or parent drive missing)

Essential options

mkdir has no switches — all behaviour is controlled through the path argument.

FormMeaning
mkdir dirnameCreate in the current directory
mkdir C:\path\to\dirAbsolute path — intermediate parents created automatically
mkdir dir1 dir2 dir3Create multiple directories in one call
mkdir "dir with spaces"Quoted path for names containing spaces

Creating a single directory

cmd
mkdir logs

Output: (none — exits 0 on success)

cmd
rem Full absolute path
mkdir C:\Projects\myapp\output

Output: (none — exits 0 on success)

cmd
rem md alias
md C:\Temp\scratch

Output: (none — exits 0 on success)

Creating nested directories

Windows mkdir creates all intermediate parent directories automatically — no equivalent of the Unix -p flag is needed.

cmd
rem Creates Projects, myapp, src, and components in one call
mkdir C:\Projects\myapp\src\components

Output: (none — exits 0 on success)

cmd
rem Relative nested path from current directory
mkdir reports\2026\Q2

Output: (none — exits 0 on success)

Creating multiple directories at once

Space-separate multiple paths to create them in a single invocation.

cmd
mkdir src tests docs build dist

Output: (none — exits 0 on success)

cmd
rem Multiple absolute paths
mkdir C:\Data\raw C:\Data\processed C:\Data\output

Output: (none — exits 0 on success)

Paths with spaces

Enclose the path in double quotes when any component contains a space.

cmd
mkdir "C:\Users\alicedev\My Projects\Q1 Report"

Output: (none — exits 0 on success)

cmd
mkdir "dist files" "build output" "test results"

Output: (none — exits 0 on success)

Using environment variables

mkdir expands %VARIABLE% in paths, which is handy in batch scripts.

cmd
set PROJECT=myapp
mkdir C:\Projects\%PROJECT%\src C:\Projects\%PROJECT%\tests

Output: (none — exits 0 on success)

Common pitfalls

  1. mkdir on an existing path raises an error — use if not exist to guard against it in scripts.
  2. Spaces without quotes create wrong directoriesmkdir My Project creates two directories named My and Project, not one named My Project.
  3. Drive must existmkdir Z:\folder fails if drive Z: is not mounted; map the drive first.
  4. Long path names — paths over 260 characters may fail; enable long path support via Group Policy or the registry key HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled = 1.

Real-world recipes

Scaffold a project structure in one block

cmd
mkdir src\models src\views src\controllers
mkdir tests\unit tests\integration
mkdir docs build dist

Output: (none — exits 0 on success)

Create a timestamped backup folder

cmd
for /f "tokens=1-3 delims=/ " %a in ("%DATE%") do set STAMP=%c%b%a
mkdir C:\Backups\%STAMP%
echo Backup folder: C:\Backups\%STAMP%

Output:

yaml
Backup folder: C:\Backups\20260428

Create a directory only if it doesn't already exist

cmd
if not exist C:\Logs mkdir C:\Logs
echo Log directory ready.

Output:

arduino
Log directory ready.

Create output directory before writing a file in a batch script

cmd
@echo off
set OUTDIR=C:\Reports\%DATE:~-4,4%-%DATE:~-10,2%
if not exist "%OUTDIR%" mkdir "%OUTDIR%"
echo Report generated on %DATE% > "%OUTDIR%\summary.txt"
echo Done.

Output:

code
Done.

Command extensions and parent creation

The implicit-parent behaviour relies on cmd.exe having Command Extensions enabled (the default on every modern Windows install). When extensions are disabled — for example by cmd /E:OFF or the EnableExtensions registry value — mkdir reverts to the strict MS-DOS behaviour and refuses to create intermediate directories. This is the single biggest portability gotcha for scripts that may run under custom shell launchers.

cmd
rem Check whether extensions are on
cmd /E:ON /C "mkdir C:\Temp\level1\level2\level3"

Output: (none — succeeds because extensions are on)

cmd
rem With extensions off, intermediate parents fail
cmd /E:OFF /C "mkdir C:\Temp\level1\level2\level3"

Output:

lua
The system cannot find the path specified.
cmd
rem Defensive script: enable extensions explicitly
setlocal EnableExtensions
mkdir C:\Reports\2026\Q2\week17
endlocal

Output: (none — exits 0 on success)

Reserved and invalid names

cmd.exe inherits the DOS reserved-device names: CON, PRN, AUX, NUL, COM1COM9, LPT1LPT9. Attempting mkdir CON silently appears to succeed in some shells but the directory is unusable (Explorer cannot enter it, cd refuses). Filenames may not contain < > : " / \ | ? *. Trailing spaces and trailing dots are stripped by Win32 unless you prefix with \\?\.

cmd
rem Reserved device name — do not use
mkdir CON

Output:

csharp
The directory name is invalid.
cmd
rem Trailing dot is stripped silently
mkdir "spaces."
dir /B "spaces."

Output:

code
spaces
cmd
rem To force literal trailing chars, use the \\?\ namespace
mkdir "\\?\C:\Temp\trailing. "

Output: (none — directory created with literal trailing space and dot, but Explorer cannot delete it without the same prefix)

Long path support

The historical MAX_PATH ceiling of 260 characters still applies to mkdir on Windows 10 versions prior to 1607 and to any process not opting in via its manifest. Windows 10 1607+ adds LongPathsEnabled (HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled = 1) and a per-app manifest setting longPathAware. Alternatively the \\?\ prefix bypasses the limit unconditionally — but most cmd.exe builtins, including mkdir, treat the prefix literally and can fail in unexpected ways.

cmd
rem Enable long path support globally (PowerShell, elevated)
reg add HKLM\SYSTEM\CurrentControlSet\Control\FileSystem /v LongPathsEnabled /t REG_DWORD /d 1 /f

Output:

code
The operation completed successfully.
cmd
rem Even with the registry key set, cmd.exe builtins may not honour it.
rem When in doubt, use PowerShell or robocopy for deeply nested paths.
powershell -NoProfile -Command "New-Item -ItemType Directory -Path 'C:\very\deeply\nested\path\that\exceeds\two\hundred\sixty\characters\and\then\some\more\depth' -Force"

Output:

lua
    Directory: C:\very\deeply\nested\path\that\exceeds\two\hundred\sixty\characters\and\then\some\more

mkdir creates only standard directories. To create reparse points use mklink /J (junction) or mklink /D (directory symbolic link). Junctions are local-only and resolve at the filesystem layer; symbolic links can target UNC paths but require either the SeCreateSymbolicLinkPrivilege or Developer Mode.

cmd
rem Create a real directory, then a junction pointing to it
mkdir C:\Data\actual
mklink /J C:\Data\link C:\Data\actual

Output:

bash
Junction created for C:\Data\link <<===>> C:\Data\actual
cmd
rem Directory symbolic link (requires admin or Dev Mode)
mklink /D C:\Quick C:\Users\alicedev\Documents\Projects

Output:

bash
symbolic link created for C:\Quick <<===>> C:\Users\alicedev\Documents\Projects

PowerShell equivalents

PowerShell exposes directory creation through New-Item -ItemType Directory. The mkdir and md names are also defined as PowerShell functions (not aliases), wrapping New-Item so the calling convention matches cmd.exe. New-Item accepts pipeline input, supports -WhatIf for dry runs, -Force to ignore "already exists", and returns the created DirectoryInfo object — none of which the cmd.exe builtin can do.

powershell
# Direct New-Item — verbose form
New-Item -ItemType Directory -Path C:\Projects\myapp\src\components

Output:

lua
    Directory: C:\Projects\myapp\src

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----            5/24/2026  10:00 AM                components
powershell
# mkdir works in PowerShell too — it is a function, not the cmd builtin
mkdir C:\Logs\app

Output:

lua
    Directory: C:\Logs

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----            5/24/2026  10:00 AM                app
powershell
# -Force: do not error if the directory already exists
New-Item -ItemType Directory -Path C:\Logs\app -Force | Out-Null

Output: (none — silent success even on re-run)

powershell
# -WhatIf: dry run, show what would happen without doing it
New-Item -ItemType Directory -Path C:\Logs\preview -WhatIf

Output:

csharp
What if: Performing the operation "Create Directory" on target "Destination: C:\Logs\preview".
powershell
# Create many directories from a list via pipeline
'src','tests','docs','build','dist' | ForEach-Object {
    New-Item -ItemType Directory -Path "C:\Projects\myapp\$_" -Force
} | Out-Null

Output: (none — five directories created silently)

CMD vs PowerShell vs bash comparison

GoalCMDPowerShellbash (Linux/macOS)
Create one dirmkdir foomkdir foo or New-Item -ItemType Directory foomkdir foo
Create nestedmkdir a\b\c (auto)mkdir a\b\c or New-Item -ItemType Directory a/b/c -Forcemkdir -p a/b/c
Multiple in one callmkdir a b cmkdir a,b,c (array) or 'a','b','c' | % { mkdir $_ }mkdir a b c or mkdir -p {a,b,c}
Idempotent (no error if exists)if not exist foo mkdir fooNew-Item -ItemType Directory foo -Forcemkdir -p foo
Dry run / preview(none built in)New-Item -ItemType Directory foo -WhatIf(none built in; use echo mkdir foo)
Set permissions on creation(separate icacls call)New-Item ... ; Set-Acl ...mkdir -m 0755 foo
Path with spacesmkdir "my dir"mkdir 'my dir'mkdir 'my dir'

Common pitfalls (continued)

  1. Command extensions off — under cmd /E:OFF the implicit-parent behaviour disappears. Wrap scripts in setlocal EnableExtensions to guarantee extensions are on.
  2. Reserved device names succeed but produce unusable directories — never name a folder CON, PRN, AUX, NUL, COM1COM9, or LPT1LPT9.
  3. Trailing dots and spaces are silently strippedmkdir "foo. " produces foo. Use \\?\ paths if literal trailing chars are required.
  4. mkdir does not create files — it only makes the directory. Use copy NUL filename or type NUL > filename to create empty files inside it.
  5. No permission flags — unlike Linux mkdir -m 0755, Windows mkdir always inherits the parent's ACL. Apply ACLs separately with icacls after creation.

Real-world recipes (continued)

Scaffold a Python project layout idempotently

cmd
@echo off
setlocal EnableExtensions
set ROOT=C:\Projects\new_app
for %%D in (src src\tests docs build dist .github\workflows) do (
    if not exist "%ROOT%\%%D" mkdir "%ROOT%\%%D"
)
echo Scaffolded %ROOT%.
endlocal

Output:

code
Scaffolded C:\Projects\new_app.

Mirror an existing directory tree's skeleton without copying files

cmd
rem Use xcopy /T /E to recreate folder structure only
xcopy C:\Projects\template C:\Projects\new_clone /T /E /I

Output:

scss
0 File(s) copied

Create a daily logs directory in PowerShell, idempotent

powershell
$date = Get-Date -Format 'yyyy-MM-dd'
$dir  = "C:\Logs\$date"
New-Item -ItemType Directory -Path $dir -Force | Out-Null
"Log started at $(Get-Date)" | Out-File "$dir\session.log"

Output: (none — directory and log file created silently)

Create and stack-navigate with pushd

pushd creates a directory entry in a navigation stack and is also the only way to make a UNC path the working directory of cmd.exe — it transparently maps a temporary drive letter and switches to it. Useful when paired with a freshly created folder.

cmd
mkdir C:\Temp\scratch
pushd C:\Temp\scratch
echo Working in: %CD%
popd

Output:

yaml
Working in: C:\Temp\scratch

Pre-create a robocopy destination with timestamps preserved

cmd
set DEST=D:\Backups\myapp_%DATE:~-4,4%%DATE:~-10,2%%DATE:~-7,2%
mkdir "%DEST%"
robocopy C:\Projects\myapp "%DEST%" /E /COPYALL /DCOPY:T /R:3 /W:5

Output:

yaml
   Files :        42        42         0         0         0         0

Sources

References consulted while writing this article. Links open in a new tab.

  • Microsoft Learn — mkdir command reference — Authoritative flag list and parameter semantics used to build the Essential options table.
  • SS64 — mkdir — Cross-version comparison and historical syntax notes.

See also

  • rmdir — the inverse: remove directories created with mkdir.
  • cd — navigate into a directory after creating it.
  • xcopy /T /E — replicate a directory tree's skeleton without files.
  • robocopy — copies typically create their own destination tree automatically.
  • mklink — when you need a junction or symbolic link rather than a real directory.
  • icacls — apply ACLs after mkdir, since Windows has no permission flag at creation time.