发布于 2020-02-18  252 次阅读


虽然感觉这个 bat 脚本用处不大,但是在 windows 渗透中有些东西还是需要用到这个小工具,最起码看懂是需要的吧,于是我总结了一些常见的语法,并按照难度将其分为初级、中级和高级,并有一些简单的示例代码,算是备忘吧,也分享出来供大家参考

系统参数

%SystemRoot% === %Windir% === C:\WINDOWS
%ProgramFiles% === C:\Program
%USERPROFILE% === C:\Users\xxxx
%APPDATA% === C:\Users\XXXX\AppData\Roaming
%TEMP% === C:\Users\xxxx\AppData\Local\Temp
%OS% === Windows_NT
%PATH% === 系统的环境变量
%HOMEDRIVE% === 系统盘
%HOMEPATH% === 当前的用户根路径的目录位置

常用的语法:

初阶

1.echo 输出后面的字符

2.echo off 其后面的命令都不回显

3.@ 其后面的命令都不回显(只针对一行)

4.%[0-9] 参数格式化占位符 %0 表示命令本身 %1 表示第一个参数

5.call 调用另一个 bat 程序

6.pause 暂停

7.rem 其后面的字符为注释(有些如管道或者重定向还是会执行)

8.del 删除其后跟着的文件(/q 表示安静删除,不请求确认)

9.:: 其后面的字符为注释 (在任何情况下都不会执行,等同于冒号 + 空格)

10.设置变量的时候 = 两边都不能有空格

11.变量的引用表达形式:% 变量名 %

12.cls 清屏命令

13.?代表单个字符,* 代表所有字符

14.^ 代表转义字符
echo 通配符 ^& 批处理
连字符 & 在此命令中只当作一个字符显示到屏幕中,如果不加 ^ 那么” 批处理” 将被当作命令执行

15.| 管道符,将前面的输出作为后面的输入

echo 0123456 | find "123" 

16.|| 连接符
前面的命令执行不成功才会执行后面的命令

echo 0123456 | find "789" || echo 字符中没有789

17.&& 连接符

前面的命令执行成功才会执行后面的命令

echo 0123456 | find "123" && echo 字符中含有123

18.& 连接符

不论前面的命令是否执行成功后面的命令都能执行

echo 0123456 | find "789" & echo 字符中含有123

19.< 输入定向符

echo 456>1.txt
set /p wind=<1.txt
  1. 求模
set /p a=10%%2
echo %a%

21.有一个特别注意的地方就是在 for 循环的时候我们 do () 中 do 和后面的括号中间要有一个空格,没有空格就是语法错误

22.errorlevel 显示程序的返回码

程序执行完成后都会有一个返回码,成功为 1 不成功为 0

23.mode 配置系统设备

mode con cols=113 lines=15 & color 9f

此命令设置 DOS 窗口大小:15 行,113 列

24.start 命令(两者同时运行)

批处理中调用外部程序的命令(该外部程序在新窗口中运行,批处理程序继续往下执行,不理会外部程序的运行状况),如果直接运行外部程序则必须等外部程序完成后才继续执行剩下的指令

例:start explorer d:\

调用图形界面打开 D 盘

25.color

设置默认的控制台前景和背景颜色。
COLOR [attr]
attr 指定控制台输出的颜色属性
颜色属性由两个十六进制数字指定 – 第一个为背景,第二个则为
前景。每个数字可以为以下任何值之一:

0 = 黑色       8 = 灰色
1 = 蓝色       9 = 淡蓝色
2 = 绿色       A = 淡绿色
3 = 湖蓝色     B = 淡浅绿色
4 = 红色       C = 淡红色
5 = 紫色       D = 淡紫色
6 = 黄色       E = 淡黄色
7 = 白色       F = 亮白色

如果没有给定任何参数,该命令会将颜色还原到 CMD.EXE 启动时
的颜色。这个值来自当前控制台窗口、/T 开关或
DefaultColor 注册表值。
如果用相同的前景和背景颜色来执行 COLOR 命令,COLOR 命令
会将 ERRORLEVEL 设置为 1。
例如: “COLOR fc” 在亮白色上产生亮红色

26.assoc 和 ftype

文件关联
assoc 设置'文件扩展名'关联,关联到'文件类型'
ftype 设置'文件类型'关联,关联到'执行程序和参数'
当你双击一个.txt文件时,windows并不是根据.txt直接判断用 notepad.exe 打开
而是先判断.txt属于 txtfile '文件类型'
再调用 txtfile 关联的命令行 txtfile=%SystemRoot%\system32\NOTEPAD.EXE %1
可以在"文件夹选项"→"文件类型"里修改这2种关联
assoc           #显示所有'文件扩展名'关联
assoc .txt      #显示.txt代表的'文件类型',结果显示 .txt=txtfile
assoc .doc      #显示.doc代表的'文件类型',结果显示 .doc=Word.Document.8
assoc .exe      #显示.exe代表的'文件类型',结果显示 .exe=exefile
ftype           #显示所有'文件类型'关联
ftype exefile   #显示exefile类型关联的命令行,结果显示 exefile="%1" %* 
assoc .txt=Word.Document.8
设置.txt为word类型的文档,可以看到.txt文件的图标都变了
assoc .txt=txtfile
恢复.txt的正确关联

ftype exefile="%1" %*
恢复 exefile 的正确关联
如果该关联已经被破坏,可以运行 command.com ,再输入这条命令

