一、为什么需要批量管理Windows系统?

每天重复点击鼠标、输入相同命令的日子该结束了!想象一下:公司新采购了50台服务器,你需要逐台设置IP、安装软件、配置防火墙...手动操作不仅耗时,还容易出错。这就是PowerShell大显身手的时候——它就像给你的键盘装上了"复制粘贴"功能,只不过操作对象是整个网络里的计算机。

举个真实案例:某企业运维团队曾花费3天手动部署100台电脑,改用PowerShell脚本后,同样的工作45分钟就完成了,准确率还达到100%。这就是自动化管理的魅力。

二、PowerShell入门其实很简单

别被命令行界面吓到,PowerShell比你想的更友好。它支持"动词-名词"式的直观命令,比如:

# 技术栈:PowerShell 5.1+
# 获取所有正在运行的浏览器进程
Get-Process -Name chrome,firefox,edge  

# 停止所有Excel进程
Stop-Process -Name excel -Force

看到没?命令读起来就像英语句子。Get就是获取,Stop就是停止,Process代表进程。这种设计让命令更容易记忆。

三、五个实用场景带你起飞

场景1:批量安装软件

# 技术栈:PowerShell 5.1+
# 定义需要安装的软件列表
$softwareList = @("7zip","notepadplusplus","googlechrome")

# 使用Chocolatey包管理器自动安装
foreach ($software in $softwareList) {
    choco install $software -y
    Write-Host "$software 安装完成" -ForegroundColor Green
}

