Windows批处理

温馨提示:点击页面下方以展开或折叠目录~

Windows批处理

本来只打算抄个批处理的脚本做windows下jdk版本的快速切换,在写的时候发现了批处理脚本和语法还挺有趣的,感觉有些甚至可以应用到安全中,遂记录下一些有趣的东西

https://github.com/vvmdx/changeYourJDK

这是我编写的批处理切换jdk的脚本

用户变量和系统变量

一般来说windows的环境变量包括了用户变量和系统变量,用户变量对当前的用户起作用,系统变量对所有用户起作用

一般的环境变量优先级是用户变量 > 系统变量,也就是说会优先从用户变量中寻找值,找不到再去系统变量中寻找,举个例子:

image

可以看到对于用户变量和系统变量中都出现的TEMP和TMP变量,若当前为用户权限,则会先在用户变量中寻找对应的值,若在用户变量中找不到,例如windir,则会去系统变量中查找

而Path这个变量比较奇葩,他是优先从系统变量找起,再找到用户变量,如果你用echo %path%将环境变量打印出来,将会发现打印的顺序是从系统变量Path的第一个开始,一直打印到用户变量Path的最后一个,举个例子:

image

可以看到,虽然我们打印出来的JAVA_HOME是jdk11.0.3,为用户变量的值,但是java -version显示的是系统变量里的jdk1.8.0_291

总结:

  • 一般来说环境变量调用优先级 用户变量 > 系统变量
  • Path变量优先级 系统变量 > 用户变量

@echo off

  • @:关闭其后命令的回显
  • echo off:关闭其他所有命令的回显
  • pause:用于暂停程序,防止批处理运行完直接退出

当无@echo off指令时

1
2
3
4
echo this is a test
echo %JAVA_HOME%
where java
pause

将以上保存为bat并执行,效果如下,可以看到相当于分别执行了4条指令

image

当echo off没有@时

1
2
3
4
5
echo off
echo this is a test
echo %JAVA_HOME%
where java
pause

批处理执行如下,可以看到只有第一条指令有回显

image

当使用@echo off时

1
2
3
4
5
@echo off
echo this is a test
echo %JAVA_HOME%
where java
pause

可以看到@echo off这一行也没了,只有剩下的内容,这正是我们希望的效果

image

set和setx

  • set和setx都是设置环境变量,不过set只针对于当前的cmd窗口,而setx是直接修改全局(注册表)环境变量

  • 以下是windows对set和setx的描述

    1
    2
    3
    4
    ::set
    显示、设置或删除 cmd.exe 环境变量。
    ::setx
    在用户或系统环境创建或修改环境变量。能基于参数、注册表项或文件输入设置变量。

set

当使用set修改环境变量时

image

可以看到在当前cmd窗口的JAVA_HOME变量已经被修改,这时当我们另开一个cmd窗口时,就会像下面这样

image

可以发现并没有在全局生效

setx

当使用setx修改环境变量时

1
2
3
4
:: 下面这条只能对用户变量生效
setx JAVA_HOME D:\DevelopTools\Java\jdk1.8.0_291
:: 加上/M才能对环境变量生效
setx JAVA_HOME D:\DevelopTools\Java\jdk1.8.0_291 /M

判断运行当前bat的用户权限

net session

  • net session用于连接、删除或查看本机与其他机器的网络连接,需要管理员权限才可以查看

image

访问需要管理员权限的路径

  • %SYSTEMROOT%\system32\config\system

    image

  • md(make directory) & rd(remove directory)

    创建目录、删除目录,若目录为系统路径,则需要管理员权限

    image

    • 首先用普通权限创建目录md %windir%\system32\aaatestaaa,可以看到拒绝访问
    • 接着用管理员权限创建目录,创建成功

    用这个方法虽然也可以判断,但是只能判断一次,因为创建后再次尝试创建时,普通用户和管理员都会返回一样的结果;因此如果要通过此方法判断管理员权限,需要结合rd(删除目录)的指令

    image

    上面的是普通用户,下面是管理员用户,其实就是在创建目录后再将其删除,普通用户没权限,管理员创建后会删除,就达到了可以一直进行判断的效果

重定向之>nul

  • > ,>>:输出重定向,echo 123>test.txt将把123输出到文件test.txt中,若文件已存在,则首先删除该文件的信息,再写入123;若文件不存在,则会先创建文件,再写入

  • >nul:将输出重定向到空,也就是不会打印到dos界面,可以达到屏蔽输出的效果

  • 1>nul:屏蔽正确执行命令的输出

  • 2>nul:屏蔽错误执行命令的输出

    image

    可以看到普通用户下net session执行错误,当使用2>nul时屏蔽了错误输出

    管理员权限下net session执行成功,当使用1>nul时屏蔽了正确输出

||与&&

  • &&表示它前面的语句成功执行的话将执行后面的语句

  • ||表示它之前的语句执行失败将执行后面的语句

  • 两者组和可以实现if…else…的效果

    image

    可以看到当普通用户net session执行失败的情况下,使用||就会执行后面的语句;当管理员net session执行成功的情况下,使用&&会执行后面的语句

PsTools

  • 官网下载:https://docs.microsoft.com/en-us/sysinternals/downloads/pstools

  • PsTools是一组能实现安全管理的套件,其中PsExec.exe可以打开system权限的进程

    image

    可以看到在开启system权限前,即使是管理员权限的cmd,打印的环境变量也是用户变量;但是system权限的cmd,打印的环境变量已经变成了系统变量