PowerShell 教程

PowerShell 教程

PowerShell 是微软推出的命令行 Shell 与脚本语言,基于 .NET Framework/.NET Core,内置 Windows 管理能力,也支持跨平台(Linux/macOS)。它是系统管理员与运维工程师的必备工具。

核心特性

  • 面向对象:命令输出的是对象而非纯文本,便于管道处理
  • Cmdlet:动词-名词 命名规范(如 Get-Process)
  • 管道管道:把对象在命令间传递,无需解析文本
  • 强大的脚本能力:变量、函数、控制结构、错误处理一应俱全
  • 系统集成:可直接管理注册表、WMI、事件日志、AD 域等

版本概览

版本平台说明
Windows PowerShell 5.1Windows随系统内置
PowerShell 7.x跨平台开源,基于 .NET Core

第一个命令

Write-Host "Hello, PowerShell!"
# 输出: Hello, PowerShell!

学习路线

  1. 安装与核心概念
  2. Cmdlet 基础与文件/进程/网络管理
  3. 管道与过滤、变量作用域
  4. 控制结构与脚本编写
  5. 实际应用场景

PowerShell 简介

PowerShell 简介

1. 什么是 PowerShell

PowerShell 是一个跨平台的任务自动化和配置管理框架,由命令行 Shell 和关联的脚本语言组成。最初于 2006 年随 Windows 发布,2016 年开源并支持 Linux/macOS。

2. 为什么重要

  • 替代传统 cmd,更强大且一致
  • 面向对象输出,管道处理优雅
  • 可管理本地与远程系统(WinRM/SSH)
  • 与 Azure、Office 365、Exchange 深度集成

3. Cmdlet 命名规范

# 动词-名词 结构
Get-Process        # 获取进程
Stop-Service       # 停止服务
Set-ItemProperty   # 设置属性
New-Item           # 创建项目
Remove-Item        # 删除项目

# 常见动词
Get 获取 | Set 设置 | New 创建
Remove 删除 | Start 启动 | Stop 停止
Restart 重启 | Test 测试 | Convert 转换

4. 对象输出示例

# cmd 只能输出文本
# PowerShell 输出对象,可直接访问属性
Get-Process -Name "explorer" | Select-Object Name, CPU, WorkingSet

5. 与 cmd 对比

# cmd 删除目录
rmdir /s /q folder

# PowerShell 删除目录
Remove-Item -Path folder -Recurse -Force

PowerShell 安装

PowerShell 安装

1. Windows 安装

# Windows PowerShell 5.1 已内置
# 安装 PowerShell 7(跨平台版)

# 方法一:winget
winget install --id Microsoft.PowerShell

# 方法二:MSI 安装包
# 从 GitHub Releases 下载 .msi

# 方法三:Microsoft Store
# 搜索 "PowerShell" 安装

2. macOS 安装

# Homebrew
brew install powershell

# 或从 GitHub Releases 下载 pkg
# 启动
pwsh

3. Linux 安装(Ubuntu)

# 方式一:snap
snap install powershell --classic

# 方式二:apt
wget -q https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install -y powershell

4. 验证安装

$PSVersionTable
# 显示版本信息

pwsh --version
# PowerShell 7.4.0

5. 执行策略

# Windows 默认禁止执行脚本,需调整策略
Get-ExecutionPolicy                 # 查看策略
Set-ExecutionPolicy RemoteSigned    # 允许本地脚本,远程需签名
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

# 绕过单次执行
powershell -ExecutionPolicy Bypass -File script.ps1

6. VS Code 开发环境

# 安装 PowerShell 扩展
# 配置终端为 pwsh
# 支持智能提示、调试、格式化

PowerShell 核心概念

PowerShell 核心概念

1. 管道(Pipeline)

# 对象在命令间流动
Get-Process | Where-Object { $_.CPU -gt 100 } | Sort-Object CPU -Descending | Select-Object -First 5

2. 变量

# 变量以 $ 开头
$name = "Alice"
$count = 42
$items = @("a", "b", "c")      # 数组
$config = @{ host = "localhost"; port = 8080 }  # 哈希表

# 读取用户输入
$input = Read-Host "请输入"

# 环境变量
$env:PATH
$env:USERNAME

3. 对象与属性

# 所有输出都是对象
$proc = Get-Process -Name "powershell"
$proc.Name
$proc.Id

# 查看对象成员
$proc | Get-Member

