585

Can anybody tell me how to do the following in in a Windows batch script? (*.bat):

  • Create a folder only if it doesn't already exist

In more detail, I want to create a folder named VTS on the C:\ drive, but only if that folder doesn't already exist. I don't want to overwrite the contents of the folder if it already exists and the batch is executed.

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
Bill
  • 5,851
  • 2
  • 15
  • 3

13 Answers13

764

You just use this: if not exist "C:\VTS\" mkdir C:\VTS it wll create a directory only if the folder does not exist.

Note that this existence test will return true only if VTS exists and is a directory. If it is not there, or is there as a file, the mkdir command will run, and should cause an error. You might want to check for whether VTS exists as a file as well.

D. A.
  • 3,369
  • 3
  • 31
  • 34
The Answerer
  • 7,673
  • 1
  • 11
  • 2
  • 9
    Except that it's wrong. You have to check for the NUL device, otherwise it won't work. See my answer three years earlier than this one. – Martin Schapendonk Feb 11 '16 at 21:39
  • 2
    @MartinSchapendonk This works on Windows 7 and Windows Server 2012 as far as I can tell from testing, and I'd be very surprised if it doesn't work at least back to XP and up to Windows 10. Can you provide the conditions when this doesn't work? – jpmc26 Mar 10 '16 at 19:00
  • 17
    @jpmc26 testing for NUL is to make sure you test for a directory. Otherwise the condition might evaluate to true, even it is a regular file. That is the difference. – Martin Schapendonk Mar 13 '16 at 10:24
  • 7
    @MartinSchapendonk Is adding a trailing slash is sufficient for that? That seems to distinguish between files and directories correctly, but there is a weakness in that if the file is not detected, creation of the directory will fail. I suspect this is a problem with testing for `NUL`, too. – jpmc26 Mar 13 '16 at 19:31
  • 11
    @jpmc26 You are right, a trailing slash does the job and is actually preferable since it works with quotes (thus allowing you to have spaces in the directory path). To distinguish between either file/directory, this will work: `if exist "a" if not exist "a\" (echo "it's a file") else (echo "it's a dir")`. About your last sentence, I suspect something is wrong with your batch file elsewhere. – Marc.2377 Dec 12 '16 at 03:45
  • @MartinSchapendonk the article mentioned FAT format. Does it work under NTFS? – Weipeng Jul 09 '22 at 01:29
  • Something to note is that when creating folders with spaces in their names, even if it's from a variable, always enclose the target directory with quotation marks, for example: `MKDIR "!pathYouWantToCreate!"` – Puntherline Apr 06 '23 at 22:27
259
if exist C:\VTS\NUL echo "Folder already exists"

if not exist C:\VTS\NUL echo "Folder does not exist"

See also https://support.microsoft.com/en-us/kb/65994

(Update March 7, 2018; Microsoft article is down, archive on https://web.archive.org/web/20150609092521/https://support.microsoft.com/en-us/kb/65994 )

Martin Schapendonk
  • 12,893
  • 3
  • 19
  • 24
  • 12
    Personally I'd prefer this since it does not set %errorlevel% when dir already exists (Agent_9191's answer returns an error code of 1) – csauve Jun 18 '12 at 14:02
  • 1
    It's also nice and generic and can be applied to every other action you want to conditionally do :) – John Humphreys Jul 20 '12 at 13:40
  • 1
    The article has some extremely convoluted information about what drive formats this works for and doesn't. – jpmc26 Mar 08 '16 at 02:28
  • I don't know why, but this doesn't work for me: `@echo off if exist C:\Dropbox\Target\SplitBins9x55\NULL echo "Folder already exists, Skip 1"` `if not exist C:\Dropbox\Target\SplitBins9x55\NULL mkdir C:\Dropbox\Target\SplitBins9x55` – YouHaveaBigEgo Sep 29 '16 at 00:45
  • 3
    @YouHaveaBigEgo `NUL` is with one L. – Martin Schapendonk Sep 29 '16 at 04:38
  • If your location has spaces, you are out of luck with this one. `if exist "C:\V T S\NUL"` won't work correctly. In this case, skip the `NUL` portion altogether and simply do `if exist "C:\V T S\"`. – Marc.2377 Dec 12 '16 at 03:47
  • 7
    Actually, although this answer is great, it does not answer to the question to "create a directory" :) – Jean-Francois T. Apr 11 '18 at 02:41
  • This won't (sometimes) work in multithreaded or multiprocessed case (like make -j4). If more than one process or thread does this command simultaneously, it is fairly possible that both will first detect that directory is missing, then attempt to create it. Note that mkdir -p on Linux works fine in such a case. – Mekk Nov 04 '19 at 08:08
  • Does this work in PowerShell? It says "Missing '(' after 'if' in if statement." for me. – Aaron Franke May 07 '20 at 05:37
  • 1
    Doesn't work for me on an NTFS drive. The archived article also just mentions FAT drives. – Michael Sebald Sep 29 '20 at 06:59
