Link to home
Start Free TrialLog in
Avatar of Yaniv Schiff
Yaniv SchiffFlag for United States of America

asked on

dos batch script to automatically create a partition and format it fat32 across multiple drives

I am trying to create a batch file to automatically create a new partition on all disks except disk 0, apply a label to each new partition, then run the fat32format.exe program to format each new partition fat32. After a lot of tinkering and searching on the internet (and EE) i was able to piece together the attached code which works well to create a new partition on each disk (except disk 0). I am now trying to build in the assigning of the disk label, which i wouldn't care about except that it seems fat32format.exe requires it to format the drive. I then need to iterate through all the new created partitions formatting them and applying a label. I'm just getting my feet wet coding batch files so please be clear. Thanks!
@echo off
setlocal
set Test=no
set IgnoreForImport=0
set DriveLabel=F
set DPFile1=%~dpn0.dp1
set DPFile2=%~dpn0.dp2
if exist "%DPFile1%" del "%DPFile1%"
if exist "%DPFile2%" del "%DPFile2%"
>>"%DPFile1%" echo rescan
>>"%DPFile1%" echo list disk
echo Rescanning drives ...
for /f "tokens=1 delims=<tab>" %%a in ('diskpart /s "%DPFile1%" ^| find /i "Online"') do (
  DriveLabel
  echo Processing disk %%a ...
  call :process %%a

)
echo Importing drives ...
if /i "%Test%"=="no" (
  diskpart /s "%DPFile2%"
  echo Test mode is inactive
) else (
  echo Test mode is active; the following diskpart script would have been run:
  type "%DPFile2%"
)
if exist "%DPFile1%" del "%DPFile1%"
if exist "%DPFile2%" del "%DPFile2%"
echo Done.
goto :eof
:process
for %%a in ("%IgnoreForImport%" ) do (
  if "%2"=="%IgnoreForImport%" (
    echo Ignored %1 %2
    goto :eof
  )
)
>>"%DPFile2%" echo select disk %2
>>"%DPFile2%" echo create partition primary
>>"%DPFile2%" echo select partition 1


goto :eof

Open in new window

Avatar of Michael Pfister
Michael Pfister
Flag of Germany image

You're not stating which OS this script should run. Windows Vista or higher has a format function included in diskpart, see
help format
It also has a label parameter.

If running on a system before Windows Vista, you can use the label DOS command.
See

label /?

HTH

Avatar of Yaniv Schiff

ASKER

I'm running Windows 7, isn't there a limitation though in Xp and newer OS's that they can't format drives bigger than 32GB fat32. That's why i'm using Fat32Format.exe. Also, from what i can dell, the label parameter in diskpart only works if you are formatting the drive.
The idea was to use diskpart to format and label the disks. If there is a limit to 32 GB (I rather use NTFS) also in diskpart, use the DOS label command instead.
Thanks for the tips fister, but i was able to figure it out. While i would rather use NTFS as well, unfortunately our business process requires Fat32. Below is the script i was able to put to together that while not the most robust script, it does do what i need.

There is one other aspect of the script that i would like to update though. The section

::echo y | fat32format f:
::echo y | fat32format g:
::label f: For_Media
::label g: For_Media

which uses the fat32format application to filter the drives. Right now, as you can see the drive letters are hard coded. I would like to dynamically create a list of all the drive letters assigned pass them to fat32format so that i am not limited. I tried using the VOL command but that only works if the drive letters have been formatted already, so the letters don't show up. Are there any other ways to get the drive letters?
@echo off
setlocal
set Test=no
set IgnoreForImport=0
set DPFile1=%~dpn0.dp1
set DPFile2=%~dpn0.dp2
if exist "%DPFile1%" del "%DPFile1%"
if exist "%DPFile2%" del "%DPFile2%"
>>"%DPFile1%" echo rescan
>>"%DPFile1%" echo list disk
echo Rescanning drives ...
for /f "tokens=1 delims=<tab>" %%a in ('diskpart /s "%DPFile1%" ^| find /i "Online"') do (
  echo Processing disk %%a ...
  call :process %%a

)
echo Importing drives ...
if /i "%Test%"=="no" (
  diskpart /s "%DPFile2%"
  echo Test mode is inactive
) else (
  echo Test mode is active; the following diskpart script would have been run:
  type "%DPFile2%"
)
if exist "%DPFile1%" del "%DPFile1%"
if exist "%DPFile2%" del "%DPFile2%"

