【 Windows 操作系统】.bat 与 .ps1 的区别和作用
很多人“会用脚本”,但说不清脚本。 真正的差距,往往从 bat 和 ps1 的理解深度 开始拉开。
一、为什么 Windows 会同时存在 .bat 和 .ps1?
这是一个历史 + 架构演进的问题。
-
.ps1是 PowerShell 脚本文件的扩展名,用于编写和执行 PowerShell 脚本。 -
.bat是 Windows 批处理脚本文件的扩展名,用于编写和执行一系列 Windows 命令。
1.1、.bat 的诞生背景
.bat(Batch File)来自 DOS 时代,核心设计目标只有一个:
把人工在命令行里敲的命令,一次性自动执行
所以它的设计思想是:
-
命令逐行执行
-
一切皆字符串
-
几乎没有“语言设计”
1.2、.ps1 的出现原因
随着 Windows 成为服务器操作系统、企业级平台,仅靠 bat 已经不够:
-
需要批量管理服务
-
需要操作注册表、AD、WMI
-
需要结构化数据(XML / JSON)
-
需要远程管理
于是 PowerShell 诞生了,而 .ps1 是它的脚本载体。
PowerShell 不是 CMD 的升级版,而是全新的自动化平台

二、.bat 是什么?
2.1、执行模型
-
执行程序:
cmd.exe -
执行方式:逐行解释
-
失败不会自动终止(除非你自己判断)
cmd.exe /c test.bat
2.2、核心特征
-
无对象概念
-
变量全是字符串
-
依赖系统内置命令
-
错误处理极弱
2.3、bat 的“变量系统”
set VAR=value
echo %VAR%
⚠️ 注意:
-
%VAR%是文本替换 -
不是运行时计算
-
循环里要用
!VAR!(延迟展开)
三、.bat 的完整语法体系
3.1、基本结构
@echo off
rem 这是注释
echo Hello World
pause
| 关键字 | 含义 |
|---|---|
@echo off |
关闭命令回显,未关闭回显时,每条命令都会先被打印出来,再执行并显示结果。 |
rem |
注释,rem 为注释命令,一般用来给程序加上注解,该命令后的内容不被执行,但能回显,::用于进行文本的注释,执行后即使打开echo on也不会回显内容 |
pause |
等待按键,用于暂停批处理脚本执行,显示本地化提示(如‘请按任意键继续...’),并等待用户任意按键后才继续。其核心价值在于防止命令窗口闪退 |
@echo off
title REM 和 :: 最小回显测试
echo 先关闭回显
echo.
pause
echo on
REM 这一行是 REM
:: 这一行是 ::
echo 这一行是普通 echo 输出
@echo off
echo.
echo 测试完成
pause
执行后结果如下所示
3.2、条件判断(if)
@echo off
title IF 输入判断示例
set /p a=请输入一个数字:
if %a%==1 (
echo 你输入的是 1
) else (
echo 你输入的不是 1
)
pause

常见判断:
-
exist -
== -
errorlevel
if %errorlevel% neq 0 echo 执行失败
这是 bat 最容易写出 bug 的地方。
3.3、循环(for)
@echo off
for %%i in (*.txt) do echo 找到文件:%%i
pause

for /f(最反人类的语法):
/f 表示 按行读取文本内容并进行解析。
@echo off
title 获取本机 IPv4 地址示例
echo 正在获取本机 IPv4 地址...
echo.
for /f "tokens=2 delims=:" %%i in ('ipconfig ^| findstr /i "IPv4"') do echo 本机IPv4地址:%%i
echo.
pause
bat 最大的痛点:
能做的事 ≠ 好做的事
四、.ps1 是什么?
4.1、本质定位
.ps1 是 PowerShell 脚本文件
而 PowerShell 本身是:
基于 .NET 的面向对象自动化语言
这句话极其重要。
4.2、执行模型
-
执行程序:
powershell.exe/pwsh.exe -
命令返回的不是文本,而是 对象
Get-Service
返回的是:
System.ServiceProcess.ServiceController
而不是字符串。

五、.ps1 的语法体系
5.1、变量与类型
$name = "Windows"
$count = 10
支持强类型:
[int]$port = 443

Windows 默认不允许直接运行 .ps1 脚本,运行需要配置如下命令
配置只对当前 PowerShell 临时允许
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

5.2、条件判断(if)
$port = 443
if ($port -eq 443) {
Write-Host "HTTPS"
} else {
Write-Host "Other"
}
对比 bat:可读性直接碾压
5.3、循环(foreach / for)
foreach ($svc in Get-Service) {
if ($svc.Status -eq "Stopped") {
Write-Host $svc.Name
}
}

这里 $svc 是对象,不是字符串。
5.4、管道(PowerShell 灵魂)
Get-Service | Where-Object Status -eq "Running"
这就是 PowerShell 能彻底干掉 bat 的原因。

