1. PowerShell 概述

PowerShell 是由微软开发的一种跨平台任务自动化和配置管理框架,由命令行 Shell 和脚本语言组成。它基于 .NET 框架,可以运行在 Windows、macOS 和 Linux 系统上。PowerShell 的强大之处在于其能够访问和管理系统的所有资源,包括文件系统、注册表、网络等。

**PowerShell 通过 cmdlet(发音为 “command-let”)来执行任务。**每个 cmdlet 通常由一个动词和一个名词组成,例如 Get-Process 用于获取进程信息。PowerShell 还支持面向对象的管道(Pipeline),允许 cmdlet 之间传递对象,而不仅仅是文本。

这也是它和 Unix Shell 最大的差异:Bash 擅长把文本流串起来,PowerShell 擅长把结构化对象传下去。做 Windows 管理、Microsoft 生态自动化、跨平台运维脚本时,PowerShell 不是“另一个 shell”,而是一套围绕对象和系统 API 组织的自动化接口。

2. 与其他 Shell 对比

比较维度PowerShellCMDBashZsh
平台支持跨平台(Windows, Mac, Linux)WindowsUnix 系统(Linux, Mac)Unix 系统(Linux, Mac)
开发公司微软微软GNU开源社区
对象模型面向对象,操作 .NET 对象基于字符串处理基于字符串处理基于字符串处理
管道机制支持对象管道不支持支持字符串管道支持字符串管道
脚本扩展名.ps1.bat, .cmd.sh.zsh
主要用途系统管理、自动化脚本简单任务自动化、批处理系统管理、自动化脚本、服务器管理系统管理、自动化脚本、服务器管理
交互界面图形界面(PowerShell ISE, VS Code)无图形界面无图形界面无图形界面
错误处理高级错误处理机制(try/catch)简单的错误处理(if errorlevel)基本错误处理基本错误处理
模块系统丰富的模块和包管理系统(PSGallery)无模块系统基于文件和库基于文件和库
脚本调试强大的调试工具(断点、变量监视)无直接调试工具基本调试工具(set -x, trap)基本调试工具(set -x, trap)
命令别名支持丰富的命令别名支持少量命令别名支持命令别名支持强大的命令别名(包括 Bash 支持的所有别名)
扩展性高度扩展性,通过 .NET 库和第三方模块低扩展性中等扩展性,通过脚本和第三方工具高度扩展性,通过插件系统
内置命令丰富的内置 cmdlet 和函数基本的内置命令丰富的内置命令丰富的内置命令
学习曲线相对陡峭,需要了解 .NET 对象模型平缓,易于上手中等,需要了解 Unix 系统和命令中等,需要了解 Unix 系统和命令
文档支持强大的内置帮助系统(Get-Help)基本的帮助命令(help, /?)丰富的在线文档和社区支持丰富的在线文档和社区支持
社区支持活跃的官方和社区支持基本的官方和社区支持广泛的社区支持广泛的社区支持

3. 环境入口

PowerShell 7 之后已经是跨平台工具,命令入口通常是 pwsh。Windows 管理场景仍然最常见,macOS/Linux 上则更适合处理 Microsoft 云服务、跨平台脚本和对象化数据管道。

Update-Help 可以更新本地帮助文档;执行策略(如 RemoteSigned)影响脚本能否运行。执行策略不是完整安全边界,只是误执行脚本的一层防护,真正的边界仍然是脚本来源、签名、权限和审计。

4. Cmdlet 命名规范

**PowerShell 的 cmdlet 以 “动词 - 名词” 形式命名,动词描述动作,名词描述操作对象。**这种规范让命令可搜索、可补全,也让脚本更接近自然语言。例如:

Get-Process   # 获取当前运行的进程
Set-Location  # 设置当前工作目录

常用动词

动词用途说明示例
Get获取信息或对象Get-Process 获取进程信息
Set设置或配置对象Set-Location 设置工作目录
New创建新的对象New-Item 创建文件或目录
Remove删除对象Remove-Item 删除文件或目录
Start启动操作或进程Start-Process 启动进程
Stop停止操作或进程Stop-Process 停止进程
Test测试或验证操作Test-Connection 测试网络连接
Export导出数据Export-Csv 导出到 CSV 文件
Import导入数据Import-Csv 从 CSV 文件导入数据
Invoke执行操作Invoke-Command 执行命令

5. 管道与对象流

PowerShell 的管道(Pipeline)允许将一个 cmdlet 的输出直接传递给下一个 cmdlet 作为输入。与 Unix Shell 不同,PowerShell 管道传递的是对象而非纯文本,这使得数据处理更加直观和灵活。