::----------------------------------------------------
::echo y | fat32format f:
::echo y | fat32format g:
::label f: For_Media
::label g: For_Media 
::-----------------------------------------------------------



echo Done.
goto :eof
:process
for %%a in ("%IgnoreForImport%" ) do (
  if "%2"=="%IgnoreForImport%" (
    echo Ignored %1 %2
    goto :eof
  )
)
>>"%DPFile2%" echo select disk %2
>>"%DPFile2%" echo create partition primary
>>"%DPFile2%" echo select partition 1
>>"%DPFile2%" echo assign
@echo off



goto :eof

Open in new window

See the 2 code snippets. I have no Win7 around right now so I tested the output of diskpart with XP. It may need some adjustment for Win7.

1st snippet 
::----------------------------------------------------
if exist "%DPFile1%" del "%DPFile1%"
>>"%DPFile1%" echo list vol
for /f "tokens=3 delims= " %%a in ('diskpart /s %DPFile1% ^| find /i "Partition"') do Call :FormatPart %%a
if exist "%DPFile1%" del "%DPFile1%"
if exist "%DPFile2%" del "%DPFile2%"


2nd snippet 

:FormatPart
rem never format C: 
If /i "%1" == "C" Goto :EOF
echo y | fat32format %1:
label %1: For_Media
Goto :EOF

Open in new window

will this replace

::echo y | fat32format f:
::echo y | fat32format g:
::label f: For_Media
::label g: For_Media


I tried running it and it relabeled my C: drive and tried formatting it! luckily it errored out. It did format and relable the F: drive though.
Also, do you know how to disable the popup window that asks if i want to format the new drive/partition everytime?
Fister, do you have any idea how to stop the script from attempting to relabel C:?
change the part
:FormatPart
rem never format C:  
If /i "%1" == "C" Goto :EOF
echo y | fat32format %1:
label %1: For_Media

to

:FormatPart
rem never format C:
echo Doing %1  
If /i "%1" == "C" Goto :EOF
echo Would format %1
:
It should start with writing
Doing C
but should never write Would format C

Whats the exact spelling on your machine? Is there a colon behind the C or something else why the if should fail?
I have replaced my protion of code:

::echo y | fat32format f:
::echo y | fat32format g:
::label f: For_Media
::label g: For_Media

with the code attached. Is this correct? When i run it i get an error that DiskPart can't find the necessary script file.
if exist "%DPFile1%" del "%DPFile1%"
>>"%DPFile1%" echo list vol
for /f "tokens=3 delims= " %%a in ('diskpart /s %DPFile1% ^| find /i "Ltr"') do Call :FormatPart %%a
if exist "%DPFile1%" del "%DPFile1%"
if exist "%DPFile2%" del "%DPFile2%"





:FormatPart
rem never format C:
echo Doing %1  
If /i "%1" == "C" Goto :EOF
echo Would format %1
:

Open in new window

Ok, here is what I made of you script. Please set the following variables
set test to "no" (without quotes) to really do something, otherwise the script runs in test-only mode. Run the script in test only mode first and check the output
set Test=y

set IgnoreForImport=0
this variable holds the disk numbers to ignore, i.e.
set IgnoreForImport=035
would ignore disks 0, 3 and 5

Set DoNotFormat=ABC
this variable holds the drive letters to exclude from formatting, here it will never format/labe A:, B: and C:

I have no 2nd drive in my Win7 machine, so I never executed the script against a real disk. But the output seems ok now.

@echo off 
setlocal 
set Test=y 
set IgnoreForImport=0
Set DoNotFormat=ABC
set DPFile1=%~dpn0.dp1 
set DPFile2=%~dpn0.dp2 
if exist "%DPFile2%" del "%DPFile2%"
echo rescan>"%DPFile1%"  
echo list disk>>"%DPFile1%" 
echo Rescanning drives ... 
For /f "tokens=2 delims= " %%a in ('diskpart /s "%DPFile1%" ^| find /i "Online"') do ( 
  echo Processing disk %%a ... 
  call :process %%a 
) 