27.pushd 和 popd
切换当前目录

@echo off
c: & cd\ & md mp3       #在 C:\ 建立 mp3 文件夹
md d:\mp4               #在 D:\ 建立 mp4 文件夹
cd /d d:\mp4            #更改当前目录为 d:\mp4
pushd c:\mp3            #保存当前目录,并切换当前目录为 c:\mp3
popd                    #恢复当前目录为刚才保存的 d:\mp4

一般用处不大,在当前目录名不确定时,会有点帮助。(dos 编程中很有用)

28.ATTRIB 显示或更改文件属性

ATTRIB [+R|-R] [+A|-A] [+S|-S] [+H|-H] [[drive:] [path] filename] [/S [/D]]
  +   设置属性。
  -    清除属性。
  R   只读文件属性。
  A   存档文件属性。
  S   系统文件属性。
  H   隐藏文件属性。
  [drive:][path][filename]
      指定要处理的文件属性。
  /S  处理当前文件夹及其子文件夹中的匹配文件。
  /D  也处理文件夹。

例:

md autorun
attrib +a +s +h autorun

上面的命令将建立文件夹 autorun,然后将其设为存档、系统、隐藏属性

29.eof (end of file)

1、在无 call 的情况下,会直接退出批处理,此时等同于 exit
2、在 call 的情况下,会中止 call,继续执行其他命令

示例:

@echo off
call :str1
pause
goto :eof
echo 此行代码不会被运行

:str1
echo 此行代码运行
goto :eof

30.copy 和 xcopy

话不多说,先丢使用帮助

COPY
将一份或多份文件复制到另一个位置。

COPY [/D] [/V] [/N] [/Y | /-Y] [/Z] [/L] [/A | /B ] source [/A | /B]
     [+ source [/A | /B] [+ ...]] [destination [/A | /B]]

  source       指定要复制的文件。
  /A           表示一个 ASCII 文本文件。
  /B           表示一个二进位文件。
  /D           允许解密要创建的目标文件
  destination  为新文件指定目录和/或文件名。
  /V           验证新文件写入是否正确。
  /N           复制带有非 8dot3 名称的文件时,
               尽可能使用短文件名。
  /Y           不使用确认是否要覆盖现有目标文件
               的提示。
  /-Y          使用确认是否要覆盖现有目标文件
               的提示。
  /Z           用可重新启动模式复制已联网的文件。
/L           如果源是符号链接,请将链接复制
               到目标而不是源链接指向的实际文件。

命令行开关 /Y 可以在 COPYCMD 环境变量中预先设定。
这可能会被命令行上的 /-Y 替代。除非 COPY
命令是在一个批处理脚本中执行的,默认值应为
在覆盖时进行提示。

要附加文件,请为目标指定一个文件,为源指定
数个文件(用通配符或 file1+file2+file3 格式)。

XCOPY

复制文件和目录树。

XCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [/W]
                           [/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T] [/
                           [/K] [/N] [/O] [/X] [/Y] [/-Y] [/Z] [/B]
                           [/EXCLUDE:file1[+file2][+file3]...]

  source       指定要复制的文件。
  destination  指定新文件的位置和/或名称。
  /A           仅复制有存档属性集的文件,但不更改属性。
  /M           仅复制有存档属性集的文件,并关闭存档属性。
  /D:m-d-y     复制在指定日期或指定日期以后更改的文件。
               如果没有提供日期,只复制那些源时间比目标时间新的文件。
  /EXCLUDE:file1[+file2][+file3]...
               指定含有字符串的文件列表。每个字符串在文件中应位于单独的一行
               如果任何字符串与复制文件的绝对路径的任何部分相符,则排除复制
               该文件。例如,指定如 \obj\ 或 .obj 的字符串会分别排除目录
               obj 下面的所有文件或带有 .obj 扩展名的所有文件。
  /P           创建每个目标文件之前提示您。
  /S           复制目录和子目录,不包括空目录。
  /E           复制目录和子目录,包括空目录。与 /S /E 相同。可以用来修改 /
  /V           验证每个新文件的大小。
  /W           提示您在复制前按键。
  /C           即使有错误,也继续复制。
  /I           如果目标不存在,且要复制多个文件,则假定目标必须是目录。
  /Q           复制时不显示文件名。
  /F           复制时显示完整的源文件名和目标文件名。
  /L           显示要复制的文件。
  /G           允许将加密文件复制到不支持加密的目标。
  /H           也复制隐藏文件和系统文件。
  /R           覆盖只读文件。
  /T           创建目录结构,但不复制文件。不包括空目录或子目录。/T /E 包括
               空目录和子目录。
  /U           只复制已经存在于目标中的文件。
  /K           复制属性。一般的 Xcopy 会重设只读属性。
  /N           用生成的短名称复制。
  /O           复制文件所有权和 ACL 信息。
  /X           复制文件审核设置(隐含 /O)。
  /Y           取消提示以确认要覆盖现有目标文件。
  /-Y          要提示以确认要覆盖现有目标文件。
  /Z           在可重新启动模式下复制网络文件。
  /B           复制符号链接本身与链接目标相对。
  /J           复制时不使用缓冲的 I/O。推荐复制大文件时使用。

开关 /Y 可以预先在 COPYCMD 环境变量中设置。
这可能被命令行上的 /-Y 覆盖。

乍一看两者都是复制文件,但是使用上有着很大的区别

(1)区别一:COPY 不能复制文件夹下的文件,而 XCOPY 可以
假设:有这样的文件结构:C 盘下有 2 个文件夹,为 A 和 B,在 A 下有 1 个文件和 1 个文件夹,现在要将 A 文件夹下的所有内容拷贝到 B 文件夹下,我们可以使用 XCOPY 实现

C:\>XCOPY A:\A\*.* C:\B /S /E

(1)区别二:XCOPY 不能实现文件的拼接,但是 COPY 可以

典型的将图片和文本结合(图片马的生成)

OPY 1.JPG/b + 1.php/a muma.jpg

31.重命名 ren

ren 原路径\文件名.扩展名 新文件名.扩展名

32.获取帮助 /?

命令 /? 获取帮助

中阶

10.if 条件语句:

(1) if [not] “参数” == “字符串” 待执行的命令
(2) if [not] exist [路径] 文件名 待执行的命令
(3) if errorlevel <数字> 待执行的命令

11.goto 跳转指令

执行到 goto 就跳转到 goto 后面指定的标号的位置(标号用:+ 字符串组成)标号所在的行不被执行(常和 if 语句配合使用)

goto end 

:end 
echo this is the end 

12.choice

用户输入预先设定好的字符之一,返回字符对应的 level 可以配合 errorlevel 实现选择功能

示例:
   CHOICE /?
   CHOICE /C YNC /M "确认请按 Y,否请按 N,或者取消请按 C。"
   CHOICE /T 10 /C ync /CS /D y
   CHOICE /C ab /M "选项 1 请选择 a,选项 2 请选择 b。"
   CHOICE /C ab /N /M "选项 1 请选择 a,选项 2 请选择 b。"

比如我输入:CHOICE /C YNC /M “确认请按 Y,否请按 N,或者取消请按 C”
就会返回:确认请按 Y,否请按 N,或者取消请按 C [Y,N,C]?

choice /C SME /M "start middle end"
if errorlevel 3 goto end
if errorlevel 2 goto middle
if errorlevel 1 goto start

:start 
echo start 
goto end

:middle
echo middle
goto end

:end 
echo good bye

13.for 循环命令

for / 参数 %% 变量 in (集合) do 命令

注意:

(1)%% 是在 bat 文件中的写法,如果是在命令行里面的话只需要有一个 %,并且变量名区分大小写

(2)in 和 () 之间是有空格的

(3)括号中的内容可以是文件、字符串甚至是命令产生的集合(可以使用通配符 *?, 还能引用环境变量)

(4)命令可以是任何合法的 DOS 命令,或者是外部可以调用的程序,可以使用括号把多条命令括起来打包执行

参数:
1./d 表示只对目录而不是文件执行 for 命令 (只对目录)

for /d %%a in (c:\*) do @echo %%a 

2./r 递归

后面可以跟路径信息(指的是包含它之下的整个目录树,如果是一个. 或者省略指的就是当前目录),表示后面的循环指令对每个目录都生效(大概意思就是我这个操作是和这个盘关联的,先指定一个范围)

实例一:

for /r . %%a in (abc.txt) do @echo . > %%a //在当前目录下的每一个目录中创建一个abc.txt 空文件

实例二:

@echo off
rem 显示d:盘中所有文件名为file1和file2的列表
for /r d:\ %%h in (file1,file2) do if exist %%h echo %%h
pause

实例三:

@echo off
rem 删除C盘中所有*.chk的文件
for /r c:\ %%h in (*.chk) do del /q %%h
pause

3./L (该集表示以增量形式从开始到结束的一个数字序列。可以使用负的 Step)–》迭代数值范围

for /L %%变量 in (起始值,每次增值,结束时的比较值) do 命令

其实就是产生一个等差数列,方便执行命令的时候使用这些数字

实例:

for /l %%i in (1,1,5) do @echo %%i --输出1 2 3 4 5
  for /l %%i in (1,2,10) do @echo %%i --输出1,3,5,7,9
  for /l %%i in (100,-20,1) do @echo %%i --输出100,80,60,40,20
  for /l %%i in (1,1,5) do start cmd --打开5个CMD窗口
  for /l %%i in (1,1,5) do md %%i --建立从1~5共5个文件夹
  for /l %%i in (1,1,5) do rd /q %%i --删除从1~5共5个文件夹

4./f
这个可能是最常用的,也是最强的命令,主要用来处理文件和一些命令的输出结果

FOR /F ["options"] %%i IN (file) DO command
FOR /F ["options"] %%i IN ("string") DO command
FOR /F ["options"] %%i IN (command) DO command

对于

FOR /F %%i IN (file) DO command

file 为文件名,按照官方的说法是,for 会依次将 file 中的文件打开,并且在进行到下一个文件之前将每个文件读取到内存,按照每一行分成一个一个的元素,忽略空白的行,看个例子。

假如文件 a.txt 中有如下内容:

第1行第1列第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列

你想显示 a.txt 中的内容,会用什么命令呢?当然是 type,type a.txt

for 也可以完成同样的命令:

for /f %%i in (a.txt) do echo %%i

还是先从括号执行,因为含有参数 / f, 所以 for 会先打开 a.txt,然后读出 a.txt 里面的所有内容,把它作为一个集合,并且以每一行作为一个元素,所以会产生这样的集合,

{"第1行第1列 第1行第2列 第1行第3列", //第一个元素
"第2行第1列 第2行第2列 第2行第3列", //第二个元素
"第3行第1列 第3行第2列 第3行第3列"}   //第三个元素

集合中只有 3 个元素,同样用 %%i 依次代替每个元素,然后执行 do 后面的命令。

们发现 for /f 会默认以每一行来作为一个元素,但是如果我们还想把每一行再分解更小的内容,该怎么办呢?不用担心,for 命令还为我们提供了更详细的参数,使我们将每一行分为更小的元素成为可能。
它们就是:delims 和 tokens

delims 用来告诉 for 每一行应该拿什么作为分隔符,默认的分隔符是空格和 tab 键
比如,还是上面的文件,我们执行下面的命令:

for /f "delims= " %%i in (a.txt) do echo %%i

显示的结果是:

第1行第1列
第2行第1列
第3行第1列

为什么是这样的呢。因为这里有了 delims 这个参数,= 后面有一个空格,意思是再将每个元素以空格分割,默认是只取分割之后的第一个元素。

执行过程是:

将第一个元素” 第 1 行第 1 列 第 1 行第 2 列 第 1 行第 3 列” 分成三个元素:” 第 1 行第 1 列” “第 1 行第 2 列” “第 1 行第 3 列”,它默认只取第一个,即” 第 1 行第 1 列”,然后执行 do 后面的命令,依次类推。

但是这样还是有局限的,如果我们想要每一行的第二列元素,那又如何呢?

这时候,tokens 跳出来说,我能做到。

它的作用就是当你通过 delims 将每一行分为更小的元素时,由它来控制要取哪一个或哪几个。

还是上面的例子,执行如下命令:

for /f "tokens=2 delims= " %%i in (a.txt) do echo %%i

执行结果:
第1行第2列
第2行第2列
第3行第2列

如果要显示第三列,那就换成 tokens=3。
同时 tokens 支持通配符 *,以及限定范围。
如果要显示第二列和第三列,则换成 tokens=2,3 或 tokens=2-3, 如果还有更多的则为:tokens=2-10 之类的。

此时的命令为:

for /f "tokens=2,3 delims= " %%i in (a.txt) do echo %%i %%j

怎么多出一个 %%j?

这是因为你的 tokens 后面要取每一行的两列,用 %%i 来替换第二列,用 %%j 来替换第三列。
并且必须是按照英文字母顺序排列的,%%j 不能换成 %%k,因为 i 后面是 j

执行结果为:
第1行第2列第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列

对以通配符 *,就是把这一行全部或者这一行的剩余部分当作一个元素了。

比如:

for /f "tokens=* delims= " %%i in (a.txt) do echo %%i

执行结果为:
第1行第1列第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列

其实就跟 for /f %%i in (a.txt) do echo %%i 的执行结果是一样的。

再如:

for /f "tokens=2,* delims= " %%i in (a.txt) do echo %%i %%j

执行结果为:
第1行第2列第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列

用 %%i 代替第二列,用 %%j 代替剩余的所有

最后还有 skip 合 eol,这俩个简单,skip 就是要忽略文件的前多少行,而 eol 用来指定当一行以什么符号开始时,就忽略它。
比如:

for /f “skip=2 tokens=*” %%i in (a.txt)

14.set

(1) 显示系统环境变量

@echo off
set 
@pause

(2) 直接在 bat 脚本中设置变量(后面引用的时候要用 % 变量名 % 的形式)
注意:= 两边不能有空格

@set var=123
@echo %var% 
@pause

(3) 接受界面参数然后传递给变量 SET /P variable=[promptString] 接受界面参数

@set /p name=请输入姓名:
@echo 你的名字为:%name%
@pause

(4) 接受表达式传参 SET /A expression

@set /a b=1+1
@echo %b%
@pause

(5) 截取字符串 %Var:~start,len%

1.第一种情况:
%var:~ 正数 %
这种情况是截取从这个长度开始一直到最后的所有字符

@set f=www.baidu.com
@set j=%f:~4%
@echo %j%
@pause 

结果:baidu.com

2.第二种情况:
%var:~ 负数 %
这种情况截取从后面数的这个数字绝对值长度的字符串

@set f=www.baidu.com
@set j=%f:~-4%
@echo %j%
@pause 

结果:.com

3.第三种情况
%var:~ 正数(开始位置,从 0 开始), 正数(长度或者是该下标的前一个)%
这种情况是从某一个位置开始到另一个位置结束

@set f=www.baidu.com
@set j=%f:~0,4%
@echo %j%
@pause 

结果: www.

4.第四种情况
%var:~ 正数, 负数 %
这种情况是从这个正数的位置开始(最开始是 0),到从后面数这个负数的绝对值个数的前一个

@set f=www.baidu.com
@set j=%f:~4,-4%
@echo %j%
@pause 

结果: baidu

(6) 替换字符串

@set f=www.baidu.com
@set j=%f:www=bbs%
@echo %j%
@pause 

结果: bbs.baidu.com

14. 字符串操作

除了上面讲的使用 set 以外我们还有其他的字符串操作

1. 扩充显示
~I - 删除任何引号("),扩充 %I
%~fI - 将 %I 扩充到一个完全合格的路径名
%~dI - 仅将 %I 扩充到一个驱动器号
%~pI - 仅将 %I 扩充到一个路径
%~nI - 仅将 %I 扩充到一个文件名
%~xI - 仅将 %I 扩充到一个文件扩展名
%~sI - 扩充的路径只含有短名
%~aI - 将 %I 扩充到文件的文件属性
%~tI - 将 %I 扩充到文件的日期/时间
%~zI - 将 %I 扩充到文件的大小
`%~$PATH`:I - 查找列在路径环境变量的目录,并将 %I 扩充
到找到的第一个完全合格的名称。如果环境变量名
未被定义,或者没有找到文件,此组合键会扩充到
空字符串
可以组合修饰符来得到多重结果:
**%~dpI - 仅将 %I 扩充到一个驱动器号和路径
%~nxI - 仅将 %I 扩充到一个文件名和扩展名
%~fsI - 仅将 %I 扩充到一个带有短名的完整路径名
%~dp$PATH:i - 查找列在路径环境变量的目录,并将 %I 扩充
到找到的第一个驱动器号和路径。
%~ftzaI - 将 %I 扩充到类似输出线路的 DIR**

说明:这里的 %I 指的是一个变量,但是不是所有的变量都能够进行扩充的,有两个条件:

1、该字符串代表一个文件路径;

2、变量要用 %x 来表示,x 可取 a-z A-Z 0-9 共 62 个字符中的任意一个。
以 %0 举例说明:

@echo off
echo 正在运行的这个批处理:
echo 完全路径:%0
echo 去掉引号:%~0
echo 所在分区:%~d0
echo 所处路径:%~p0
echo 文件名:%~n0
echo 扩展名:%~x0
echo 文件属性:%~a0
echo 修改时间:%~t0
echo 文件大小:%~z0
pause
2. 字符串拷贝
@echo off
set str1=This is old string
set str2=This is new string
echo str1=%str1%
echo str2=%str2%
set str1=%str2%
echo %str1%------------%str2%
@pause

结果:

str1=This is old string
str2=This is new string
This is new string————This is new string

4. 变量延迟扩展

先来看一段代码:

set str=test

if %str%==test (
    set str=another test
    echo %str%
)

输出结果是 test 而不是 another test 这是为什么呢?,以为程序会把这个复合语句看成是一条语句同时操作,变量一开始就被赋值成了 test ,等价于下面这样。

set str=test

if %str%==test (
    set str=another test
    echo test    ::注意这里
)

这个时候为了解决这个问题出现了变量延迟扩展(符合语句不一下赋值而是一句一句执行),形式就是声明一个变量延迟扩展开启,然后将需要延迟的变量变成两个感叹号包围

@echo off
setlocal enabledelayedexpansion    ::注意这里

set str=test

if %str%==test (
    set str=another test
    echo !str!      ::注意这里
    echo %str%  ::区别
5. 计算字符串长度
@echo off
set str1=This is a test string
set str=%str1%
:next1
if not "%str%"=="" (
set /a num+=1
set "str=%str:~1%"
goto next1
)
echo str1=%str1%
echo str1的长度为:%num%
6. 寻找一个字符串中某个字符第一次出现的位置
@echo off
Setlocal ENABLEDELAYEDEXPANSION

set str1=This is a test string
set ch1=t
set str=%str1%
:next
if not "%str%"=="" (
set /a num+=1
if "!str:~0,1!"=="%ch1%" goto last
set "str=%str:~1%"
goto next
)
set /a num=0
:last
echo 字符'%ch1%'在字符串"%str1%"中的首次出现位置为%num%

14.call 指定调用

(1) 指定调用 bat 脚本

新建一个 call1.bat 内容如下

@echo running call1

新建一个 call2.bat 内容如下

@call call1.bat
@echo running call2.bat

结果:
running call1
running call2

(2) 指定调用标签 (和 goto 比较一下)

call3bat

@echo off
call :label
echo 1
echo 2

:label
echo 3
echo 4

call4.bat

@echo off
call call3.bat
pause

call5.bat

@echo off
goto label
echo 1
echo 2

:label
echo 3
echo 4

call6.bat

@echo off
call call5.bat
pause

(3) 传参数

a.bat 内容:

@echo off
echo %0 %1
goto :eof

b.bat 内容:

@echo off
call a.bat hello
dir c:\
pause

15. 产生随机数

(1) 生成 0-65535 随机数:

@echo %random%

(2) 生成指定范围的随机数 (利用模运算)

产生一个 255 以内的数

@echo off 
setlocal enabledelayedexpansion 
set /a h1=%random%%%(255+1) 
echo %h1% 
pause 

16. 延时

bat 脚本往往采用 ping 命令指定发包数实现延时

延时两秒:

@ping 127.0.0.1 -n 3 >nul 

17. 正则匹配

findstr 个人认为不够强大,还是推荐 shell 脚本

FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file]
[/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]
strings [[drive:][path]filename[ ...]]

/B 在一行的开始配对模式。
/E 在一行的结尾配对模式。
/L 按字使用搜索字符串。
/R 将搜索字符串作为正则表达式使用。
/S 在当前目录和所有子目录中搜索匹配文件。
/I 指定搜索不分大小写。
/X 打印完全匹配的行。
/V 只打印不包含匹配的行。
/N 在匹配的每行前打印行数。
/M 如果文件含有匹配项,只打印其文件名。
/O 在每个匹配行前打印字符偏移量。
/P 忽略有不可打印字符的文件。
/OFF[LINE] 不跳过带有脱机属性集的文件。
/A:attr 指定有十六进位数字的颜色属性。请见 "color /?"
/F:file 从指定文件读文件列表 (/ 代表控制台)。
/C:string 使用指定字符串作为文字搜索字符串。
/G:file 从指定的文件获得搜索字符串。 (/ 代表控制台)。
/D:dir 查找以分号为分隔符的目录列表
strings 要查找的文字。
[drive:][path]filename
指定要查找的文件。

除非参数有 /C 前缀,请使用空格隔开搜索字符串。
例如: 'FINDSTR "hello there" x.y' 在文件 x.y 中寻找 "hello" 或
"there"。'FINDSTR /C:"hello there" x.y' 文件 x.y 寻找
"hello there"。

正则表达式的快速参考:
. 通配符: 任何字符
* 重复: 以前字符或类出现零或零以上次数
^ 行位置: 行的开始
$ 行位置: 行的终点
[class] 字符类: 任何在字符集中的字符
[^class] 补字符类: 任何不在字符集中的字符
[x-y] 范围: 在指定范围内的任何字符
\x Escape: 元字符 x 的文字用法
\<xyz 字位置: 字的开始
xyz\> 字位置: 字的结束 

实际应用

1. 注册表操作

reg 是专门用来修改注册表的命令

1.reg add 将新的子项或者项添加到注册表中

reg add KeyName [/v EntryName|/ve][/tDataType][/s separator][/d value][/f]

参数解释:

1.KeyName 指定项的完全路径
对于远程计算机,请在 \ ComputerName\PathToSubkey 中的子项路径前包含计算机名称。忽略 ComputerName 会导致默认对本地计算机进行操作。以相应的子目录树开始路径。有效子目录树为 HKLM、HKCU、HKCR、HKU 以及 HKCC。远程机器上只有 HKLM 和 HKU

常见的缩写以及全称:

HKCR: HKEY_CLASSES_ROOT
HKCU: HKEY_CURRENT_USER
HKLM: HKEY_LOCAL_MACHINE
HKU: HKEY_USERS
HKCC: HKEY_CURRENT_CONFIG 

/v EntryName 你添加的项的名字
/ve 指定名称为空值
/t DataType 指定想的数据类型

常见的类型:

REG_SZ
REG_MULTI_SZ
REG_DWORD_BIG_ENDIAN
REG_DWORD
REG_BINARY
REG_DWORD_LITTLE_ENDIAN
REG_LINK
REG_FULL_RESOURCE_DESCRIPTOR
REG_EXPAND_SZ 

/s 指定分隔符,不自定默认为 \0
/d 指定值
/f 取消质询

实例:
1.显示隐藏的文件和文件夹

cmd /k reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden\SHOWALL" /v Checkedvalue /t reg_dword /d 1 /f

2.开机启动输入法程序 CTFMON

 cmd /k reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v ctfmon.exe /t REG_SZ /d "%SystemRoot%\system32\ctfmon.exe" /f

3.添加远程机器 ABC 上的一个注册表项 HKLM\Software\MyCo

REG ADD \ABC\HKLM\Software\MyCo

2.reg delete 从注册表删除项或子项

reg delete KeyName [{/v EntryName|/ve|/va}] [/f] 

参数解释:

/va
  删除指定子项下的所有项。使用本参数不能删除指定子项下的子项。

实例:

1.删除 CTFMON 的镜像劫持

cmd /k reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ctfmon.exe" /f

3.reg compare 比较指定的注册表子项或项

reg compare KeyName1 KeyName2 [/v EntryName | /ve] {[/oa]|[/od]|[/os]|[on]} [/s]

参数解释:

/ve 指定只可以比较没有值的项。
  {[/oa]|[/od]|[/os]|[on]}
  指定不同点和匹配点的显示方式。默认设置是/od。
  
值说明
  /oa指定显示所有不同点和匹配点。默认情况下,仅列出不同点。
  /od指定仅显示不同点。这是默认操作。
  /os指定仅显示匹配点。默认情况下,仅列出不同点。
  /on指定不显示任何内容。默认情况下,仅列出不同点。
  /s Separator
  比较所有子项和项。 

实例:

reg compare "hkcu\software\microsoft\winmine" "hkcu\software\microsoft\winmine" /od /s 

4.reg copy 将一个注册表项复制到本地或远程计算机的指定位置

reg copy KeyName1 KeyName2 [/s] [/f] 

参数解释:

/s 复制指定子项下的所有子项和项。

实例:

reg copy "hkcu\software\microsoft\winmine" "hkcu\software\microsoft\winminebk" /s /f

  reg copy "hkcu\software\microsoft\winminebk" "hkcu\software\microsoft\winmine" /s

 5.reg export 将指定子项、项和值的副本创建到文件中,以便将其传输到其它服务器

reg export KeyName FileName 

参数解释:

FileName 指定要导出文件的名称和路径。该文件必须具有.reg扩展名。 

实例:

reg export "hkcu\software\microsoft\winmine" c:\data\regbackups\wmbkup.reg 

6.reg import 将包含导出的注册表子项、项和值的文件复制到本地计算机的注册表中

reg import FileName 

参数解释:

 FileName 指定将复制到本地计算机注册表中的文件的名称和路径。必须预先使用reg export命令创建该文件。

实例:

reg import hkcu\software\microsoft\winmine" c:\data\regbackups\wmbkup.reg 

7.reg load 将保存的子项和项写回到注册表的不同子项中

其目的是保存到一个临时文件中,而该文件可用于注册表项的疑难解答或编辑注册表项。

reg load KeyName FileName 

参数解释:

 /s 将返回各个层中的所有子项和项。如果不使用该参数,将只返回下一层的子项和项。

8.reg query 返回注册表的子项下的项和下一层子项的列表

reg query KeyName [{/v EntryName|/ve}] [/s] 

参数解释:

/s将返回各个层中的所有子项和项。如果不使用该参数,将只返回下一层的子项和项。 

实例:

reg query "hklm\system\currentcontrolset\control\session manager" /v maxstacktracedepth

reg query "hkcu\software\microsoft\winmine" /s 

9.reg restore 将保存的子项和项写回到注册表

reg restore KeyName FileName

参数解释:

FileName 指定将写回到注册表中的文件的名称和路径。必须使用带 .hiv 扩展名的 reg save 操作预先创建该文件。

实例:

 reg restore "hkcu\software\microsoft\winmine" wmbkup.hiv 
 

10.reg save 将指定的子项、项和注册表值的副本保存到指定文件中。

reg save KeyName FileName 

参数解释:

FileName 指定所创建的文件的名称和路径。如果未指定路径,则使用当前路径。 

实例:

reg save "hkcu\software\microsoft\winmine" wmbkup.hiv 

11.reg unload 使用 reg load 操作删除已加载的部分注册表

reg unload KeyName 

实例:

reg unload "hkcu\software\microsoft\winminebk2"

补充:

1. 注册表的常用位置

a. 系统启动项:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run]         
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run]