68

Just call mkdir C:\VTS no matter what. It will simply report that the subdirectory already exists.

Edit: As others have noted, this does set the %ERRORLEVEL% if the folder already exists. If your batch (or any processes calling it) doesn't care about the error level, this method works nicely. Since the question made no mention of avoiding the error level, this answer is perfectly valid. It fulfills the needs of creating the folder if it doesn't exist, and it doesn't overwrite the contents of an existing folder. Otherwise follow Martin Schapendonk's answer.

Community
  • 1
  • 1
Agent_9191
  • 7,216
  • 5
  • 33
  • 57
  • 30
    this is a bad behavior due an unexpected error message / warning. – SeriousM Apr 25 '13 at 13:13
  • 17
    Calling something "perfectly valid" when it violates best practices is intellectually dishonest. As another example: When somebody asks you how to avoid a certain specific security problem, your answer shouldn't be "run the computer as an administrator" even if the question didn't explicitly specify minimum security impact as a prerequisite. :-) – Jouni Heikniemi Jun 12 '14 at 05:59
  • 3
    @JouniHeikniemi s/best practices/Jouni's personal preferences – dss539 Sep 08 '15 at 22:29
  • 1
    @dss539 It _is_ my personal preference that processes do not raise unnecessary error codes or exceptions. I also think it is a best practice, and a generally accepted one at that. You can, of course, disagree - but I would think some arguments might make your stance more understandable. – Jouni Heikniemi Sep 10 '15 at 19:41
  • 2
    @JouniHeikniemi imo, the `%ERRORLEVEL%` is a fine way to return the result of an operation. It's very similar to `errno` in the C std library http://www.cplusplus.com/reference/cerrno/errno/ Some people could easily argue that the C std library followed/established "best practices" as defined by some group. I guess my point is that "best practices" is highly subjective, and this guy's suggestion follows somebody's best practices (e.g. C std lib and others), so to call him intellectually dishonest seems a bit of a stretch. – dss539 Sep 10 '15 at 21:22
  • 4
    Nothing wrong with Errorlevel or errno. They are platform-specific error messaging paradigms, and they work for the purpose they have been built for. But no matter what the platform or messaging approach is, I wouldn't recommend the "try to do this and recover if it fails" pattern when you can easily avoid - and thus legibly document - the common error case. Hence, I do find the "if not exists"-style approaches superior. But, I don't want or care to go too deep into a debate about the formation of best practices. I had no intention of offending anyone, just wanted to clarify my downvote. – Jouni Heikniemi Sep 12 '15 at 20:39
  • 4
    The problem with simply ignoring the error is that you don't know *why* it failed. It could have failed because the directory already existed, because the user doesn't have permissions on that directory, because the parent path didn't exist, or because the disk failed. "Create if it doesn't exist" should fail in all cases except the first. This answer results in an error in all cases, though. That's why it's unsuitable for a batch script. -1 – jpmc26 Mar 10 '16 at 19:04
  • 1
    This is the normal programming pattern. Do then test. Testing then doing requires three disk accesses. Doing then testing requires two. Testing the result of a Do (if you care) is comparing an integer rather than reading a disk when testing first. So less battery power is used, program is quicker. One core principal of programming is to conserve resources, esp on multitasking computers. –  Dec 22 '19 at 18:22
  • @user12431753 But there is other core principal of programming before conserve resources - Fail Fast. Lets say you are programming car breaks. It is better to have an error on a car engine start than assume that everything went ok on start despite some error and have an unpleasant surprise on the road. – digital_infinity Aug 05 '21 at 15:29
  • You can avoid the error level by redirecting output to nul: MKDIR Path\To\Create 2> nul – user1760150 Feb 21 '22 at 16:52
53
mkdir C:\VTS 2> NUL

create a folder called VTS and output A subdirectory or file TEST already exists to NUL.

or

(C:&(mkdir "C:\VTS" 2> NUL))&

change the drive letter to C:, mkdir, output error to NUL and run the next command.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
3years2late
  • 539
  • 4
  • 3
  • Is there a way to make this work in PowerShell? It doesn't seem to support `NUL` as an output file. – Aaron Franke May 07 '20 at 05:38
  • 1
    @AaronFranke https://stackoverflow.com/questions/16906170/create-directory-if-it-does-not-exist/16911470#16911470 – rofrol Jul 07 '21 at 10:01
35
set myDIR=LOG
IF not exist %myDIR% (mkdir %myDIR%)
Robie Nayak
  • 819
  • 10
  • 18
  • 2
    As others have pointed out and you may have seen in the top rated answer, this does not work if you have a file named `log`. It's a subtle difference, but it will lead to hard-to-find bugs in your scripts. – Abel Sep 28 '17 at 01:32
25

I use this way, you should put a backslash at the end of the directory name to avoid that place exists in a file without extension with the same name as the directory you specified, never use "C:\VTS" because it can a file exists with the name "VTS" saved in "C:" partition, the correct way is to use "C:\VTS\", check out the backslash after the VTS, so is the right way.