echo Importing drives ... 
if /i "%Test%"=="no" ( 
  If Exist "%DPFile2%" (
	  diskpart /s "%DPFile2%" 
  	echo Test mode is inactive 
	) else (
	  Echo ERROR: No diskpart script %DPFile2% generated!
	  Goto :EOF
	)
) else ( 
  echo Test mode is active; the following diskpart script would have been run: 
  If Exist "%DPFile2%" (
  	type "%DPFile2%"
	) else (
	  Echo ERROR: No diskpart script %DPFile2% generated!
 	  Goto :EOF
	)
) 
if exist "%DPFile2%" del "%DPFile2%"  
echo list vol>"%DPFile1%" 
for /f "tokens=3 delims= " %%a in ('diskpart /s %DPFile1% ^| find /i "Partition"') do Call :FormatPart %%a 
if exist "%DPFile1%" del "%DPFile1%" 
if exist "%DPFile2%" del "%DPFile2%" 
echo Done. 
goto :eof 

:process 
echo %IgnoreForImport%|Findstr /C:"%1">NUL
If Errorlevel 1 (
 Echo select disk %1>>"%DPFile2%" 
 Echo create partition primary>>"%DPFile2%" 
 Echo select partition 1>>"%DPFile2%" 
 Echo assign>>"%DPFile2%"
) Else (
  Echo Ignored disk %1 
) 
Goto :eof

:FormatPart 
rem never format drives in DoNotFormat
echo %DoNotFormat%|Findstr /I /C:"%1">NUL
If Errorlevel 1 (
if /i "%Test%"=="no" (
 echo y | fat32format %1: 
 label %1: For_Media 

) else (
Echo would run fat32format %1: 
Echo would label %1: For_Media
)
) else (
  Echo Ignored drive %1 
) 
Goto :EOF

Open in new window

Thanks for uploading the whole piece. Two problems though, even after i change Test=no, it still prints out "Test mode is active". and two, i get the error "No diskpart script generated." Attached is the code you supplied, slight modified.
@echo off  
setlocal  
set Test=no 
set IgnoreForImport=0 
Set DoNotFormat=ABCDELMOPSTV 
set DPFile1=%~dpn0.dp1  
set DPFile2=%~dpn0.dp2  
if exist "%DPFile1%" del "%DPFile1%"
if exist "%DPFile2%" del "%DPFile2%"
echo rescan>>"%DPFile1%"   
echo list disk>>"%DPFile1%"  
echo Rescanning drives ...  
For /f "tokens=2 delims=<tab>" %%a in ('diskpart /s "%DPFile1%" ^| find /i "Online"') do (  
  echo Processing disk %%a ...  
  call :process %%a  
)  
 
 
echo Importing drives ...  
if /i "%Test%"=="no" (  
  If Exist "%DPFile2%" ( 
          diskpart /s "%DPFile2%"  
        echo Test mode is inactive  
        ) else ( 
          Echo ERROR: No diskpart script %DPFile2% generated! 
          Goto :EOF 
        ) 
) else (  
  echo Test mode is active; the following diskpart script would have been run:  
  If Exist "%DPFile2%" ( 
        type "%DPFile2%" 
        ) else ( 
          Echo ERROR: No diskpart script %DPFile2% generated! 
          Goto :EOF 
        ) 
)  
if exist "%DPFile2%" del "%DPFile2%"   
echo list vol>>"%DPFile1%"  
for /f "tokens=3 delims=<tab>" %%a in ('diskpart /s %DPFile1% ^| find /i "Ltr"') do Call :FormatPart %%a  
if exist "%DPFile1%" del "%DPFile1%"  
if exist "%DPFile2%" del "%DPFile2%"  
echo Done.  
goto :eof  
 
:process  
echo %IgnoreForImport%|Findstr /C:"%1">NUL 
If Errorlevel 1 ( 
 Echo select disk %1>>"%DPFile2%"  
 Echo create partition primary>>"%DPFile2%"  
 Echo select partition 1>>"%DPFile2%"  
 Echo assign>>"%DPFile2%" 
) Else ( 
  Echo Ignored disk %1  
)  
Goto :eof 
 
:FormatPart  
rem never format drives in DoNotFormat 
echo %DoNotFormat%|Findstr /I /C:"%1">NUL 
If Errorlevel 1 ( 
if /i "%Test%"=="no" ( 
 echo y | fat32format %1:  
 label %1: For_Media  
 
) else ( 
Echo would run fat32format %1:  
Echo would label %1: For_Media 
) 
) else ( 
  Echo Ignored drive %1  
)  
Goto :EOF