5.5、函数(企业级脚本必备)
function Restart-MyService {
param($Name)
Restart-Service $Name
}
六、执行策略(为什么 ps1 默认跑不了)
6.1、执行策略是什么?
PowerShell 引入了 Execution Policy:
防止脚本被恶意执行
常见策略:
| 策略 | 含义 |
|---|---|
| Restricted | 禁止脚本 |
| RemoteSigned | 本地允许 |
| Bypass | 全放行 |
6.2、企业最常用方式
powershell -ExecutionPolicy Bypass -File deploy.ps1
注意:这是“临时放行”,不改系统策略。
七、.bat 与 .ps1 的工程级对比
| 维度 | bat | ps1 |
|---|---|---|
| 自动化能力 | 低 | 极高 |
| 可维护性 | 差 | 好 |
| 错误处理 | 原始 | 完整 |
| 日志能力 | 几乎没有 | 原生支持 |
| 适合规模 | 小 | 中 / 大 |
| 企业标准 | 淘汰中 | 主流 |
bat 能跑 ps1 能长期维护
八、真实企业场景建议
8.1、不再用 bat 的场景
-
安全整改脚本
-
批量系统配置
-
运维巡检
-
自动化部署
8.2、ps1 的黄金场景
-
等保 / 分保脚本
-
批量漏洞修复
-
服务巡检
-
日志采集
-
AD / 注册表管理
九、一个现实真相
很多“只会 bat 的运维”, 本质上还停留在 人工命令自动化阶段
而 PowerShell 做的是:
系统能力的程序化控制
这是两个时代。
.bat是历史的产物.ps1是 Windows 自动化的基石懂 bat 是入门 精通 ps1 才是职业护城河
十、【实战】Windows信息检查脚本
功能说明:
检查Windows主机的硬件配置,系统安装时间,系统版本,硬件序列号等。
具体脚本内容:
GetSystemInfo.ps1文件内容如下所示
# ========================================================
# 版权所有 © 2026 笨熊呆呆瓜
# 联系方式:842668578@qq.com
# 用途:收集本机系统信息(时间、主机名、用户、BIOS、硬盘、IP与MAC等)
# ========================================================
# 确保脚本路径正确
$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { Get-Location }
Set-Location -Path $scriptDir
# 获取时间、主机名、用户、操作系统信息
$timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$hostname = $env:COMPUTERNAME
$username = $env:USERNAME
$osinfo = Get-CimInstance Win32_OperatingSystem
$osname = $osinfo.Caption
$installTime = $osinfo.InstallDate.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss")
# 构造输出文件路径
$outputFile = Join-Path $scriptDir "system_info_${hostname}_${timestamp}.txt"
# 初始化输出
Set-Content -Path $outputFile -Value "===== 系统信息收集 =====" -Encoding UTF8
Add-Content -Path $outputFile -Value "导出时间:$timestamp" -Encoding UTF8
Add-Content -Path $outputFile -Value "系统安装时间:$installTime" -Encoding UTF8
Add-Content -Path $outputFile -Value "主机名:$hostname" -Encoding UTF8
Add-Content -Path $outputFile -Value "当前用户:$username" -Encoding UTF8
Add-Content -Path $outputFile -Value "操作系统:$osname" -Encoding UTF8
Add-Content -Path $outputFile -Value "" -Encoding UTF8
# BIOS 序列号
Add-Content -Path $outputFile -Value "[设备序列号 - BIOS SerialNumber]" -Encoding UTF8
(Get-CimInstance Win32_BIOS).SerialNumber | Add-Content -Path $outputFile -Encoding UTF8
Add-Content -Path $outputFile -Value "" -Encoding UTF8
# 物理硬盘序列号
Add-Content -Path $outputFile -Value "[硬盘序列号 - Disk Serial Numbers]" -Encoding UTF8
Get-PhysicalDisk | ForEach-Object {
"硬盘: $($_.FriendlyName) - 序列号: $($_.SerialNumber)" |
Add-Content -Path $outputFile -Encoding UTF8
}
Add-Content -Path $outputFile -Value "" -Encoding UTF8
# 网卡 IP 和 MAC 配对输出(清晰配对)
Add-Content -Path $outputFile -Value "[网络接口 - IP 与 MAC 地址配对]" -Encoding UTF8
$adapters = Get-NetAdapter | Where-Object { $_.Status -eq "Up" }
foreach ($adapter in $adapters) {
$name = $adapter.Name
$mac = $adapter.MacAddress
$ips = Get-NetIPAddress -InterfaceAlias $name -AddressFamily IPv4 | Where-Object { $_.IPAddress -ne $null }
if ($ips.Count -eq 0) {
Add-Content -Path $outputFile -Value "接口: $name" -Encoding UTF8
Add-Content -Path $outputFile -Value " IP地址: 无" -Encoding UTF8
Add-Content -Path $outputFile -Value " MAC地址: $mac" -Encoding UTF8
} else {
foreach ($ip in $ips) {
Add-Content -Path $outputFile -Value "接口: $name" -Encoding UTF8
Add-Content -Path $outputFile -Value " IP地址: $($ip.IPAddress)" -Encoding UTF8
Add-Content -Path $outputFile -Value " MAC地址: $mac" -Encoding UTF8
}
}
Add-Content -Path $outputFile -Value "" -Encoding UTF8
}
# 控制台驻留(兼容所有 PowerShell 版本)
Write-Host "`n系统信息已导出到:" -NoNewline
Write-Host "$outputFile" -ForegroundColor Green
Write-Host "请按任意键退出..."
[void][System.Console]::ReadKey($true)
BAT文件RunSystemInfo.bat内容如下所示
@echo off
:: ========================================================
:: 版权所有 © 2026 笨熊呆呆瓜
:: 联系方式:842668578@qq.com
:: 用途:调用 PowerShell 脚本收集本机系统信息
:: ========================================================
powershell -ExecutionPolicy Bypass -NoExit -File "%~dp0GetSystemInfo.ps1"
运行BAT文件

执行过程如下所示

生成如下结果文件

文件内容如下所示

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)