example:

REG ADD HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run /v VNC_Server /t REG_SZ /d "%cd%\VNC_Server.bat" /f

b. 系统环境变量:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment]   

c. 当前用户的环境变量:

[HKEY_CURRENT_USER\Environment]   

2.修改注册表之后,结束并重新加载 explorer.exe 进程,可刷新注册表,令其生效

taskkill /f /im explorer.exe >nul start "" "explorer.exe"

2. 系统服务

1)停止 / 启动服务

停止:NET STOP 服务名
启动:NET START 服务名

2)设置启动类型:

自动: SC CONFIG 服务名 START= auto
手动: SC CONFIG 服务名 START= demand
已禁用:SC CONFIG 服务名 START= disabled

注:“START=” 等号后面必须要有一个空格。(start 还有 boot,system 两个值)

Sample:

SC CONFIG Spooler START= demand (打印机加载项,设置成手动,默认自动)

3)查看系统服务

start %SystemRoot%\system32\services.msc /s 

3. 文件 / 目录操作

这里要注意一点,在 windows 下,目录和文件并不是一个概念,注意和 linux 系统的区分

1.del 文件删除

DEL [/P] [/F] [/S] [/Q] [/A[[:]attributes]] names

参数解释:

/P 删除每一个文件之前提示确认。
/F 强制删除只读文件。
/S 删除所有子目录中的指定的文件 
/Q 安静模式。删除全局通配符时,不要求确认