Open in new window

1) there seems to be a space character after the
Set Test=no
therefore the compare with "no" doesn't match

@echo off  
setlocal  
set Test=no
set IgnoreForImport=0 
Set DoNotFormat=ABCDELMOPSTV 
set DPFile1=%~dpn0.dp1  
set DPFile2=%~dpn0.dp2  
if exist "%DPFile1%" del "%DPFile1%"
if exist "%DPFile2%" del "%DPFile2%"
echo rescan>>"%DPFile1%"   
echo list disk>>"%DPFile1%"  
echo Rescanning drives ...  
For /f "tokens=2 delims= " %%a in ('diskpart /s "%DPFile1%" ^| find /i "Online"') do (  
  echo Processing disk %%a ...  
  call :process %%a  
)  
 
 
echo Importing drives ...  
if /i "%Test%"=="no" (  
  If Exist "%DPFile2%" ( 
          diskpart /s "%DPFile2%"  
        echo Test mode is inactive  
        ) else ( 
          Echo ERROR: No diskpart script %DPFile2% generated! 
          Goto :EOF 
        ) 
) else (  
  echo Test mode is active; the following diskpart script would have been run:  
  If Exist "%DPFile2%" ( 
        type "%DPFile2%" 
        ) else ( 
          Echo ERROR: No diskpart script %DPFile2% generated! 
          Goto :EOF 
        ) 
)  
if exist "%DPFile2%" del "%DPFile2%"   
echo list vol>>"%DPFile1%"  
for /f "tokens=3 delims= " %%a in ('diskpart /s %DPFile1% ^| find /i "Partition"') do Call :FormatPart %%a
if exist "%DPFile1%" del "%DPFile1%"  
if exist "%DPFile2%" del "%DPFile2%"  
echo Done.  
goto :eof  
 
:process  
echo %IgnoreForImport%|Findstr /C:"%1">NUL 
If Errorlevel 1 ( 
 Echo select disk %1>>"%DPFile2%"  
 Echo create partition primary>>"%DPFile2%"  
 Echo select partition 1>>"%DPFile2%"  
 Echo assign>>"%DPFile2%" 
) Else ( 
  Echo Ignored disk %1  
)  
Goto :eof 
 
:FormatPart  
rem never format drives in DoNotFormat 
echo %DoNotFormat%|Findstr /I /C:"%1">NUL 
If Errorlevel 1 ( 
if /i "%Test%"=="no" ( 
 echo y|fat32format %1:  
 label %1: For_Media  
 
) else ( 
Echo would run fat32format %1:  
Echo would label %1: For_Media 
) 
) else ( 
  Echo Ignored drive %1  
)  
Goto :EOF

Open in new window

2) I changed back both for loops. You can't filter for the column header Ltr, therefore you need to filter for "Partition" to get only partitions.
attached is a screen shot of the result from running the script you posted. The only thing that seems to be happening is my c: partition is getting renamed RAW:For_Media.
result.jpg
Thats really difficult to debug, since I have no add'l disk attached to my system and its WIn 7 German.

Whats the output of the script in test mode?
Whats the output of the following diskpart commands:

list disk
list vol


Here are the results. If you can't debug this than i might just stick with my original script which is hard coded to 4 drives. I can give you some points though for you all your help, which i really appreciate.
result.jpg
list-disk.jpg
list-vol.jpg
Waht I don't understand from your screen shot: where are the disks you want to format? I just see Disk 0, which I assume is your system disk?
sorry about that. here are screenshots from my actually box with the drive attached.
list-disk.jpg
list-vol.jpg
result-in-test-mode.jpg
result-not-in-test-mode.jpg
That was really a hard one :-) Change :process to

:process
SET DRIVE=%1  
echo %IgnoreForImport%|Findstr /C:"%1">NUL
If Errorlevel 1 (
 Echo select disk %DRIVE%>>"%DPFile2%"  
 Echo create partition primary>>"%DPFile2%"  
 Echo select partition 1>>"%DPFile2%"  
 Echo assign>>"%DPFile2%"
) Else (
  Echo Ignored disk %DRIVE%  
)  


getting closer....

Something is still being called improperly though when it gets to the :Formatpart.

I included a screenshot of the output of the List Vol command, i think that's where something is getting messed up, but i could be wrong.
result-in-test-mode.jpg
list-vol.jpg
Add one line after FormatPart