4. 类型系统

[int]      # 整数
[string]   # 字符串
[bool]     # 布尔
[array]    # 数组
[hashtable]# 哈希表
[datetime] # 日期时间

[int]"42"          # 字符串转数字
[string]42         # 数字转字符串
[datetime]"2026-08-18"

5. 别名与函数

# 常用别名
Get-ChildItem   → ls / dir
Copy-Item       → cp
Move-Item       → mv
Remove-Item     → rm
Write-Host      → echo

# 查看别名
Get-Alias

PowerShell 入门指南

PowerShell 入门指南

1. 常用命令初体验

Get-Date                    # 当前日期时间
Get-Location                # 当前目录
Set-Location C:\Users       # 切换目录
Get-ChildItem               # 列出文件
Get-Help Get-Process        # 查看帮助
Get-Command -Name "*Process*"   # 查找命令

2. 查看帮助系统

# 帮助系统
Get-Help Get-Process            # 基础帮助
Get-Help Get-Process -Examples  # 示例
Get-Help Get-Process -Detailed  # 详细帮助

# 在线帮助
Get-Help Get-Process -Online

3. 输出与格式化

Write-Output "普通输出"
Write-Host "直接显示(绿色)" -ForegroundColor Green
Write-Warning "警告信息"
Write-Error "错误信息"
Write-Verbose "详细输出" -Verbose

# 格式化表格/列表
Get-Process | Format-Table Name, CPU -AutoSize
Get-Process | Format-List Name, Id, CPU

4. 读取与导出

# 导出 CSV
Get-Process | Export-Csv processes.csv -NoTypeInformation

# 导出 JSON
Get-Process | ConvertTo-Json | Out-File processes.json

# 读取 CSV
Import-Csv processes.csv

5. 交互式操作

# 确认对话框
if (Read-Host "继续吗?(y/n)") -eq "y" {
    Write-Host "继续执行"
}

# 暂停
Pause

PowerShell 面向对象的命令行

PowerShell 面向对象的命令行

1. 对象输出理念

传统 Shell 输出文本,PowerShell 输出 .NET 对象。对象携带属性与方法,管道传递的是对象引用而非字符串。

# 传统文本需要解析
# ps aux | grep xxx

# PowerShell 直接筛选属性
Get-Process | Where-Object { $_.ProcessName -like "*chrome*" }

2. 属性与 Select-Object

# 选择对象属性
Get-Process | Select-Object Name, Id, CPU, WorkingSet

# 计算属性
Get-Process | Select-Object Name, @{ Name="MemMB"; Expression={ [math]::Round($_.WorkingSet/1MB, 2) } }

3. 方法与调用

# 对象方法
$file = Get-Item "C:	emp.txt"
$file.FullName
$file.Length
$file.CopyTo("C:	emp.txt")

# 字符串方法
"hello world".ToUpper()
"abc".Replace("a", "x")
"1,2,3".Split(",")

4. 管道中的对象

# 每个管道对象都是上一步输出
Get-Process | ForEach-Object {
    "{0} 占用内存 {1} MB" -f $_.Name, [math]::Round($_.WorkingSet/1MB, 1)
}

# 分组统计
Get-Service | Group-Object Status | Select-Object Name, Count

5. 创建对象

# 自定义对象
$user = [PSCustomObject]@{
    Name = "张三"
    Age  = 30
    City = "北京"
}
$user.Name

# 从表转换对象
[pscustomobject]@{ A = 1; B = 2 }

PowerShell Cmdlet 基础

PowerShell Cmdlet 基础

1. Cmdlet 结构

# 动词-名词 + 参数
Get-Process -Name "chrome" -ErrorAction SilentlyContinue

# 常见参数
-Path       路径
-Filter     通配符过滤
-Recurse    递归
-Force      强制
-ErrorAction 错误处理(Stop/Continue/SilentlyContinue)
-Verbose    显示详细输出

2. 核心 Cmdlet

# 获取信息
Get-Process       # 进程
Get-Service       # 服务
Get-Item / Get-ChildItem   # 文件系统
Get-Content       # 读取文件内容
Get-Date          # 日期
Get-WmiObject     # WMI 信息

# 操作
New-Item          # 新建
Set-Content       # 写入文件
Add-Content       # 追加
Copy-Item / Move-Item / Rename-Item
Remove-Item       # 删除
Start-Process     # 启动进程
Start-Service / Stop-Service / Restart-Service

