一、批处理脚本(.bat
/.cmd
)
1. 本质与执行环境
- 扩展名:
.bat
(兼容旧版 MS-DOS)、.cmd
(Windows NT 之后的标准格式,支持 Unicode 注释) - 执行引擎:
cmd.exe
(命令解释器),通过%ComSpec%
环境变量指向(默认C:\Windows\System32\cmd.exe
) - 文件编码:默认 ANSI(GBK/UTF-8 需配合
chcp 65001
或 BOM 头)
2. 语法基础
- 注释:
rem 注释
(支持换行)或:: 单行注释
(不支持重定向) - 命令回显:
@echo off
(禁止回显当前命令),echo 文本
(输出内容) - 特殊符号:
- 管道:
|
(传递前一命令输出到后一命令) - 并行执行:
&
(命令1 & 命令2
) - 条件执行:
&&
(前成功后执行)、||
(前失败后执行) - 重定向:
>
(覆盖写入)、>>
(追加写入)、<
(输入重定向) - 转义:
^
(转义特殊符号,如^&
表示字面量&
)
- 管道:
3. 变量与参数
- 环境变量:
%变量名%
(如%SystemRoot%
、%USERPROFILE%
) - 自定义变量:
set 变量=值
(set name=John
→%name%
) - 延迟变量扩展:
setlocal enabledelayedexpansion // 启用延迟扩展 set count=0 for /L %%i in (1,1,5) do ( set /a count+=1 echo !count! // 用 `!` 替代 `%` 访问实时值 )
- 参数传递:
%0
(脚本自身路径),%1
~%9
(位置参数),%*
(所有参数)- 修正参数顺序:
shift
(左移参数,%1
变为原%2
)
4. 控制结构
- 条件判断(
if
):if exist "C:\file.txt" ( echo 文件存在 ) else ( echo 文件不存在 ) if %errorlevel% equ 0 echo 命令执行成功 // 检查错误码(需配合 `set errorlevel=N`) if defined variable echo 变量已定义 if " %str% "==" hello " echo 字符串相等(注意空格防空值错误)
- 循环(
for
):- 遍历文件:
for %%i in (*.txt) do echo %%i
- 数值循环:
for /L %%i in (1,1,10) do echo %%i
(从1到10,步长1) - 解析输出:
for /f "tokens=2 delims=," %%i in ('命令') do echo %%i
(提取逗号分隔的第2列) - 目录遍历:
for /d %%i in (C:\dir\*) do echo %%i
(仅目录)
- 遍历文件:
- 跳转(
goto
/exit
)::label echo 到达标签 goto :eof // 退出当前脚本(等价于 `exit /b`) exit 99 // 终止 cmd 进程并返回错误码 99
5. 高级功能
- 错误处理:
try/catch
模拟:通过set errorlevel
和if %errorlevel%
判断- 静默执行:
>nul 2>&1
(重定向标准输出和错误到nul)
- 与外部程序交互:
- 调用 exe:
start "" "C:\program.exe"
(避免阻塞脚本) - 传递参数:
call another.bat 参数1 参数2
(保留当前环境变量)
- 调用 exe:
- 脚本调试:
echo on
显示执行的每一条命令pause
暂停执行以便查看输出rem 注释关键步骤
辅助定位问题
6. 限制与最佳实践
- 不支持浮点运算:仅整数运算(
set /a x=10/3
→ x=3) - 路径处理:用
~dpnx
修饰符解析参数路径(%~dp1
为参数1的驱动器+路径) - 避免中文路径:默认编码可能导致乱码,建议用
chcp 65001
切换 UTF-8
二、PowerShell 脚本(.ps1
)
1. 核心特性
- 执行引擎:
powershell.exe
(Windows 原生)/pwsh.exe
(跨平台 PowerShell Core) - 语言特性:基于
.NET
,支持面向对象、函数、类、模块,管道传递对象而非文本 - 执行策略(安全控制):
Get-ExecutionPolicy // 查看当前策略(默认 Restricted,禁止运行脚本) Set-ExecutionPolicy RemoteSigned -Scope CurrentUser // 允许运行本地编写的脚本
2. 语法基础
- 变量:
$var = "值"
(强类型可选,默认对象类型) - 注释:
# 单行注释
,<# 多行注释 #>
- 输出:
Write-Host "文本"
(控制台输出),Write-Output "对象"
(供管道使用)
3. 控制结构
- 条件判断(
if
):if ($file.Exists) { "文件存在" } elseif ($file.Length -gt 1MB) { "文件过大" } else { "文件不存在" }
- 循环:
for ($i=0; $i -lt 10; $i++) { ... }
foreach ($item in $collection) { ... }
(推荐,支持对象遍历)while ($condition) { ... }
- 函数:
function Get-FreeSpace { [CmdletBinding()] // 启用高级参数功能 param ( [string]$Path = $env:SystemDrive ) $drive = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='$Path'" [PSCustomObject]@{ Drive = $Path FreeSpaceGB = $drive.FreeSpace / 1GB -as [int] } }
4. 系统管理核心
- Cmdlet(命令集):
- 文件系统:
Get-ChildItem
(等价dir
)、Copy-Item
、Remove-Item
- 进程管理:
Get-Process
、Stop-Process -Id 1234
- 服务控制:
Get-Service
、Start-Service "ServiceName"
- 注册表:
Set-ItemProperty -Path HKLM:\Software\Test -Name Value -Value 1
- 文件系统:
- 管道操作:
Get-ChildItem C:\ -Filter *.log | Where-Object Length -gt 1MB | Sort-Object LastWriteTime | Remove-Item ```(筛选、排序、删除大日志文件)
5. 高级功能
- 自定义对象:
[PSCustomObject]@{属性1=值1; 属性2=值2}
- 调用 .NET 类:
$webClient = New-Object System.Net.WebClient $webClient.DownloadFile("http://url", "C:\file.exe")
- 远程处理:
Invoke-Command -ComputerName Server01 -ScriptBlock { Get-Service } // 远程执行命令 Enter-PSSession Server01 // 交互式远程会话
- 模块管理:
Import-Module ActiveDirectory // 加载 Active Directory 管理模块 Find-Module -Name *security* // 搜索在线模块(需 PowerShell Gallery 权限)
6. 最佳实践
- 使用参数绑定:通过
[Parameter()]
定义强类型参数,支持补全和验证 - 日志记录:
Write-Log
自定义函数记录执行详情 - 避免
Write-Host
:优先用Write-Output
保证管道兼容性
三、VBScript 脚本(.vbs
)与 JScript(.js
)
1. 执行环境
- Windows 脚本宿主(WSH):
wscript.exe
(图形化宿主,弹出对话框)cscript.exe
(命令行宿主,输出到控制台,加/nologo
隐藏版权信息)
- 语言定位:早期 Windows 自动化工具,基于 COM 对象,语法简单但功能有限。
2. VBScript 核心语法
- 变量:
Dim var
(弱类型,默认Empty
) - 消息对话框:
MsgBox "内容", 按钮类型 + 图标类型, "标题" ' 示例:MsgBox "操作完成", 64 + 0, "提示" (64=问号图标,0=确定按钮)
- 文件系统操作(FSO 对象):
Set fso = CreateObject("Scripting.FileSystemObject") If fso.FileExists("C:\file.txt") Then Set file = fso.OpenTextFile("C:\file.txt", 1) ' 1=只读,2=写入,8=追加 content = file.ReadAll file.Close End If
- 注册表操作:
Set reg = CreateObject("WScript.Shell").RegWrite reg.RegWrite "HKCU\Software\Test\Value", "数据", "REG_SZ" ' 写入字符串值
3. JScript 语法差异
- 变量声明:
var x = 10;
(类似 JavaScript) - 函数定义:
function sayHello() { WScript.Echo("Hello"); }
- 对象访问:通过
WScript.Shell
替代 VBScript 的CreateObject
4. 限制与替代方案
- 无错误处理机制:依赖
On Error Resume Next
静默错误 - 被 PowerShell 取代:现代场景建议用 PowerShell 实现 COM 对象调用(如
New-Object -ComObject Scripting.FileSystemObject
)
四、脚本文件对比与选型指南
特性 | 批处理(.bat ) | PowerShell(.ps1 ) | VBScript(.vbs ) |
---|---|---|---|
学习难度 | 简单(基础命令) | 中等(面向对象+.NET) | 简单(VB 语法) |
系统控制能力 | 有限(仅 cmd 命令) | 极强(.NET+COM+API) | 中等(COM 对象) |
跨平台支持 | 仅 Windows | 跨平台(PowerShell Core) | 仅 Windows |
复杂逻辑支持 | 基础(有限循环/条件) | 完整(函数/类/模块) | 基础(无模块) |
默认执行安全 | 高(无执行策略) | 严格(需配置 ExecutionPolicy) | 中等(WSH 安全设置) |
- 选型建议:
- 快速文件操作/兼容性优先:批处理
- 系统管理/自动化运维:PowerShell
- 老旧系统兼容/简单弹窗提示:VBScript(不建议新项目)
五、高级主题与最佳实践
1. 脚本调试
- 批处理:
echo on
显示命令,pause
暂停,setlocal enabledelayedexpansion
调试变量 - PowerShell:
Set-PSBreakpoint -Command Get-ChildItem
设置断点,Debug-Runspace
交互式调试 - VBScript:
cscript //X 脚本.vbs
启动调试器(需安装 Visual Studio 调试工具)
2. 环境变量与作用域
- 批处理:
set
变量仅在当前 cmd 窗口或脚本内有效,setx
写入注册表持久化(需管理员权限) - PowerShell:
$env:变量名 = "值"
临时修改,Set-Item -Path Env:变量名 -Value "值"
同作用域有效
3. 权限管理
- 以管理员身份运行:脚本开头添加
@echo off fltmc >nul 2>&1 || (powershell start-process -verb runas '%0' & exit /b) ```(批处理检测管理员权限,非管理员时重新以管理员身份启动)
- PowerShell 脚本:
Start-Process -FilePath $PSCommandPath -Verb RunAs
4. 性能优化
- 批处理:合并多条命令减少
cmd.exe
启动次数(如&
或()
分组) - PowerShell:使用
Where-Object -FilterScript
替代循环遍历,利用管道流水线并行处理
六、总结与资源推荐
- 官方文档:
- 学习路径:
- 掌握批处理基础命令与流程控制
- 深入 PowerShell Cmdlet 与对象模型
- 实践系统管理脚本(用户创建、服务监控、日志分析)