实例:

1.将直接删除 d:\test\a.bat,没有任务提示

del /s /q /f d:\test\a.bat 

2.将直接删除 本目录的 temp 目录的所有文件,没有任务提示

del temp\* /q /f /s 

2.rmdir 目录删除

RMDIR [/S] [/Q] [drive:]path
RD [/S] [/Q] [drive:]path

参数解释:

/S 除目录本身外,还将删除指定目录下的所有子目录和文件。用于删除目录树。

/Q 安静模式,带 /S 删除目录树时不要求确认

注意:在不加任何参数时,rd 命令只能删除空的文件夹。

实例:

1.如果文件夹 123 不为空,则通过 / S 参数,可删除文件夹 123
rd /s d:\123

2.此时通过 / Q 参数可以使其不用询问而直接删除。

rd /s /q d:\123

3.fc 文件比较

比较两个文件或两个文件集并显示它们之间的不同

FC [/A] [/C] [/L] [/LBn] [/N] [/OFF[LINE]] [/T] [/U] [/W] [/nnnn][drive1:][path1]filename1 [drive2:][path2]filename2

FC /B [drive1:][path1]filename1 [drive2:][path2]filename2
​
  /A         只显示每个不同处的第一行和最后一行。
  /B         执行二进制比较。
  /C         不分大小写。
  /L         将文件作为 ASCII 文字比较。
  /LBn       将连续不匹配的最大值设置为指定
             的行数。
  /N         在 ASCII 比较上显示行数。
  /OFF[LINE] 不要跳过带有脱机属性集的文件。
  /T         不要将制表符扩充到空格。
  /U         将文件作为 UNICODE 文本文件比较。
  /W         为了比较而压缩空白(制表符和空格)。
  /nnnn      指定不匹配处后必须连续
             匹配的行数。
  [drive1:][path1]filename1
             指定要比较的第一个文件或第一个文件集。
  [drive2:][path2]filename2
             指定要比较的第二个文件或第二个文件集。

