[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[系统相关] [已解决]如何在批处理中使用diskpart命令,删除特定卷标的分区

本帖最后由 5i365 于 2021-8-8 17:14 编辑

本人平时删除分区时, 很少使用其它的第三方软件, 都是在PE的磁盘管理下, 使用右键删除分区,  但最近, 非常想尝试一下使用批处理代码来自动删除分区, 看看效果如何,  如果能实现, 以后删分区的操作相对而言就更简单了,改成特定卷标就行了,例如,将要删除分区的卷标改为no,批处理执行后相关的分区就删除了

因为要在PE下使用, 而PE下不能执行wmic命令, 所以只能使用diskpart命令, 具体描述如下:

---先判断WIN分区在哪个硬盘,得到硬盘号!因为是在PE下,Win系统的盘符有可能不为C,所以不能通过盘符做判断, 可以根据分区下是否有windows\system32文件夹判断 【只处理包含window系统的硬盘, 其它的硬盘即使有卷标为no的分区, 也不做处理 】
---删除卷标为no的分区,可能有一个或多个, 而卷标不为no的分区则保留
【根据卷标得出盘符,
然后sel volume=盘符如C 没有冒号:
最后del volume noerr】


---如果该硬盘中有ESP系统引导分区, 即使卷标不是no, 也删除它 【最下面输出信息中 type 为 system 的分区 是esp分区】
---如果该硬盘中有MSR保留分区, 即使卷标不是no, 也删除它 【最下面输出信息中 type 为 Reserved 的分区 是MSR保留分区】
---如果该硬盘中有恢复分区, 即使卷标不是no, 也删除它, 【最下面输出信息中 type 为 Recovery 的分区 是恢复分区】

如果没找到卷标为no的分区, 则弹出下面消息框, 点确定后, 脚本直接退出
start mshta vbscript:msgbox("No partition no was found",0,"tip")(window.close)&&exit

上面几种情况的判断, 应该要根据分区的类型来添加限定条件, 相关代码参考链接:
http://www.bathome.net/redirect. ... 9390&pid=242338

感谢几位大侠所推荐的无忧论坛的专门针对diskpart而写的脚本工具,虽然也可以实现效果,  但是操作步骤感觉不太简单明了, 代码量也非常多, 想自行修改下, 但能力有限, 实在吃不消
另外,还有不少磁盘软件, 如diskgnius, 傲梅助手等, 都可以实现我要的效果, 但是不在此贴的讨论范围, 感觉还是系统内置的工具来的直接
  
期待诸位高手, 尽量能用最少的代码, 实现上面功能, 那将非常震撼, 提前感谢!

下面是完整的手动删除分区操作步骤:
提醒:
为了让代码中英文系统兼容性更好,最好在批处理代码最前面加上chcp 437  切换到英文,这样会输出英文信息,就像最下面的输出信息那样
________________________________________________________________________________
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\Administrator>chcp 437

Active code page: 437

X:\Users\Administrator>diskpart

Microsoft DiskPart version 10.0.19041.1

Copyright (C) Microsoft Corporation.
On computer: Winpe

DISKPART> sel disk 1

Disk 1 is now the selected disk.

DISKPART> detail disk

TOSHIBA MK1655GSX USB Device
Disk ID: {AA01743D-F6E3-11EB-8FB7-08107649E626}
Type   : USB
Status : Online
Path   : 0
Target : 0
LUN ID : 0
Location Path : UNAVAILABLE
Current Read-only State : No
Read-only  : No
Boot Disk  : No
Pagefile Disk  : No
Hibernation File Disk  : No
Crashdump Disk  : No
Clustered Disk  : No

  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
  ----------  ---  -----------  -----  ----------  -------  ---------  --------
  Volume 3     F   no          NTFS   Partition     39 GB  Healthy   
  Volume 4     G   soft         NTFS   Partition     20 GB  Healthy
  Volume 5     H   data         NTFS   Partition     60 GB  Healthy
  Volume 6     I                RAW    Partition     10 GB  Healthy
  Volume 7                      NTFS   Partition     19 GB  Healthy    Hidden
  Volume 8                      FAT32  Partition    300 MB  Healthy    Hidden

DISKPART> list part

  Partition ###  Type              Size     Offset
  -------------  ----------------  -------  -------
  Partition 1    System             300 MB  1024 KB
  Partition 2    Reserved            16 MB   301 MB
  Partition 3    Primary             39 GB   317 MB
  Partition 4    Primary             20 GB    39 GB
  Partition 5    Primary             60 GB    59 GB
  Partition 6    Recovery            10 GB   119 GB
  Partition 7    Primary             19 GB   129 GB

DISKPART> sel part 1

Partition 1 is now the selected partition.

DISKPART> del part override

DiskPart successfully deleted the selected partition.

DISKPART> sel part 2

Partition 2 is now the selected partition.

DISKPART> del part override

DiskPart successfully deleted the selected partition.

DISKPART> sel part 3

Partition 3 is now the selected partition.

DISKPART> del part override

DiskPart successfully deleted the selected partition.

DISKPART> sel part 6

Partition 6 is now the selected partition.

DISKPART> del part override

DiskPart successfully deleted the selected partition.



回复 48# idwma


    感谢快速回复, 我有时间再测试一下, 有问题会来反馈

TOP

  1. for /f "tokens=2 delims= " %%c in ('^(echo sel disk %disk% ^&echo list part^)^|diskpart^|findstr /i "Partition.*B"') do (
  2. ((echo sel disk %disk%
  3. echo sel partition %%c
  4. echo detail partition)|diskpart|findstr /i "C12A7328-F81F-11D2-BA4B-00A0C93EC93B DE94BBA4-06D1-4D40-A16A-BFD50179D6AC E3C9E316-0B5C-4DB8-817D-F92DF00215AE 其它系统下分区类型的ID"
  5. )&&(
  6. (echo sel disk %disk%
  7. echo sel part %%c
  8. echo del part override)>>dsk.txt
  9. )
  10. )
复制代码
回复 47# 5i365

TOP

本帖最后由 5i365 于 2021-8-9 19:44 编辑

回复 46# idwma

第14-20行
for /f "tokens=2 delims= " %%c in ('^(echo select disk %disk% ^&echo list part^)^|diskpart^|findstr /i "System Reserved Recovery"') do (
        if not "%%c"=="" (
                (echo sel disk %disk%
                echo sel part %%c
                echo del part override)>>dsk.txt
        )
)

你好,大侠,能增强一下上面几行代码的功能吗? 改成类似下面的,用分区类型的ID来表示的形式,这样我如果想删除其它系统下的某分区类型的分区,就直接在后加分区类型的ID就可以了,这样功能就没强大多了
for /f "tokens=2 delims= " %%c in ('^(echo select disk %disk% ^&echo list part^)^|diskpart^|findstr /i "C12A7328-F81F-11D2-BA4B-00A0C93EC93B DE94BBA4-06D1-4D40-A16A-BFD50179D6AC E3C9E316-0B5C-4DB8-817D-F92DF00215AE 其它系统下分区类型的ID"')

★★★需要增强的原因是:

所有windows相关的分区类型,因为本身就是微软的东西, 他们都有英文名字, 像System、 Reserved、 Recovery
但是更多的其它系统,像苹果系统,linux等系统下的分区类型,却没有名字,统一显示为Unknown
但好在,每种分区类型,在分区的详情中都有一串字符ID来表示这种类型,例如:查看一个 system类型分区的详情,里面有下面的内容
Type: C12A7328-F81F-11D2-BA4B-00A0C93EC93B

Windows下的一些分区,英文类型名字和其ID的对应关系如下
system
C12A7328-F81F-11D2-BA4B-00A0C93EC93B

recovery
DE94BBA4-06D1-4D40-A16A-BFD50179D6AC

reserved
E3C9E316-0B5C-4DB8-817D-F92DF00215AE
_______________________________________________________
附获取分区类型详情的步骤:

Active code page: 437

C:\Users\Administrator>diskpart

Microsoft DiskPart version 6.1.7601
Copyright (C) 1999-2008 Microsoft Corporation.
On computer: WIN

DISKPART> sel disk 0

Disk 0 is now the selected disk.

DISKPART> list part

  Partition ###  Type              Size     Offset
  -------------  ----------------  -------  -------
  Partition 1    System            1027 MB  1024 KB
  Partition 2    Primary             80 GB  1028 MB
  Partition 3    Primary            112 GB    81 GB
  Partition 4    Primary             29 GB   193 GB

DISKPART> sel part 1

Partition 1 is now the selected partition.

DISKPART> detail part

Partition 1
Type    : c12a7328-f81f-11d2-ba4b-00a0c93ec93b
Hidden  : Yes
Required: No
Attrib  : 0X8000000000000000
Offset in Bytes: 1048576

  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
  ----------  ---  -----------  -----  ----------  -------  ---------  --------
* Volume 3         EFI          FAT32  Partition   1027 MB  Healthy    System

DISKPART>

TOP

回复 45# 5i365


    提示的中文显示多加个判断
变量的后面习惯性的多打了个空格
  1. @echo off
  2. chcp 437
  3. echo list vol|diskpart|findstr /i "volume.*no" &&set f=1||chcp 936
  4. if not defined f start mshta vbscript:msgbox("没找到卷标为no的分区",0,"%提醒%")(window.close)&&exit
  5. if exist dsk.txt del dsk.txt
  6. for /f "tokens=2,3 delims= " %%a in ('echo list vol^|diskpart^|findstr /i "volume.*no"') do (
  7. if exist %%b:\windows\system32 (
  8. for /f "tokens=2 delims=* " %%c in ('^(echo sel vol %%a ^&echo list disk^)^|diskpart^|findstr "*"') do set disk=%%c&BOOTICE /DEVICE=%%c /mbr /backup /sectors=1 /quiet /file=MBR_Bak
  9. (echo select volume %%a
  10. echo delete volume)|diskpart
  11. )
  12. )
  13. for /f "tokens=2 delims= " %%c in ('^(echo select disk %disk% ^&echo list part^)^|diskpart^|findstr /i "System Reserved Recovery"') do (
  14. if not "%%c"=="" (
  15. (echo sel disk %disk%
  16. echo sel part %%c
  17. echo del part override)>>dsk.txt
  18. )
  19. )
  20. for /f "tokens=2 delims= " %%a in ('^(echo select disk %disk% ^&echo detail disk^)^|diskpart^|findstr /i "volume.*no"') do (
  21. if not "%%a"=="" (
  22. (echo select volume %%a
  23. echo delete volume)>>dsk.txt
  24. )
  25. )
  26. echo;exit>>dsk.txt
  27. if exist dsk.txt diskpart /s dsk.txt
  28. del dsk.txt
  29. for /f "tokens=3 delims= " %%c in ('echo list vol^|diskpart^|findstr /i "volume.*data"') do set data_pf=%%c
  30. set no_yph=%disk%
  31. pause
复制代码
1

评分人数

TOP

本帖最后由 5i365 于 2021-8-9 10:22 编辑

回复 38# idwma

第五行代码的中文部分,在使用chcp 437后,会显示乱码, 有办法显示中文吗:?
if not defined f start mshta vbscript:msgbox("没找到卷标为no的分区",0,"%提醒%")(window.close)&&exit

找到一文章,但不知道修改
https://www.cnblogs.com/tsoukw/archive/2010/10/20/1856497.html
______________________________________________________________________
另外还有一个问题,
第32行, 回显硬盘号,后面会有一个空格,怎样在开始获取硬盘号的地方,删除空格?
例如:
echo %no_yph%abc
输出的结果是0 abc

TOP

回复 43# newswan


    感谢指点, 感觉在PE下分配盘符,有时不太可靠,目前还是感觉分区号稳点

TOP

总之就是 卷号倒序, 盘符,两个方法
或者没有盘符先分配盘符

TOP

本帖最后由 newswan 于 2021-8-8 18:41 编辑

定位硬盘不行,分区号也会自动变
卷号,按大到小排序
  1. cmd /c "echo list vol" ^| diskpart ^| findstr /i /r /C:"Volume [0-9]" ^| sort /r
复制代码
剩下的你自己改

测试
  1. DISKPART>
  2.   Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
  3.   ----------  ---  -----------  -----  ----------  -------  ---------  --------
  4.   Volume 0     C                NTFS   Partition    100 GB  Healthy    Boot
  5.   Volume 1     D                NTFS   Partition    138 GB  Healthy
  6.   Volume 2                      FAT32  Partition    260 MB  Healthy    System
  7.   Volume 3                      RAW    Partition    260 MB  Healthy    Hidden
  8.   Volume 4                      RAW    Partition   1023 MB  Healthy
  9.   Volume 5                      RAW    Partition   4096 MB  Healthy
  10. DISKPART> 5
  11. 4
  12. 3
  13. 2
  14. 1
  15. 0
复制代码

TOP

回复 40# 5i365


    改了,应该可正常备份了
方法一不稳

TOP

回复 39# idwma


    测试过了, 没有遇到问题, 速度也快了, 感觉代码还可以精简  


备份硬盘分区表, 那个硬盘参数, 要改, 能否使用方法1的代码改一下呢?

TOP

回复 39# idwma


    第三行,的备份分区表代码, 要操作的硬盘号,还不知道, 因为在PE下也有可能是硬盘1或2,
如果用方法一的代码, 我认为应该将备份分区表代码放下面的位置

方法一代码:
@echo off&setlocal enabledelayedexpansion
chcp 437
for /f "delims=" %%i in ('^(echo list disk ^)^|diskpart^|find "Online"') do set/a n+=1
        set/a n=!n!-1
        for /l %%i in (0,1,!n!) do ((echo select disk %%i &echo detail disk)|diskpart|findstr /i "volume.*no" &&set f=%%i)
                if not defined f start mshta vbscript:msgbox("not find no",0,"tip")(window.close)&&exit
                for /l %%i in (0,1,!n!) do (
                        for /f "tokens=2,3 delims= " %%a in ('^(echo select disk %%i ^&echo detail disk^)^|diskpart^|findstr /i "volume.*no"') do (
                                if exist %%b:\windows\system32 (
                                              BOOTICE /DEVICE=硬盘号 /mbr /backup /sectors=1 /quiet /file=MBR_Bak
                                        (echo select disk %%i
                                        echo select volume %%a
                                        echo delete volume)|diskpart
                                        for /f "tokens=2 delims= " %%c in ('^(echo select disk %%i ^&echo list part^)^|diskpart^|findstr /i "system Reserved Recovery"') do (
                                                if not "%%c"=="" (
                                                (echo sel disk %%i
                                                echo sel part %%c
                                                echo del part override)|diskpart)
                                        )
                                )
                        )
                )
pause

TOP

本帖最后由 idwma 于 2021-8-8 17:54 编辑

回复 36# 5i365

你看11行就是定位硬盘一样的
    不太清楚这样是不是顺序不会变可以试试
  1. @echo off
  2. if exist dsk.txt del dsk.txt
  3. chcp 437
  4. echo list vol|diskpart|findstr /i "volume.*no" &&set f=1
  5. if not defined f start mshta vbscript:msgbox("没找到卷标为no的分区",0,"%提醒%")(window.close)&&exit
  6. for /f "tokens=2,3 delims= " %%a in ('echo list vol^|diskpart^|findstr /i "volume.*no"') do (
  7. if exist %%b:\windows\system32 (
  8. for /f "tokens=2 delims=* " %%c in ('^(echo sel vol %%a ^&echo list disk^)^|diskpart^|findstr "*"') do set disk=%%c &BOOTICE /DEVICE=%%c /mbr /backup /sectors=1 /quiet /file=MBR_Bak
  9. (echo select volume %%a
  10. echo delete volume)|diskpart
  11. )
  12. )
  13. for /f "tokens=2 delims= " %%c in ('^(echo select disk %disk% ^&echo list part^)^|diskpart^|findstr /i "System Reserved Recovery"') do (
  14. if not "%%c"=="" (
  15. (echo sel disk %disk%
  16. echo sel part %%c
  17. echo del part override)>>dsk.txt
  18. )
  19. )
  20. for /f "tokens=2 delims= " %%a in ('^(echo select disk %disk% ^&echo detail disk^)^|diskpart^|findstr /i "volume.*no"') do (
  21. if not "%%a"=="" (
  22. (echo select volume %%a
  23. echo delete volume)>>dsk.txt
  24. )
  25. )
  26. echo;exit>>dsk.txt
  27. if exist dsk.txt diskpart /s dsk.txt
  28. del dsk.txt
  29. for /f "tokens=3 delims= " %%c in ('echo list vol^|diskpart^|findstr /i "volume.*data"') do set data_pf=%%c
  30. set no_yph=%disk%
  31. pause
复制代码

TOP

回复 35# idwma

备份分区表的代码, 应该是备份要操作的硬盘, 有可能是 硬盘0 或1 或2 , 所以放在最开始, 无法知道硬盘号, 行不通

另外, 因为只处理包含卷标no的分区, 且包含windows系统的硬盘, 所以感觉还是方法一代码那个合适

TOP

回复 35# idwma


    对 是硬盘0的意思, 就是备份硬盘0的分区表

TOP

返回列表