Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BAT/CMD file to remove drive letters using DISKPART

I am trying to write a batch file to remove drive letters that are assigned to partitions with no file system. I cannot use wmi since it is being used in a WinPE recovery environment.

DISKPART> list volume

  Volume ###   Ltr  Label          Fs              Type         Size      Status     Info
  ----------   ---  -----------   -----      ----------      -------   ---------  --------
  Volume 0       K                              DVD-ROM         0 B   No Media
  Volume 1       L                              DVD-ROM         0 B   No Media
  Volume 2       C   Windows 7    NTFS        Partition        80 GB  Healthy      System
  Volume 3       D                            Partition       500 GB  Healthy      System
  Volume 4                                    Partition       500 GB  Healthy      System
  Volume 5       E                            Partition       500 GB  Healthy      System

DISKPART> exit 

For loop = 0 to 5
If Type[loop]="Partition" then
    If Ltr[loop]<>"" then
        If Fs[loop]="" then
            SELECT VOLUME loop
            REMOVE LETTER Ltr[loop]
       End If
    End If
End If
Next

This is what I have so far...

@echo off

For /F "Tokens=1,2,3,4,5,6*" %%I In ('echo.list volume^|diskpart.exe^|findstr /I /R /C:"Volume [0-9]"') Do (
echo %%I %%J %%K %%L %%M %%N
if "%%N"=="Partition" (
if NOT "%%K"=="" (
if "%%M"=="" (
echo mountvol %%K: /D
)
)
)
)

The above does not work because the output is space delimited and some blank columns mess up the parsing.

Another attempt, I think this works, but it could be better

@echo off
cd /d "%~dp0"
for /f "skip=8 tokens=*" %%A in ('echo.list volume && echo.exit^|%windir%\system32\diskpart.exe') do (
echo.%%A ^^| find /I "       Partition" >nul && (
for /f "tokens=3 delims= " %%B in ("%%A") do (echo.mountvol %%B: /D)
)
)
pause
exit

Do you know why the above needs 2 ^ before the | (pipe) ?

@echo off
for /f "skip=9 tokens=*" %%A in ('echo.list volume^| diskpart') do (
echo."%%A"| find /I "       Partition" >nul && (
for /f "tokens=3 delims= " %%B in ("%%A") do (echo.mountvol %%B: /D & mountvol %%B: /D)
)
)
pause
exit

The above seems to be working now, I had to put double quotes around the echo."%%A" and then I removed the 2 ^ before the pipe.

@echo off
setlocal enableDelayedExpansion
set "validDrives=;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z;"
for /f "skip=9 tokens=*" %%A in ('echo.list volume^| diskpart') do (
echo."%%A"| find /I "       Partition" >nul && (
for /f "tokens=3 delims= " %%B in ("%%A") do (
if "!validDrives:;%%~B;=!" neq "!validDrives!" (echo.mountvol %%B: /D & mountvol %%B: /D)
)
)
)
pause
exit

The above is my working script, I added some code to validate the drive letter.

If anybody can offer suggestions on how to improve this then please do!

Thanks

like image 331
articlebot Avatar asked Aug 15 '15 13:08

articlebot


1 Answers

I may have a much simpler solution for you. Just grab the whole line and use batch sub-strings to pull out the right pieces

@echo off
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
    for /f "delims=" %%i in ('^
        echo list volume ^|^
        diskpart ^|^
        findstr Volume ^|^
        findstr /v ^
        /c:"Volume ###  Ltr  Label        Fs     Type        Size     Status     Info"^
       ') do (
        set "line=%%i"
        set letter=!line:~15,1!
        set fs=!line:~32,7!
        if not "       "=="!fs!" (
            if not " "=="!letter!" (
                call :removeVol !letter!
            )
        )
    )
endlocal
exit /b

:removeVol
    (
        echo select volume %1
        echo remove letter %1
    ) | diskpart
exit /b

The for statement produces of listing of volumes without the column headers or separators.

The do statement does the sub-string operations.

Ensure that you have admin privilege for the diskpart command. I am a bit curious about your WinRE environment. Most of the ones I've worked in did have a minimal WMI instance running, as well as WSH which would make this code much cleaner.

like image 157
Dan Avatar answered Sep 30 '22 17:09

Dan