4.move 移动文件

移动文件并重命名文件和目录。

MOVE [/Y | /-Y] [drive:][path]dirname1 dirname2

参数解释:

/Y 取消重命名提示

1.重命名文件

move d:\abc d:\abcd

注意:
1.move 不能跨分区移动文件夹
2.不能够识别出带隐藏或系统属性的文件(可以使用 attrib 命令去掉这些文件的隐藏或系统属性,再来 move)

5.attrib 显示或更改文件属性

ATTRIB [+R | -R] [+A | -A] [+S | -S] [+H | -H] [+O | -O] [+I | -I] [+P | -P] [+U | -U][drive:][path][filename] [/S [/D]] [/L]

  +   设置属性。
  -   清除属性。
  R   只读文件属性。
  A   归档文件属性。
  S   系统文件属性。
  H   隐藏文件属性。
  O   脱机属性。
  I   没有内容索引的文件属性。
  X   没有擦除文件属性。
  V   完整性属性。
  P   钉住属性。
  U   未被钉扎的属性。
  [drive:][path][filename]
      指定要处理的ATTILB文件或文件。
  /S  在当前文件夹中匹配文件的进程以及所有子文件夹。
  /D  处理文件夹也是如此
  /L  对符号链接的属性与符号链接的目标进行工作

