欢迎光临
我们一直在努力

【 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 的工程级对比

    维度batps1
    自动化能力 极高
    可维护性
    错误处理 原始 完整
    日志能力 几乎没有 原生支持
    适合规模 中 / 大
    企业标准 淘汰中 主流

    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文件

    执行过程如下所示

    生成如下结果文件

    文件内容如下所示

    赞(0)
    未经允许不得转载:171主机测评 » 【 Windows 操作系统】.bat 与 .ps1 的区别和作用
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址