3. 参数绑定

# 位置参数
Get-ChildItem C:\Windows

# 命名参数
Get-ChildItem -Path C:\Windows -Filter "*.log"

# 开关参数
Get-ChildItem -Recurse -Force

4. 通配符

Get-ChildItem *.txt            # 所有 txt
Get-Service *sql*              # 含 sql 的服务
Get-ChildItem a?.txt           # 单字符通配
Get-ChildItem [a-c]*.txt       # 字符范围

5. ErrorAction 与错误处理

Get-Process -Name "不存在" -ErrorAction SilentlyContinue
# 不报错,静默

Get-Process -Name "不存在" -ErrorAction Stop
# 抛出终止错误,可用 try/catch 捕获

try {
    Get-Process -Name "notepad" -ErrorAction Stop
} catch {
    Write-Host "捕获错误: $_"
}

PowerShell 基本语法

PowerShell 基本语法

1. 运算符

# 算术
1 + 2; 5 - 3; 4 * 2; 10 / 3
10 % 3        # 取余
2 -pow 10     # 幂

# 比较(-eq 等,不区分大小写;区分加 c 前缀)
5 -eq 5        # true
5 -ne 3        # true
5 -gt 3        # 大于
5 -ge 5        # 大于等于
3 -lt 5        # 小于
5 -le 5        # 小于等于

# 字符串比较
"abc" -like "a*"      # 通配符匹配
"abc" -match "^a"     # 正则匹配
"a" -in @("a","b")    # 在集合中
$null -eq $var        # 判空

# 逻辑
$true -and $false
$true -or $false
-not $true

2. 条件语句

if ($age -ge 18) {
    Write-Host "成年"
} elseif ($age -ge 12) {
    Write-Host "青少年"
} else {
    Write-Host "未成年"
}

# switch
switch ($fruit) {
    "苹果" { "红色" }
    "香蕉" { "黄色" }
    default { "未知" }
}

3. 循环

# for
for ($i = 0; $i -lt 5; $i++) {
    Write-Host $i
}

# foreach 语句
foreach ($item in @("a","b","c")) {
    Write-Host $item
}

# 管道 ForEach-Object
@(1,2,3) | ForEach-Object { $_ * 2 }

# while
$n = 0
while ($n -lt 3) { $n++; Write-Host $n }

# do-while
do { $n-- } while ($n -gt 0)

4. 注释

# 单行注释

<# 多行
注释 #>

# 帮助注释(脚本/函数开头)
<#
.SYNOPSIS
    脚本简述
.DESCRIPTION
    详细描述
.PARAMETER Path
    参数说明
.EXAMPLE
    .\script.ps1 -Path C:\temp
#>

Cmdlet 文件系统操作

Cmdlet 文件系统操作

1. 目录操作

# 创建目录
New-Item -ItemType Directory -Path "C:	emp\logs"
New-Item -ItemType Directory -Path "C:	emp","C:	emp"   # 批量

# 切换目录
Set-Location C:	emp
cd C:	emp        # 别名

# 查看目录
Get-ChildItem C:	emp
ls C:	emp

# 删除目录
Remove-Item C:	emp\logs -Recurse -Force

2. 文件操作

# 创建文件
New-Item -ItemType File -Path "C:	emp.txt"

# 写入内容
Set-Content -Path "C:	emp.txt" -Value "第一行"
Add-Content -Path "C:	emp.txt" -Value "追加一行"

# 读取内容
Get-Content "C:	emp.txt"
# 批量读取行
$lines = Get-Content "C:	emp.txt"
foreach ($line in $lines) { Write-Host $line }

# 复制/移动/重命名
Copy-Item "a.txt" "b.txt" -Force
Move-Item "b.txt" "C:	empak"
Rename-Item "a.txt" "renamed.txt"

# 删除
Remove-Item "renamed.txt" -Force

3. 文件信息

$f = Get-Item "C:	emp.txt"
$f.FullName      # 完整路径
$f.Length        # 大小(字节)
$f.LastWriteTime # 最后修改时间
$f.Attributes    # 属性

# 查找文件
Get-ChildItem C:\ -Recurse -Filter "*.log" -ErrorAction SilentlyContinue
Get-ChildItem C:	emp -Recurse | Where-Object { $_.Length -gt 10MB }

4. 文件内容处理

# 统计行数
(Get-Content "a.txt").Count