6.md 创建文件夹

1.如果创建的文件夹有空格,那么需要用引号括起来

例如:

md "d:\my game"

2.同时创建多个目录

md [路径\]目录1 [路径\]目录2 [路径\]目录3……

实例:

在当前目录下建立 abc 和 abcd 两个文件, 同时 D:\gmae 下也建立一个文件夹 123。

md abc D:\gmae\123 abcd

3.创建多级目录

md [路径\]目录1\目录2\目录3\…

实例:

md d:\abc\abcd\abcde

7. 递归查找指定文件

SearchFile.bat

@echo off
setlocal enabledelayedexpansion    
if "%1" equ "" (
    echo 作用: 递归搜索文件名中含有 关键字 的文件,并列出文件的绝对路径 
    ::   上角标符号 ^ 是转义字符,用于输出尖括号
    echo 用法: searchFile ^<关键字^> ^<搜索路径^>
    goto end
)
if "%2" equ "" (
    echo 作用: 递归搜索文件名中含有 关键字 的文件,并列出文件的绝对路径 
    ::   上角标符号 ^ 是转义字符,用于输出尖括号
    echo 用法: searchFile ^<关键字^> ^<搜索路径^>
    goto end
)
echo 开始搜索文件,请等待程序提示“搜索完成”再退出...    
echo.    
echo 搜索结果: > result.txt
for /r %2 /d %%i in (.) do (    
    dir %%i 2>nul | find /i "%1" | find /v "目录"
    if !errorlevel! equ 0 (    ::此处使用感叹号 !    
        echo  上述文件位置 %%i
        echo -------------------------------------------
        echo %%i >> result.txt
    )    
)    
echo.    
echo 搜索完成!回车可退出    
pause >nul 

