PowerShell 为什么叫“面向对象的命令行”?
—— 这句话是 PowerShell 和 cmd、bash、zsh 的最大分水岭,掌握它你就真正“开窍”了。
一张图看懂根本区别
| 工具 | 管道里流动的是什么? | 后果(举例:找 CPU > 1000 的进程) |
|---|---|---|
| cmd.exe | 纯文本 | tasklist | findstr "1000" → 根本不知道哪一列是 CPU |
| bash/zsh | 纯文本 | ps -aux | awk '$3>10' → 靠列号硬解析,换机器就炸 |
| PowerShell | 完整的 .NET 对象 | Get-Process | Where CPU -gt 1000 → CPU 是真正的数字属性,永远不会错 |
核心真理:PowerShell 输出的每一行都是一个对象
# 这条命令输出的不是文字,而是对象!
Get-Process notepad
你看到的是表格,但 PowerShell 内部其实是这样的对象:
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
123 15 25000 35000 8.32 9876 1 notepad
这个对象真实类型是:
(Get-Process notepad)[0] | Get-Member
# 你会看到它其实是 System.Diagnostics.Process 类型
# 拥有 70+ 个属性和方法:.Name, .CPU, .StartTime, .Kill(), .WaitForExit() ...
实战:面向对象带来的降维打击(5 个真实例子)
# 1. 直接点属性,根本不需要解析文本
Get-Process | Where-Object {$_.CPU -gt 500}
# 2. 直接调用对象的方法(杀进程、刷新资源管理器)
(Get-Process explorer).Kill() # 秒关资源管理器
(Get-Process explorer).Refresh() # 刷新内存统计
# 3. 计算属性(管道中随时加新列)
Get-ChildItem C:\Windows\System32 *.dll |
Select Name,
@{Name="大小MB"; Expression={ "{0:N2}" -f ($_.Length/1MB) }},
LastWriteTime
# 4. 创建自定义对象(报表神器)
$report = @()
$report += [pscustomobject]@{
电脑名 = $env:COMPUTERNAME
开机时间 = (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
空闲内存GB = [math]::Round((Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory/1MB*1000/1GB,2)
}
$report | Export-Csv "C:\健康报告.csv" -NoTypeInformation -Encoding UTF8
# 5. 真正的“面向对象”玩法:链式调用 + 管道对象不丢失
# 找出占用内存最多的 5 个进程,然后杀掉最老的那个
Get-Process |
Sort-Object WS -Descending |
Select -First 5 |
Sort-Object StartTime | # 再按启动时间排序
Select -First 1 | # 取最老的
Stop-Process -Force # 直接调用 .Kill() 方法
面向对象带来的 5 个超级能力
| 能力 | 传统 Shell 做不到的事 |
|---|---|
| 属性精确过滤 | Where Handles -gt 1000(永远不会因为列顺序错) |
| 随时计算新属性 | Select *, @{Name="年龄";Expression={(Get-Date)-$_.StartTime}} |
| 直接调用方法 | .Kill()、.Start()、.ExportToExcel() |
| 类型自动转换 | [datetime]"2025-01-01" 自动变成日期对象 |
| 自定义对象 + Export-Csv | 一行代码生成完美 Excel 报表 |
30 秒验证你是否真的理解了“面向对象”
把下面这行代码复制粘贴运行,看看你能不能立刻读懂它在干什么:
Get-Service |
Where Status -eq 'Running' |
Select Name, DisplayName,
@{Name="启动类型";Expression={ $_.StartType }},
@{Name="可停止";Expression={ $_.CanStop }} |
Sort CanStop |
Export-Csv "运行中服务.csv" -NoTypeInformation -Encoding UTF8
如果你能立刻说出:
“这行代码把所有正在运行的服务导出成 CSV,额外加了两列:启动类型 + 是否允许停止,最后按‘可停止’排序”
恭喜你!你已经完全掌握了 PowerShell 的“面向对象”精髓!
现在告诉我:
你想马上看一个“面向对象”写出来的完整自动化脚本(比如自动巡检 100 台电脑并生成 Excel 报告)吗?
我可以给你一个 50 行代码干翻传统 bat 500 行的案例!