How to Create a Folder If It Doesn’t Exist in PowerShell

To create a folder if it does not exist in PowerShell, check it with Test-Path -PathType Container and run New-Item when the check comes back False:

$path = 'C:\psfaqs\Sales\Reports'
if (-not (Test-Path -Path $path -PathType Container)) {
    New-Item -Path $path -ItemType Directory | Out-Null
}

That pattern is safe to run on every script start. Below I cover the -Force shortcut, the .NET method, a reusable function, and two traps I hit while testing in PowerShell 7 and Windows PowerShell 5.1.

Create a folder if it doesn’t exist with Test-Path and New-Item

The Test-Path cmdlet returns True or False, so it fits straight into an if statement. I ran the same check twice in one script to show both branches:

$path = 'C:\psfaqs\Sales\Reports'
foreach ($run in 1, 2) {
    if (-not (Test-Path -Path $path -PathType Container)) {
        New-Item -Path $path -ItemType Directory | Out-Null
        "Run ${run}: created $path"
    }
    else { "Run ${run}: $path already exists" }
}

Output:

Run 1: created C:\psfaqs\Sales\Reports
Run 2: C:\psfaqs\Sales\Reports already exists
PowerShell creates a folder only if it does not exist using Test-Path and New-Item
The first run creates Reports, the second run skips it (PowerShell 7)

New-Item prints a directory listing for every folder it creates. Piping it to Out-Null keeps the script output clean, which matters in scheduled tasks and logs.

Why -PathType Container matters

A plain Test-Path returns True for files too. If a file happens to have your folder’s name, the check passes and your script carries on without a folder:

$path = 'C:\psfaqs\Sales\Archive'
Set-Content -Path $path -Value 'not a folder'     # a file named Archive
"Test-Path:           $(Test-Path -Path $path)"
"Test-Path Container: $(Test-Path -Path $path -PathType Container)"
$result = New-Item -Path $path -ItemType Directory -Force
"New-Item -Force returned: $(if ($result) { 'a folder' } else { 'nothing' })"
"Archive is still a:  $((Get-Item -Path $path).GetType().Name)"

Output:

Test-Path:           True
Test-Path Container: False
New-Item -Force returned: nothing
Archive is still a:  FileInfo
PowerShell Test-Path returns True for a file with the folder name, -PathType Container returns False
A file named Archive fools plain Test-Path and New-Item -Force (PowerShell 7)

New-Item -Force didn’t create the folder and didn’t raise an error either. It just returned nothing, in both PowerShell 7 and 5.1.

Adding -PathType Container makes the check fail, so you notice. The same idea applies when you create a file only if it doesn’t exist, where you’d use -PathType Leaf.

Does New-Item -Force overwrite an existing folder?

No. For folders, -Force returns the existing folder and leaves its contents alone. That makes it a one-line way to create a folder if it doesn’t exist:

$path = 'C:\psfaqs\Sales\2026\Q4'
New-Item -Path $path -ItemType Directory | Out-Null    # also creates Sales\2026
Set-Content -Path "$path\forecast.csv" -Value 'Region,Total'
$again = New-Item -Path $path -ItemType Directory -Force
"Returned:   $($again.FullName)"
"Files kept: $((Get-ChildItem -Path $path).Name)"
"mkdir:      $((mkdir -Path $path -Force).Name)"

Output:

Returned:   C:\psfaqs\Sales\2026\Q4
Files kept: forecast.csv
mkdir:      Q4

forecast.csv survived, and the first New-Item call also built the missing Sales\2026 parent. The mkdir function, which calls New-Item -ItemType Directory, accepts -Force the same way.

Files are different: -Force on an existing file replaces it with an empty one. See the New-Item cmdlet guide for that case.

Create a folder with [System.IO.Directory]::CreateDirectory

The .NET method creates every missing folder in the path and doesn’t complain if the folder is already there. The catch is how it reads a relative path:

Set-Location -Path 'C:\psfaqs\Sales'
$rel = [System.IO.Directory]::CreateDirectory('Receipts')
"Relative path: $($rel.FullName)"
$full = Join-Path -Path (Get-Location) -ChildPath 'Receipts'
$dir = [System.IO.Directory]::CreateDirectory($full)
"Full path:     $($dir.FullName)"
"Exists:        $([System.IO.Directory]::Exists($full))"

Output:

Relative path: C:\psfaqs\Receipts
Full path:     C:\psfaqs\Sales\Receipts
Exists:        True

Set-Location moved PowerShell to C:\psfaqs\Sales, but the relative call created C:\psfaqs\Receipts. .NET resolves relative paths against the process folder, not your current PowerShell directory. Always pass a full path, as the second call does.

Create multiple folders with a reusable function

When a script needs several folders, I wrap the check in a small function. It uses -LiteralPath so a folder name with square brackets is read as plain text:

function New-FolderIfMissing {
    param([Parameter(Mandatory)][string[]]$Path)
    foreach ($p in $Path) {
        if (Test-Path -LiteralPath $p -PathType Container) {
            "Exists:  $p"; continue
        }
        New-Item -Path $p -ItemType Directory -ErrorAction Stop | Out-Null
        "Created: $p"
    }
}
$root = 'C:\psfaqs\Sales'
New-FolderIfMissing -Path "$root\Austin", "$root\Logs [2026]"
New-FolderIfMissing -Path "$root\Austin", "$root\Logs [2026]", "$root\Denver"
"Test-Path -Path:        $(Test-Path -Path "$root\Logs [2026]")"
"Test-Path -LiteralPath: $(Test-Path -LiteralPath "$root\Logs [2026]")"

Output:

Created: C:\psfaqs\Sales\Austin
Created: C:\psfaqs\Sales\Logs [2026]
Exists:  C:\psfaqs\Sales\Austin
Exists:  C:\psfaqs\Sales\Logs [2026]
Created: C:\psfaqs\Sales\Denver
Test-Path -Path:        False
Test-Path -LiteralPath: True

The last two lines show why. Test-Path -Path treats [2026] as a wildcard and reports False for a folder that exists, so the function would try to create it again and fail.

For more patterns, see creating multiple folders at once and naming a folder with the current date.

Handle errors when the folder can’t be created

Without -Force, New-Item throws an IOException when the folder already exists. The same applies to a missing drive or a folder you don’t have permission to write to:

$path = 'C:\psfaqs\Sales\Reports'
New-Item -Path $path -ItemType Directory | Out-Null
try {
    New-Item -Path $path -ItemType Directory -ErrorAction Stop | Out-Null
}
catch [System.IO.IOException] {
    "Failed. $($_.Exception.Message)"
    "Error ID: $($_.FullyQualifiedErrorId)"
}