# 查找含关键字的行
Get-Content "a.txt" | Select-String "error"

# 替换并保存
(Get-Content "a.txt") -replace "旧值", "新值" | Set-Content "a.txt"

Cmdlet 进程和服务管理

Cmdlet 进程和服务管理

1. 进程管理

# 列出进程
Get-Process                       # 全部
Get-Process -Name "chrome"        # 按名称
Get-Process -Id 1234              # 按 PID

# 筛选高 CPU 进程
Get-Process | Where-Object { $_.CPU -gt 50 } | Sort-Object CPU -Descending

# 内存 Top5
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5 Name, WorkingSet

# 启动/停止进程
Start-Process notepad
Start-Process "C:	emppp.exe" -ArgumentList "-silent"
Stop-Process -Name "notepad" -Force
Stop-Process -Id 1234 -Force

# 等待进程退出
$p = Start-Process notepad -PassThru
$p.WaitForExit()

2. 服务管理

# 查看服务
Get-Service                       # 全部
Get-Service -Name "wuauserv"      # Windows Update 服务
Get-Service *sql*                 # 通配符

# 服务状态统计
Get-Service | Group-Object Status

# 操作服务
Start-Service -Name "wuauserv"
Stop-Service -Name "wuauserv"
Restart-Service -Name "wuauserv"
Set-Service -Name "wuauserv" -StartupType Automatic   # 设置开机自启

# 需要管理员权限的服务操作
# 启动管理员 PowerShell 执行

3. 远程管理

# WinRM 远程执行
Invoke-Command -ComputerName "server01" -ScriptBlock {
    Get-Process | Sort-Object CPU -Descending | Select-Object -First 3
}

# SSH 远程(Linux 目标)
ssh user@server "ps aux | head -10"

4. 计划任务

# 创建计划任务(需管理员)
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:	empackup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "02:00"
Register-ScheduledTask -TaskName "DailyBackup" -Action $action -Trigger $trigger

# 查看/删除
Get-ScheduledTask -TaskName "DailyBackup"
Unregister-ScheduledTask -TaskName "DailyBackup" -Confirm:$false

Cmdlet 网络与系统管理

Cmdlet 网络与系统管理

1. 网络测试

# 测试连通性(类似 ping)
Test-Connection -ComputerName "www.baidu.com" -Count 4

# 测试端口
Test-NetConnection -ComputerName "example.com" -Port 443
Test-NetConnection -ComputerName "192.168.1.1" -Port 3389 -InformationLevel Detailed

# 查看网络配置
Get-NetIPConfiguration
Get-NetIPAddress | Select-Object InterfaceAlias, IPAddress

# DNS 解析
Resolve-DnsName "www.baidu.com"

2. HTTP 请求

# GET 请求
$resp = Invoke-WebRequest -Uri "https://api.example.com/users"
$resp.StatusCode
$resp.Content

# 简写
Invoke-RestMethod -Uri "https://api.example.com/users" -Method Get

# POST 提交 JSON
$body = @{ name = "张三"; age = 30 } | ConvertTo-Json
Invoke-RestMethod -Uri "https://api.example.com/users" -Method Post -Body $body -ContentType "application/json"

# 带认证头
$headers = @{ Authorization = "Bearer token123" }
Invoke-RestMethod -Uri "https://api.example.com/data" -Headers $headers

3. 系统信息

# 系统信息
Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, TotalPhysicalMemory

# 磁盘
Get-PSDrive -PSProvider FileSystem
Get-Volume | Select-Object DriveLetter, FileSystemLabel, Size, SizeRemaining

# 磁盘使用率告警
Get-Volume | Where-Object { $_.SizeRemaining -lt 10GB }