小贴士:需要先安装Chocolatey(执行Set-ExecutionPolicy Bypass然后运行iwr https://chocolatey.org/install.ps1 -UseBasicParsing | iex)

场景2:统一设置IP地址

# 技术栈:PowerShell 5.1+
# 定义IP配置参数
$ipAddress = "192.168.1.100"
$subnetMask = "255.255.255.0"
$gateway = "192.168.1.1"
$dnsServers = @("8.8.8.8", "114.114.114.114")

# 获取网络适配器(这里以有线网卡为例)
$adapter = Get-NetAdapter -Name "Ethernet"

# 配置静态IP
New-NetIPAddress -InterfaceIndex $adapter.ifIndex `
                 -IPAddress $ipAddress `
                 -PrefixLength 24 `
                 -DefaultGateway $gateway

# 设置DNS
Set-DnsClientServerAddress -InterfaceIndex $adapter.ifIndex `
                           -ServerAddresses $dnsServers

场景3:自动化用户账户管理

# 技术栈:PowerShell 5.1+
# 批量创建部门用户
$departments = @("财务部","技术部","市场部")
$password = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force

foreach ($dept in $departments) {
    for ($i=1; $i -le 5; $i++) {
        $username = "$dept-User$i"
        New-LocalUser -Name $username `
                     -Password $password `
                     -FullName "$dept 员工$i" `
                     -Description "自动创建账户"
        Add-LocalGroupMember -Group "Users" -Member $username
        Write-Host "已创建用户: $username"
    }
}

场景4:集中收集系统信息

# 技术栈:PowerShell 5.1+
# 获取多台计算机的系统信息
$computers = @("PC01","PC02","PC03")
$outputFile = "C:\Reports\SystemInfo_$(Get-Date -Format 'yyyyMMdd').csv"

$results = foreach ($pc in $computers) {
    # 如果计算机在线则收集信息
    if (Test-Connection -ComputerName $pc -Count 1 -Quiet) {
        $os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $pc
        $cpu = Get-WmiObject -Class Win32_Processor -ComputerName $pc
        $disk = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID='C:'" -ComputerName $pc

        [PSCustomObject]@{
            ComputerName = $pc
            OSVersion = $os.Caption
            CPU = $cpu.Name
            FreeSpace = "{0:N2} GB" -f ($disk.FreeSpace / 1GB)
            LastBoot = $os.LastBootUpTime
        }
    }
}

# 导出到CSV文件
$results | Export-Csv -Path $outputFile -NoTypeInformation
Write-Host "系统信息报告已生成: $outputFile"

场景5:定时清理磁盘空间

# 技术栈:PowerShell 5.1+
# 自动清理临时文件并发送邮件报告
function Clean-DiskSpace {
    param (
        [string]$Drive = "C:",
        [int]$DaysOld = 30
    )

    # 记录清理前空间
    $before = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID='$Drive'"
    $startFree = $before.FreeSpace / 1GB

    # 清理临时文件
    $tempFolders = @(
        "$env:TEMP",
        "$env:WINDIR\Temp",
        "$env:USERPROFILE\AppData\Local\Temp"
    )

    foreach ($folder in $tempFolders) {
        if (Test-Path $folder) {
            Get-ChildItem -Path $folder -Recurse | 
            Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$DaysOld) } |
            Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
        }
    }

    # 清理Windows更新缓存
    if (Test-Path "$env:WINDIR\SoftwareDistribution\Download") {
        Remove-Item -Path "$env:WINDIR\SoftwareDistribution\Download\*" -Recurse -Force
    }

    # 生成报告
    $after = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID='$Drive'"
    $endFree = $after.FreeSpace / 1GB
    $freed = $endFree - $startFree

    return [PSCustomObject]@{
        Drive = $Drive
        FreedSpaceGB = [math]::Round($freed, 2)
        BeforeCleanGB = [math]::Round($startFree, 2)
        AfterCleanGB = [math]::Round($endFree, 2)
        CleanedTime = Get-Date
    }
}

# 执行清理并显示结果
$result = Clean-DiskSpace -Drive "C:" -DaysOld 30
$result | Format-Table -AutoSize

四、进阶技巧:远程管理与计划任务

远程批量执行命令

# 技术栈:PowerShell 5.1+
# 配置远程管理(需先在目标机启用PSRemoting)
Enable-PSRemoting -Force

# 定义目标计算机列表
$computers = Get-Content -Path "C:\ServerList.txt"

# 在远程计算机上执行磁盘检查
$scriptBlock = {
    chkdsk C: /f /r
    Get-Date
}

# 并行执行远程命令
Invoke-Command -ComputerName $computers -ScriptBlock $scriptBlock -AsJob

创建计划任务

# 技术栈:PowerShell 5.1+
# 创建每周五晚上清理磁盘的任务
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
                                  -Argument "-File C:\Scripts\WeeklyCleanup.ps1"

$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Friday -At 8pm

Register-ScheduledTask -TaskName "Weekly Maintenance" `
                      -Action $action `
                      -Trigger $trigger `
                      -Description "自动执行每周清理任务"

五、避坑指南与最佳实践

  1. 执行权限问题: 首次运行脚本前需要设置执行策略:

    Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
    
  2. 错误处理很重要

    # 好的做法:添加错误处理和日志记录
    try {
        # 尝试执行可能失败的操作
        Stop-Service -Name "SomeService" -ErrorAction Stop
    }
    catch {
        # 记录错误详情
        $errorMsg = $_.Exception.Message
        Write-Warning "操作失败: $errorMsg"
        Add-Content -Path "C:\ScriptLog.txt" -Value "$(Get-Date) - ERROR: $errorMsg"
    }
    
  3. 脚本安全建议

    • 不要在脚本中硬编码密码,使用SecureString或凭据管理器
    • 对重要操作添加确认提示:
      $confirmation = Read-Host "确定要删除所有临时文件吗?(y/n)"
      if ($confirmation -ne 'y') { exit }
      
  4. 性能优化技巧

    • 处理大量计算机时使用并行处理:
      # 使用ForEach-Object -Parallel (PowerShell 7+)
      $computers | ForEach-Object -Parallel {
          Test-Connection -ComputerName $_ -Count 1
      } -ThrottleLimit 10
      

六、为什么选择PowerShell而不是其他工具?

优势

  • 内置于Windows系统,无需额外安装
  • 直接调用.NET框架,功能强大
  • 面向对象的管道设计
  • 完善的远程管理能力
  • 丰富的社区支持

局限性

  • 跨平台支持不如Bash(虽然PowerShell Core已改进)
  • 学习曲线略高于简单批处理
  • 部分旧系统需要升级PowerShell版本

适用场景

  • Windows环境下的自动化管理
  • 需要与Active Directory集成的操作
  • 涉及.NET对象的高级操作
  • 需要结构化数据处理的场景

七、你的自动化之旅现在开始

从今天开始,试着把重复性工作变成脚本吧!建议从小处着手:

  1. 先记录你每天做的重复操作
  2. 选择最耗时的3个任务
  3. 查找对应的PowerShell命令
  4. 组合成简单脚本
  5. 逐步扩展功能

记住:不需要一次写出完美脚本,就像学游泳,先在浅水区练习。遇到问题随时可以查阅微软官方文档或访问PowerShell技术社区。

最后送大家一个实用小技巧:在PowerShell窗口按F8可以快速执行选中的代码片段,这对调试脚本特别有用!