PowerShell 控制结构

PowerShell 的控制结构(流程控制)非常丰富、统一、强大,而且几乎全部都“对象友好”,写起来比传统批处理/Bash 爽太多。

下面按实际使用频率和重要性,从高到低系统梳理一遍,配上最实用的写法和防坑技巧。

1. if / elseif / else(最常用)

$age = 18

if ($age -lt 13) {
    "儿童"
}
elseif ($age -lt 18) {
    "青少年"
}
elseif ($age -lt 60) {
    "成年人"
}
else {
    "老年人"
}

# 推荐写法:一行写法(很常见)
if (Test-Path $path) { Remove-Item $path -Force }

常见比较运算符(区分大小写!)

类型相等不等大于小于包含匹配正则类型判断
区分大小写-eq-ne-gt-lt-contains-match-is
不区分大小写-ieq-ine-igt-ilt-icontains-imatch-isnot
正则专用-ceq-cne-cgt-clt-in-inotmatch-like / -notlike
-notin-cmatch-ilike

示例:

if ($env:USERNAME -ceq "ADMIN") { "大小写精确匹配" }
if ($list -contains $item)       { "集合包含判断" }
if ($path -like "*\Windows\*")   { "通配符匹配" }
if ($text -match "^\d{11}$")     { "正则匹配手机号" }

2. switch(PowerShell 最强大、最好用的控制结构)

基本语法(支持字符串、数字、数组、文件、甚至对象集合!)

switch ($os)
{
    "Windows" { "是 Windows" }
    "Linux"   { "是 Linux" }
    "Darwin"  { "是 macOS" }
    default   { "未知系统" }
}

超实用高级特性(其他语言基本没有)

# 1. 支持正则匹配(加 -regex)
switch -Regex ($line)
{
    '^\d{4}-\d{2}-\d{2}' { "这是日期行" }
    'ERROR|FAIL'         { "错误日志" }
    'WARNING'            { "警告日志" }
}

# 2. 支持通配符(-Wildcard)
switch -Wildcard ($file.Extension)
{
    *.exe  { "可执行文件" }
    *.dll  { "动态库" }
    *.ps1  { "PowerShell 脚本" }
}

# 3. 支持文件读取(最牛!一行处理整个文件)
switch -File "C:\logs\app.log"
{
    {$_ -match "ERROR"}   { Write-Host "发现错误: $_" -ForegroundColor Red }
    {$_ -match "WARN"}    { Write-Host "警告: $_" -ForegroundColor Yellow }
    default               { Write-Debug "普通日志: $_" }
}

# 4. 支持集合自动展开(对数组直接遍历)
$processes = Get-Process
switch ($processes)
{
    {$_.CPU -gt 1000} { "$($_.Name) CPU 占用过高" }
    {$_.Handles -gt 1000} { "$($_.Name) 句柄泄漏嫌疑" }
}

switch 最佳参数组合(背下来就无敌)

switch -Regex -File $logPath { ... }          # 处理大日志最快
switch -CaseSensitive ($choice) { ... }       # 区分大小写
switch -Wildcard -File $list { ... }

3. for 循环(用得少,但某些场景必须)

# 经典计数循环
for ($i = 1; $i -le 10; $i++) {
    Write-Progress -Activity "处理中" -PercentComplete ($i*10)
    Start-Sleep -Milliseconds 300
}

# 修改数组时必须用传统 for(foreach 会报错)
$array = 1..5
for ($i=0; $i -lt $array.Count; $i++) {
    $array[$i] *= 10
}

4. foreach(PowerShell 里最常用循环)

# 方式1:最快(推荐)
foreach ($file in $files) {
    $file.Name
}

# 方式2:管道方式(最常见,但比上面慢 5-50 倍)
$files | ForEach-Object { $_.Name }

# 方式3:别名(最常用写法)
Get-ChildItem | % { $_.FullName }

# 方式4:PS7+ 超快新语法(推荐大集合)
$files.ForEach{ $_.Length }

性能排序(10万条数据)

$list = 1..100000

# 最快:foreach 语句
foreach ($i in $list) { $null }

# 次快:.ForEach() 方法(PS7+)
$list.ForEach{ $null }

# 中等:ForEach-Object
$list | ForEach-Object { $null }

# 最慢:ForEach-Object 别名 %
$list | % { $null }

5. while / do-while / do-until

# while(先判断后执行)
while ($i -lt 10) {
    $i++
}

# do-while(至少执行一次)
do {
    $input = Read-Host "输入 q 退出"
} while ($input -ne 'q')

# do-until(直到条件为真才停)
$num = 0
do {
    $

num = Get-Random -Maximum 100
“随机数: $num”
} until ($num -eq 77)

### 6. break / continue / return / exit 的区别(常被混淆)

| 关键字    | 作用范围                     | 常用场景                                 |
|-----------|------------------------------|------------------------------------------|
| break     | 跳出当前循环(for/switch/while)| switch 中跳到 default 后 break          |
| continue  | 跳过本次循环,进入下一次      | foreach 里跳过某些文件                   |
| return    | 立即返回函数/脚本的结果       | 函数提前返回                             |
| exit      | 立即退出整个 PowerShell 进程  | 脚本验证失败直接终止                     |
| throw     | 抛出终止性错误                | 参数校验失败                             |

示例:

powershell
1..100 | ForEach-Object {
if ($_ % 15 -eq 0) { return “找到 15 的倍数: $_” } # 只返回第一个
if ($_ % 3 -eq 0) { continue } # 跳过 3 的倍数
}

### 7. try / catch / finally(异常处理)

powershell
try {
Get-Item “C:\不存在的文件.txt” -ErrorAction Stop
}
catch [System.IO.FileNotFoundException] {
“文件真的没找到!”
}
catch {
“其他错误: $($_.Exception.Message)”
}
finally {
“无论如何都会执行的清理代码”
}
“`

必知技巧

  • 只有加了 -ErrorAction Stop$ErrorActionPreference = 'Stop' 才会进入 catch
  • $_.Exception$_.TargetObject$_.InvocationInfo 是调试神器

8. 终极总结:PowerShell 控制结构优先级口诀

  1. 能用 switch 绝不用 if(特别是处理字符串、日志、正则时)
  2. 能用 foreach 语句 绝不用 ForEach-Object(性能差太多)
  3. 99% 的循环用 foreach 或 .ForEach() 就够了
  4. 能用管道就用管道,管道才是 PowerShell 的灵魂
  5. 参数校验失败直接 throw,配合 try/catch 最优雅
  6. 永远记得 -ErrorAction Stop 才能 catch

把上面这些吃透,你写的 PowerShell 脚本就从“能跑”进化到“专业级、又快又优雅”。

有任何控制结构相关的代码想优化或重构,随时贴出来,我帮你改成最 PowerShell 味的写法!

文章已创建 2965

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部