@echo off
@break off
@title Create folder with batch but only if it doesn't already exist - D3F4ULT
@color 0a
@cls

setlocal EnableDelayedExpansion

if not exist "C:\VTS\" (
  mkdir "C:\VTS\"
  if "!errorlevel!" EQU "0" (
    echo Folder created successfully
  ) else (
    echo Error while creating folder
  )
) else (
  echo Folder already exists
)

pause
exit
D3F4ULT
  • 926
  • 1
  • 12
  • 20
  • 4
    What is particularly interesting of your solution, is that you use `!errorlevel!`, i.e., delayed expansion. Otherwise, the variable `ERRORLEVEL` would be parsed prior to entering the first `if` (i.e., at parse time). Now it is parsed at execution time, so it can capture the result of `mkdir`. You are also correct in that, even though you test for existence, you should still test for success (think: access denied error, for instance). Very good solution compared to the others, +10!!! – Abel Sep 28 '17 at 01:41
22

You can use:

if not exist "C:\VTS\" mkdir "C:\VTS"

You can also expand the code to replace any missing expected files.

if not exist "C:\VTS\important.file" echo. > "C:\VTS\important.file"
10

This should work for you:

IF NOT EXIST "\path\to\your\folder" md \path\to\your\folder

However, there is another method, but it may not be 100% useful:

md \path\to\your\folder >NUL 2>NUL

This one creates the folder, but does not show the error output if folder exists. I highly recommend that you use the first one. The second one is if you have problems with the other.

Lumito
  • 490
  • 6
  • 20
9

You need to create a folder if it doesn't exist eh? Well, here is an example of how to do it.

First, I check to see if the folder doesn't already exist by entering this code:

if not exist "FOLDERPATH" ( 
    mkdir "FOLDERPATH"
)

So if I run the code. And if the folder already exists, It will do nothing. This is what we do if the folder already exists:

if exist "FOLDERPATH" ( 
    rmdir /s /q "FOLDERPATH"
    mkdir "FOLDERPATH"
)

Now if I run the code, It will re-create the folder if it already exists. This is the example code:

@echo off
cls

if not exist "C:\ExamplePath\" ( 
    echo Creating Folder...
    mkdir "C:\ExamplePath\"
    pause
)

if exist "C:\ExamplePath\" ( 
    echo Re-Creating Folder...
    rmdir /s /q "C:\ExamplePath"
    pause
)

Now the if exist part is Optional. If the folder already exists, you can jump to an label instead like this:

if exist "FOLDERPATH" ( 
    goto :ExampleLabel
    
    :ExampleLabel
    echo Hi.
    pause
)

Hopefully, this could help with your problem.

i Mr Oli i
  • 605
  • 5
  • 12
DevX
  • 106
  • 1
  • 5
1

Personally, I would do this:

if not exist "C:\YourFolderPathHere\" (
mkdir C:\YourFolderPathHere\
) else (
echo Folder already exists!
)

Let's break that down:

  1. if not exist "C:\YourFolderPathHere\": this checks for the folder. The Backslash (\) after the path is very important, else it will look for a file rather than a folder.
  2. mkdir C:\YourFolderPathHere\: Creates the directory if the above statement is true.
  3. echo Folder already exists!: prints to console that it already exists.

Here's the same code, but with comments:

::Does the folder exist?
if not exist "C:\YourFolderPathHere\" (
::No, make it.
mkdir C:\YourFolderPathHere\
) else (
::Yes, don't make it, and print text.
echo Folder already exists!
)

One-line version: if not exist "C:\YourFolderPathHere\" mkdir C:\YourFolderPathHere\

Haven't tested it though, so don't quote me on it.

i Mr Oli i
  • 605
  • 5
  • 12
0

i created this for my script I use in my work for eyebeam.

:CREATES A CHECK VARIABLE

set lookup=0

:CHECKS IF THE FOLDER ALREADY EXIST"

IF EXIST "%UserProfile%\AppData\Local\CounterPath\RegNow Enhanced\default_user\" (set lookup=1)

:IF CHECK is still 0 which means does not exist. It creates the folder

IF %lookup%==0 START "" mkdir "%UserProfile%\AppData\Local\CounterPath\RegNow Enhanced\default_user\"
Harry
  • 87,580
  • 25
  • 202
  • 214
0

I'm creating a folder in the context of docker from a Dockerfile to avoid build stopping in error if folder already exists on a mkdir command, and none of answer here worked for me, but some inspired me to try this, that works (the RUN is Dockerfile command that, by default on Windows docker, runs in context of cmd):

RUN mkdir C:\VTS & echo.
gluttony
  • 402
  • 6
  • 14
-5

You can add the /I option to the mkdir command. The /I option tells mkdir to only create the directory if it doesn't already exist. If the directory already exists, the mkdir command will do nothing and continue with the next command.

mkdir /I dist