鉴证实录系列之三:自动删除文件和目录,但须保留指定目录
问题实录
为了方便描述,对本文所描述的问题稍作改动(保留第一人称):
E盘里,除了“网络游戏”、“存档游戏”这两目录外,还有其他用户下载或者拷贝的文件和目录。现在希望自动清空除了“网络游戏”、“存档游戏”这两目录外的所有文件和目录。
我想到了组策略中的“关机脚本”,用Del命令做一个批处理文件,可惜该命令没有排除某文件或目录的参数。
又想到给“网络游戏”、“存档游戏”两个目录设置NTFS权限不让删除,可是试了几次好像不太理想。所以请教大家给一个好的方法。
提示 本问题取自微软Windows XP中文新闻组,原帖的URL如下:
请教关于关机后自动删除E盘里一些用户的文件
分析实录
1.为什么NTFS权限不管用?
先说一个题外话,提问的网友提到给所需排除的目录设置了NTFS访问权限,拒绝当前用户的删除权限,但是关机脚本并不“听话”,这是何故?
原来关机脚本是在用户注销以后,而非注销前运行的,它是以计算机帐户的身份运行,可以理解为运行在system帐户下,目录的ACL对其没有作用。
可以把这个脚本放在组策略的注销脚本里,就可以生效了。
2.Robocopy命令工具
一个简单但是不彻底的方法是借助robocopy命令行工具,因为robocopy可以排除特定的目录(或者组合),这样我们就可以借助robocopy工具把除了“网络游戏”、“存档游戏”这两目录外的所有目录“移动”到回收站目录中,变相达到目的。
但是这个方法,还需要清空、或者删除回收站里的内容,所以说是一个不彻底的方法。
所以接下来我们介绍一个方法,制作一个批处理文件,帮助我们每次关机时自动清除E盘下的内容,而不会影响正常的目录。
提示 以下的方法受到热心网友zeloterr的启发,在此表示感谢。
zeloterr网友原帖的URL
解决实录
1.前提条件
(1) “网络游戏”、“存档游戏”必须位于E盘根目录,这点并不难。
(2) 其他文件和目录必须不具有隐藏属性。这主要是为了防止误删回收站等系统目录。当然你可以修改这个示例,让它可以适合这种情况,这里为了简单起见,不再提供方法。
(3) 必须是中文Windows XP,英文的话,也可以照着改动。
2.批处理文件内容实录
echo off
E:
rem 把当前目录切换到E盘
dir E: /a:d-H >E:\1.txt
rem 列出E盘下的所有目录(除隐藏目录),并把目录列表存放到E盘的1.txt文件里。
for /f "skip=4 tokens=4" %%1 in (E:\1.txt) do @if not "%%1"=="网络游戏" if not "%%1"=="存档游戏" if not "%%1"=="字节" if not "%%1"== "可用字节" rd %%1 /s /q
rem 命令必须放在同一行!中间没有回车符!
rem 该命令对E:\1.txt文件的内容进行扫描,skip=4表示从第四行开始算起(不算空行)。
rem tokens=4表示从第四列开始循环扫描(不算空格)。
rem 显示出所有不包括“网络游戏”和“存档游戏”的内容,这些就是所需删除的目录。
rem 找到所需删除的目录,就用rd /s /q命令删除该目录。
del *.* /a:-h-s /f /q
rem 最后删除E盘根目录下所有文件,当然要排除隐藏文件和系统文件。
把该文件保存为RMDIR.bat,然后放在关机脚本或者注销脚本里,每次关机或者注销时,就会自动删除“网络游戏”、“存档游戏”之外的所有目录和文件,包括1.txt文件本身。
3.疑难注释
(1) 为什么要用“dir E: /a:d-H”命令?
/a:d参数表示仅列出目录,这样才能用接下来的for命令过滤“网络游戏”、“存档游戏”这两个目录。
-H参数确保不会列出隐藏目录,因为某些隐藏目录,例如回收站目录、System Volume Information目录等,都属于系统目录,显然不能将其删除(尽管由于权限原因可能无法删除)。
(2) 如何扫描目录列表?
可以打开CMD命令提示符窗口,运行一下“dir E: /a:d-H”命令,结果如下。
驱动器 E 中的卷是 Program
卷的序列号是 2833-C34F
E:\ 的目录 从第四列开始是目录名!
2006-03-07 20:55 <DIR> ATI 从第四行开始是目录!
2006-04-13 11:56 <DIR> Log
2006-04-14 03:20 <DIR> My Documents
2006-04-22 16:00 <DIR> Outlook
2006-04-23 12:16 <DIR> Program Files
2006-02-25 12:51 <DIR> symbols
2006-04-24 01:02 <DIR> Temp
2006-04-23 22:42 <DIR> Temporary Internet Files
2006-03-28 12:36 <DIR> Test Vista
2006-04-16 23:58 <DIR> Windows Vista Product Guide - Beta 2
0 个文件 0 字节
10 个目录 4,494,643,200 可用字节
可以看到命令结果中,从第四行开始才显示目录信息,而从第四列开始才是目录名。
这里要注意的是,命令结果最后两行的“字节”和“可用字节”也位于第四列,这需要我们在目录扫描里将其排除(目录名为“字节”或者“可用字节”的可能性极小)。
for /f "skip=4 tokens=4" %%1 in (E:\1.txt) do @if not "%%1"=="网络游戏" if not "%%1"=="存档游戏" if not "%%1"=="字节" if not "%%1"== "可用字节" rd %%1 /s /q
以上的命令的执行含义是:
对E:\1.txt文件里的内容,从第四行、第四列开始,依次扫描每个目录名,只要不是“网络游戏”、“存档游戏”和“字节”、“可用字节”,则运行“rd %%1 /s /q”命令将该目录彻底删除(1%%是批处理文件的参数,代表满足筛选条件的目录名)。
(3) 为什么要执行“del *.* /a:-h-s /f /q”
前面所述的for循环命令只能删除目录,要删除E盘根目录下的文件,还需要执行del命令。以上的del命令可以删除所有根目录下的文件,除隐藏和系统文件之外。
写在后面
1.防君子不防小人
严格来说,这个方法象征意义更多一些。如果其他用户是略懂电脑、且人品略有贵恙者,则该脚本几乎对他们无用,例如只要把下载的文件存放在“网络游戏”和“存档游戏”目录下,就可以轻松绕过脚本的限制。
2.攻心为上
窃以为还是攻心为上、技术为辅,应该向朋友解释E盘空间有限,为了照顾大家所计,必须限制配额—说到配额,自然想到可以用NTFS磁盘配额来限制每个用户可以使用的E盘空间,如果超过这个配额,就会拒绝用户继续写文件,并给出提示警告。
如果启用NTFS磁盘配额,还可以有一个方法,可以用来处理特定用户的文件和目录:
利用“fsutil /file /findbysid UserName”命令可以生成指定用户所拥有的所有文件和目录列表,然后我们就可以编制脚本,删除其中的某些文件和目录,脚本从略。