# 系统时间与运行时长
Get-Date
(Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime

4. 事件日志

# 查看系统日志
Get-EventLog -LogName System -Newest 10

# 筛选错误事件
Get-EventLog -LogName Application -EntryType Error -Newest 20

# 查看 Windows 事件日志(新版)
Get-WinEvent -LogName Application -MaxEvents 10 | Select-Object TimeCreated, LevelDisplayName, Message

PowerShell 管道和过滤

PowerShell 管道和过滤

1. 管道基础

# 对象从左侧命令流向右侧命令
Get-Process | Stop-Process

# 管道配合常用命令
Get-ChildItem *.log | Remove-Item
Get-Content servers.txt | Test-Connection
"hello world" | Select-Object -First 1

2. Where-Object 过滤

# 过滤条件
Get-Process | Where-Object { $_.CPU -gt 10 }

# 多种比较
Get-Service | Where-Object { $_.Status -eq "Running" }
Get-ChildItem | Where-Object { $_.Length -gt 1MB -and $_.Extension -eq ".zip" }
Get-EventLog -LogName System | Where-Object { $_.EventID -eq 6006 }

# 简单语法(省略 $_.)
Get-Process | Where-Object CPU -gt 10
Get-Service | Where-Object Status -eq "Running"

3. ForEach-Object 处理

# 逐个处理
Get-ChildItem *.txt | ForEach-Object { $_.Name }

# 简写 %
Get-Process | % { $_.Name }

# 索引与统计
$files = Get-ChildItem
$files | ForEach-Object -Begin { $total = 0 } -Process { $total += $_.Length } -End { "总大小: $total 字节" }

4. Select-Object 选择

# 取前 N 个
Get-Process | Select-Object -First 5

# 取后 N 个
Get-Process | Select-Object -Last 3

# 跳过
Get-Process | Select-Object -Skip 5

# 选择属性
Get-Process | Select-Object Name, CPU

5. 排序与分组

# 排序
Get-Process | Sort-Object CPU -Descending
Get-ChildItem | Sort-Object Length -Descending

# 去重
Get-Service | Select-Object -Unique Status

# 分组统计
Get-Service | Group-Object Status | Select-Object Name, Count
Get-ChildItem | Group-Object Extension | Sort-Object Count -Descending

6. 复杂管道示例

# 找到内存占用最高的3个进程
Get-Process |
    Sort-Object WorkingSet -Descending |
    Select-Object -First 3 Name, @{N="Mem(MB)";E={[math]::Round($_.WorkingSet/1MB,1)}}

# 统计各扩展名文件数
Get-ChildItem -Recurse -File |
    Group-Object Extension |
    Sort-Object Count -Descending |
    Select-Object -First 5 Count, Name

PowerShell 变量和作用域

PowerShell 变量和作用域

1. 变量声明

# 变量以 $ 开头,不区分大小写
$name = "Alice"
$number = 42
$list = @(1, 2, 3)
$hash = @{ key1 = "value1"; key2 = "value2" }

# 只读变量
Set-Variable -Name "config" -Value "v1" -Option ReadOnly

# 删除变量
Remove-Variable -Name "name"
$name = $null   # 或置空

2. 变量类型

# 强制类型
[int]$port = 8080
[string]$hostname = "server01"
[bool]$enabled = $true
[datetime]$date = "2026-08-18"

# 类型转换
[int]"123"
[string](1 + 2)
[array]$items = "single"   # 单元素数组

# 自动变量
$PSVersionTable    # 版本信息
$PSScriptRoot      # 脚本所在目录
$PSCommandPath     # 脚本完整路径
$_                 # 管道当前对象
$args              # 脚本参数数组
$LASTEXITCODE      # 上次外部程序退出码
$true / $false     # 布尔常量
$null              # 空值

3. 环境变量与特殊变量

# 环境变量
$env:Path
$env:USERNAME
$env:COMPUTERNAME

# 设置环境变量(当前会话)
$env:MY_VAR = "hello"

# 永久设置
[Environment]::SetEnvironmentVariable("MY_VAR", "hello", "User")

4. 作用域

# 作用域类型
# Global 全局 | Script 脚本 | Local 本地(函数内)
# 默认变量优先级:Local > Script > Global

$global:g = "全局变量"
$script:s = "脚本变量"
$local:l = "本地变量"

function Test-Scope {
    $local:inside = "函数内变量"
    Write-Host "函数内: $inside"
    Write-Host "访问全局: $global:g"
}
Test-Scope
# 函数外访问 $inside 会失败

5. 变量命令

Get-Variable          # 列出所有变量
Get-Variable -Name "name"
Set-Variable -Name "x" -Value 10
Clear-Variable -Name "x"     # 清空
Remove-Variable -Name "x"    # 删除

PowerShell 控制结构

PowerShell 控制结构

1. 条件分支

# if/elseif/else
$score = 85
if ($score -ge 90)      { "优秀" }
elseif ($score -ge 80)  { "良好" }
elseif ($score -ge 60)  { "及格" }
else                    { "不及格" }

# switch(支持正则与通配)
switch -Regex ($input) {
    "^\d+$"    { "数字" }
    "^[a-z]+$"  { "小写字母" }
    default     { "其他" }
}

2. 循环结构

# for
for ($i = 0; $i -lt 5; $i++) { $i }

# foreach
foreach ($item in 1..5) { $item * 2 }

# ForEach-Object(管道)
1..5 | ForEach-Object { $_ * 3 }

# while
$n = 0
while ($n -lt 3) { $n++ }

# do-while(至少执行一次)
do { $n-- } while ($n -gt 0)

# break 与 continue
foreach ($i in 1..10) {
    if ($i -eq 3) { continue }
    if ($i -eq 8) { break }
    Write-Host $i
}

3. 函数定义

function Get-Square {
    param([int]$num)
    return $num * $num
}

# 调用
Get-Square -num 5    # 25

# 带默认参数与管道输入
function Add-Prefix {
    param(
        [string]$Prefix = "[默认]",
        [Parameter(ValueFromPipeline)]$Value
    )
    process { "$Prefix$Value" }
}
"a", "b" | Add-Prefix -Prefix ">>"

4. 异常处理

# try/catch/finally
try {
    Get-Item "C:\不存在.txt" -ErrorAction Stop
} catch {
    Write-Host "捕获异常: $($_.Exception.Message)"
} finally {
    Write-Host "无论是否出错都会执行"
}

# 抛出异常
if (-not (Test-Path $path)) {
    throw "路径不存在: $path"
}

# 特定异常类型
catch [System.IO.FileNotFoundException] {
    "文件未找到"
}
catch {
    "其他错误"
}

5. 流程控制最佳实践

  • 条件里用 -eq 而非 ==
  • 判空用 $null -eq $var(避免误判)
  • 函数输出所有命令的结果,注意用 Write-Output 或赋值
  • 用 param() 声明参数,配合 [CmdletBinding()] 增强

PowerShell 脚本编写

PowerShell 脚本编写

1. 脚本文件

# 脚本扩展名 .ps1
# 创建 backup.ps1

# 头部帮助
<#
.SYNOPSIS
    备份指定目录
.DESCRIPTION
    将源目录压缩为 zip 到备份目录
.PARAMETER Source
    源目录路径
.PARAMETER Dest
    备份目录
.EXAMPLE
    .\backup.ps1 -Source C:\data -Dest D:\backup
#>
param(
    [Parameter(Mandatory=$true)]
    [string]$Source,

    [string]$Dest = "C:\backup"
)

if (-not (Test-Path $Source)) {
    throw "源目录不存在: $Source"
}
if (-not (Test-Path $Dest)) {
    New-Item -ItemType Directory -Path $Dest -Force | Out-Null
}

$stamp = Get-Date -Format "yyyyMMdd_HHmmss"
$zip = Join-Path $Dest "backup_$stamp.zip"
Compress-Archive -Path $Source -DestinationPath $zip
Write-Host "备份完成: $zip"

2. 参数处理

param(
    [Parameter(Mandatory=$true)]        # 必填
    [string]$Name,

    [ValidatePattern("^[a-z]+$")]       # 正则校验
    [string]$Code,

    [ValidateRange(1, 100)]             # 数值范围
    [int]$Level = 5,

    [ValidateSet("dev", "prod")]        # 枚举值
    [string]$Env = "dev",

    [switch]$Force                      # 开关参数
)

if ($Force) { Write-Host "强制模式" }

3. 模块化

# 函数导出(psm1 模块文件)
function Get-Hello { "Hello" }
Export-ModuleMember -Function Get-Hello

# 导入模块
Import-Module .\myModule.psm1
Get-Hello

# 点源脚本(共享函数)
. .\common.ps1
Use-CommonFunction

4. 错误处理与日志

# 全局错误处理
$ErrorActionPreference = "Stop"

# 日志函数
function Write-Log {
    param([string]$Message)
    $time = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    Add-Content -Path "app.log" -Value "[$time] $Message"
}

try {
    Write-Log "开始处理"
    # 业务逻辑
    Write-Log "处理完成"
} catch {
    Write-Log "出错: $($_.Exception.Message)"
    exit 1
}

5. 调用外部命令与退出码

# 调用外部程序
& "C:\Program Files\app.exe" --version
$LASTEXITCODE     # 退出码

# 捕获输出
$output = & ping 127.0.0.1
$output | Select-Object -Last 3

# 执行策略绕过运行
powershell -ExecutionPolicy Bypass -File .\script.ps1

PowerShell 实际应用

PowerShell 实际应用

1. 批量重命名文件

Get-ChildItem "C:\temp" -Filter "*.jpg" |
    ForEach-Object {
        $newName = "photo_" + $_.Name
        Rename-Item $_.FullName -NewName $newName
    }

# 加日期前缀
Get-ChildItem *.log |
    ForEach-Object {
        $prefix = Get-Date -Format "yyyyMMdd"
        Rename-Item $_ -NewName "$prefix`_$($_.Name)"
    }

2. 监控磁盘并告警

# 磁盘剩余低于 10% 时发邮件
$threshold = 10
$volumes = Get-Volume | Where-Object { $_.DriveLetter }

foreach ($v in $volumes) {
    $freePct = [math]::Round($v.SizeRemaining / $v.Size * 100, 1)
    if ($freePct -lt $threshold) {
        Send-MailMessage -To "admin@example.com"
            -Subject "磁盘告警: $($v.DriveLetter): 剩余 $freePct%"
            -From "monitor@example.com"
            -SmtpServer "smtp.example.com"
    }
}

3. 定期清理临时文件

# 删除 7 天前的临时文件
$cutoff = (Get-Date).AddDays(-7)
Get-ChildItem "C:\temp" -Recurse -File |
    Where-Object { $_.LastWriteTime -lt $cutoff } |
    Remove-Item -Force -Verbose

# 清理日志(保留最近 20 个)
Get-ChildItem "C:\logs\*.log" |
    Sort-Object LastWriteTime -Descending |
    Select-Object -Skip 20 |
    Remove-Item -Force

4. 批量检查端口

$servers = @("web01", "web02", "db01")
foreach ($s in $servers) {
    $result = Test-NetConnection -ComputerName $s -Port 443 -WarningAction SilentlyContinue
    "{0}: {1}" -f $s, $(if ($result.TcpTestSucceeded) { "OK" } else { "FAIL" })
}

5. 配置文件读取

# 读取 JSON 配置
$config = Get-Content "config.json" | ConvertFrom-Json
$config.host
$config.port

# 遍历 CSV
Import-Csv "users.csv" | ForEach-Object {
    New-Item -ItemType Directory -Path "C:\home\$($_.username)" -Force
}

# 计划任务执行
# 配合任务计划程序,定时运行 .ps1 即可实现全自动化

PowerShell 总结与资源

PowerShell 总结与资源

1. 核心要点回顾

  • 面向对象:命令输出对象,管道传递对象,这是与 cmd/bash 的本质区别
  • Cmdlet 规范:动词-名词命名,参数统一,可预测
  • 强大管道:Where-Object 过滤、ForEach-Object 处理、Select-Object 投影
  • 脚本能力:变量、函数、控制结构、异常处理、模块化
  • 系统集成:进程、服务、网络、磁盘、事件日志全覆盖

2. 常用命令速查

场景命令
文件Get/Set/Add/New/Copy/Move/Remove-Item
进程Get/Start/Stop-Process
服务Get/Start/Stop/Restart-Service
网络Test-Connection / Test-NetConnection
HTTPInvoke-WebRequest / Invoke-RestMethod
系统Get-ComputerInfo / Get-CimInstance
帮助Get-Help / Get-Command / Get-Alias

3. 最佳实践

  • 脚本开头用 param() 声明参数并加注释帮助
  • 开启 $ErrorActionPreference = "Stop" 及时暴露错误
  • 敏感信息用 Read-Host -AsSecureString 或 SecretManagement 模块
  • 写日志、处理退出码,便于排障
  • 复用代码封装为函数与模块

4. 学习资源

  • 微软官方文档:learn.microsoft.com/powershell
  • PowerShell 开源仓库:github.com/PowerShell/PowerShell
  • 模块库:PowerShell Gallery(psgallery)
  • 社区:Reddit r/PowerShell、Stack Overflow

5. 进阶方向

  • DSC:Desired State Configuration 配置管理
  • 自动化测试:Pester 测试框架
  • 云管理:Azure PowerShell、AWS Tools
  • 安全:安全审计脚本、事件响应自动化

至此 PowerShell 教程全部介绍完毕,建议在真实环境中动手实践,用脚本解决实际问题,进步最快。

第 1 / 17 节