:FormatPart  
If /i "%1" == "RAW" Goto :EOF

This will filter out the RAW drive. After being initilazied there should not be a RAW drive. Anyway...
well my c: partition didn't get relabled but newly created partition didn't get formatted or labeled either. Attached is the result. If i filter out the RAW disks then my newly created partition won't be formatted.
result.jpg
Whats the output of disk part
list disk
and
list vol
and
select disk 1
list part
right after this?
I assume due to the error during select partition in your screen shot, the new partition will not get a drive letter assigned. Without a drive letter, the part trying to format will fail or is ignored.
the drive is being assigned a letter "f", so that is working.
list-disk.jpg
list-part.jpg
list-vol.jpg
Can't follow you. Where is F on you last screen?
ASKER CERTIFIED SOLUTION
Avatar of Michael Pfister
Michael Pfister
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Could you please rerun the corrected script in test mode and post the output?
And another small change:

Line 37:
echo list vol>>"%DPFile1%"

Please change to

echo list vol>"%DPFile1%"
Also nice would be if you can enter the following commands on the command line and post the output:


echo list vol >dp.in
for /f "tokens=3 delims= " %a in ('diskpart /s dp.in ^| find /i "Partition"') do @echo [%a]

Open in new window

OK, so ignore my last post  :-)
I need a beer now ;-)
Ha, i am. Thank you so much for taking the time to work this through. I really appreciate it!
here's that output you requested
output.jpg
i'm gonna run a few tests before closing out the ticket but i think we're good.
works perfectly! i'm reattaching the complete code so it's easy to follow.
@echo off  
setlocal  
set Test=no
set IgnoreForImport=0 
Set DoNotFormat=ABCDELMOPSTV 
set DPFile1=%~dpn0.dp1  
set DPFile2=%~dpn0.dp2  
if exist "%DPFile1%" del "%DPFile1%"
if exist "%DPFile2%" del "%DPFile2%"
echo rescan>>"%DPFile1%"   
echo list disk>>"%DPFile1%"  
echo Rescanning drives ...  
For /f "tokens=2 delims= " %%a in ('diskpart /s "%DPFile1%" ^| find /i "Online"') do (  
  echo Processing disk %%a ...  
  call :process %%a  
)  
 
 
echo Importing drives ...  
if /i "%Test%"=="no" (  
  If Exist "%DPFile2%" ( 
          diskpart /s "%DPFile2%"  
        echo Test mode is inactive  
        ) else ( 
          Echo ERROR: No diskpart script %DPFile2% generated! 
          Goto :EOF 
        ) 
) else (  
  echo Test mode is active; the following diskpart script would have been run:  
  If Exist "%DPFile2%" ( 
        type "%DPFile2%" 
        ) else ( 
          Echo ERROR: No diskpart script %DPFile2% generated! 
          Goto :EOF 
        ) 
)  
if exist "%DPFile2%" del "%DPFile2%"   
echo list vol>>"%DPFile1%"  
for /f "tokens=3 delims= " %%a in ('diskpart /s %DPFile1% ^| find /i "Partition"') do Call :FormatPart %%a
if exist "%DPFile1%" del "%DPFile1%"  
if exist "%DPFile2%" del "%DPFile2%"  
echo Done.  
goto :eof  
 
:process
SET DRIVE=%1  
echo %IgnoreForImport%|Findstr /C:"%1">NUL 
If Errorlevel 1 ( 
 Echo select disk %DRIVE%>>"%DPFile2%"  
 Echo create partition primary>>"%DPFile2%"  
 Echo select partition 1 >>"%DPFile2%"  
 Echo assign>>"%DPFile2%" 
) Else ( 
  Echo Ignored disk %DRIVE%  
)    
Goto :eof 
 
:FormatPart
If /i "%1" == "RAW" Goto :EOF  
rem never format drives in DoNotFormat 
echo %DoNotFormat%|Findstr /I /C:"%1">NUL 
If Errorlevel 1 ( 
if /i "%Test%"=="no" ( 
 echo y|fat32format %1:  
 label %1: For_Media  
 
) else ( 
Echo would run fat32format %1:  
Echo would label %1: For_Media 
) 
) else ( 
  Echo Ignored drive %1  
)  
Goto :EOF

Open in new window

Thank you so much for all your help. This made my day.