# 获取所有进程,筛选出 CPU 使用率大于 100 的进程
 
Get-Process | Where-Object { $_.CPU -gt 100 }

$_ 表示管道中的当前对象,后接属性名即可访问对象属性。判断一段 PowerShell 是否可靠,关键要看它是否在处理真实对象属性,而不是把格式化后的文本再拿来解析。

# 获取所有已停止的服务并重新启动它们
Get-Service | Where-Object { $_.Status -eq 'Stopped' } | Start-Service

6. 获取帮助

PowerShell 提供了强大的内置帮助系统,Get-Help 是学习和查找 cmdlet 详细信息的最佳方式:

Get-Help Get-Process

使用 Update-Help 更新本地帮助文件以获取最新文档:

Update-Help

7. 变量与数据类型

变量以 $ 符号开头,PowerShell 变量是动态类型的,无需提前声明类型:

$name = "John"
$age = 30
$fruits = @("Apple", "Banana", "Cherry")
 
Write-Output "Name: $name, Age: $age"

数据类型

数据类型描述示例
字符串(String)文本数据$string = "Hello, World!"
整数(Integer)整数型数值$integer = 42
浮点数(Float)浮点型数值$float = 3.14
数组(Array)有序集合$array = @(1, 2, 3, 4, 5)
哈希表(Hashtable)键值对集合$hashtable = @{ Name = "Alice"; Age = 25 }

8. 运算符

算术运算符

运算符描述示例
+加法$a + $b
-减法$a - $b
*乘法$a * $b
/除法$a / $b
%取模(余数)$a % $b

比较运算符

运算符描述示例
-eq等于$a -eq $b
-ne不等于$a -ne $b
-gt大于$a -gt $b
-ge大于或等于$a -ge $b
-lt小于$a -lt $b
-le小于或等于$a -le $b

逻辑运算符

运算符描述示例
-and$a -and $b
-or$a -or $b
-not-not $a

特殊运算符

运算符描述示例
-match正则表达式匹配$string -match "Power"
-like通配符匹配$string -like "Power*"
-contains检查数组是否包含元素$array -contains 3

9. 流程控制

条件语句

if / else

$a = 10
 
if ($a -gt 5) {
    Write-Output "a is greater than 5"
} elseif ($a -eq 5) {
    Write-Output "a is equal to 5"
} else {
    Write-Output "a is less than 5"
}

switch

$day = "Tuesday"
 
switch ($day) {
    "Monday"    { Write-Output "Today is Monday" }
    "Tuesday"   { Write-Output "Today is Tuesday" }
    "Wednesday" { Write-Output "Today is Wednesday" }
    default     { Write-Output "Today is another day" }
}

循环语句

for

for ($i = 0; $i -lt 5; $i++) {
    Write-Output "Iteration $i"
}

foreach

$array = @(1, 2, 3, 4, 5)
 
foreach ($item in $array) {
    Write-Output "Item: $item"
}

while

$i = 0
 
while ($i -lt 5) {
    Write-Output "Iteration $i"
    $i++
}

do-while

$i = 0
 
do {
    Write-Output "Iteration $i"
    $i++
} while ($i -lt 5)

10. 脚本编写基础

PowerShell 脚本文件的扩展名为 .ps1,可以用任何文本编辑器编写,然后在 PowerShell 中运行:

# hello.ps1
$name = "World"
Write-Output "Hello, $name!"
.\hello.ps1

脚本参数

通过 param 关键字定义参数,使脚本更灵活:

# greet.ps1
param (
    [string]$name = "World"
)
Write-Output "Hello, $name!"
.\greet.ps1 -name "Alice"

注释

使用 # 添加单行注释,使用 <# ... #> 添加多行注释:

# 这是单行注释
Write-Output "Single-line comment."
 
<#
这是多行注释
可以跨越多行
#>
Write-Output "Multi-line comment."

11. 使用原则

先看对象,再看显示Get-Process 在终端里显示成表格,但管道里传递的是对象。需要调试时,用 Get-Member 看属性和方法。

动词 - 名词是导航系统:不确定命令名时,先猜动词和对象,再用 Get-Command -Verb GetGet-Command -Noun Process 搜索。

执行策略不是安全银弹:不要运行来路不明的 .ps1;自动化脚本要保留来源、参数、日志和权限边界。

跨平台时避免 Windows 假设:路径分隔符、注册表、服务管理、换行和编码都可能不同。能用跨平台 cmdlet 就不要硬写平台细节。

对象流适合 Agent 和运维自动化:结构化对象比人类表格更稳定。需要给脚本或 Agent 消费时,优先输出对象、JSON 或明确结构,而不是漂亮文本。