:end
pause

8. 隐藏某目录的所有文件及文件夹

cd /d 要隐藏的目录(如:D:)      
for /f "usebackq delims=" %%A in (`dir /a /b`) do (attrib "%%A" -r +h -s) 

9. 批处理中使用密码

这个操作可以针对将 bat 文件转换成 exe 文件的时候使用,防止未授权操作

security.bat

@echo off      
set num=0      
:11      
set /p pass=请输入密码:      
if "%pass%"=="admin" goto next1             
set /a num=%num% + 1      
if %num%==3 goto no1      
goto 11      
:no1                
%windir%\system32\rundll32.exe     user32.dll,LockWorkStation      
goto 11      
:next1      
echo 密码正确,执行下面的程式              
pause 

10. 清除 3389 的登录记录

@echo off
@reg delete "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default" /va /f
@del "%USERPROFILE%\My Documents\Default.rdp" /a
@exit 

11.清理 IE 等日志信息

@echo off
color 0a
mode con cols=100 lines=350
echo %date% %time%
set time1=%time::=%
set file=%time1:~,8%
echo 即将进行清理,请先关闭浏览器
set /p=<nul 1>cls%file%.log 2>clsErr%file%.log
set /p a=你确定继续清理吗?(Y/N)
if /i  not "%a%"=="y" goto :end

echo 清理中,请稍后。。。
echo ------------------------------------开始清理:%temp%\*.*>>cls%file%.log
del /f /s /q %temp%\*.* >>cls%file%.log 2>>clsErr%file%.log
del /f /s /q "%userprofile%\locals~1\tempor~1\*.*" >>cls%file%.log 2>>clsErr%file%.log
del /f /s /q "%systemdirve%\recycled\*.*" >>cls%file%.log 2>>clsErr%file%.log
del /f /s /q "%userprofile%\recent\*.*" >>cls%file%.log 2>>clsErr%file%.log
del /f /s /q "%userprofile%\cookies\*.*" >>cls%file%.log 2>>clsErr%file%.log
del /f /s /q "%userprofile%\locals~1\history\*.*" >>cls%file%.log 2>>clsErr%file%.log
echo ------------------------------------开始清理:注册表信息>>cls%file%.log
echo y | reg delete "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\TypedURLS" >>cls%file%.log 2>>clsErr%file%.log
echo y | reg delete "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\internet settings\5.0\cache\extensible cache" >>cls%file%.log 2>>clsErr%file%.log
echo 清理完毕,按任意键退出

:end
pause

或许明日太阳西下倦鸟已归时