最近老是用PowerShell,我记得以前都是用cmd的,PowerShell和CMD到底有什么区别,为什么现在大家都在推荐用PowerShell。说实话,刚开始接触Windows系统管理的时候,我也是一脸懵逼,黑框框不都一样吗?今天就跟大家聊聊这个话题,相信看完之后你会对这两个工具有个清晰的认识。
PowerShell究竟是什么东西
PowerShell说白了就是微软开发的一个命令行工具和脚本语言,但它可不是简单的命令行那么简单。我记得第一次用PowerShell的时候,输入Get-Process命令,看到那整齐的表格输出,当时就觉得这玩意儿不一般。
image-20250930213512332
跟传统的CMD比起来,PowerShell最大的特点就是面向对象。什么意思呢?就是说它处理的不是简单的文本,而是对象。比如你用Get-Service命令获取服务列表,返回的每一行都是一个完整的服务对象,包含了服务名、状态、启动类型等各种属性。
PowerShell基于.NET Framework构建,这意味着你可以直接调用.NET的各种类库和方法。有一次我需要批量处理Excel文件,用PowerShell直接调用Excel的COM对象,几行代码就搞定了,要是用CMD的话...想都不敢想。
现在PowerShell已经发展到7.x版本了,而且还支持跨平台,Linux和macOS上也能跑。微软把它开源了,这在以前是不可想象的事情。
image-20250930213601819
CMD的历史和局限性
CMD其实就是Command Prompt,它的历史可以追溯到DOS时代。说起来也挺有意思,我刚工作那会儿还在用Windows XP,那时候PowerShell还没普及,大家都是用CMD做各种操作。
CMD的工作方式很简单粗暴,就是执行命令然后返回文本。比如你用dir命令列出文件,返回的就是一堆文本信息,想要进一步处理的话就得用各种文本处理工具,非常麻烦。
我记得有一次需要统计某个目录下所有文件的大小,用CMD写了一个批处理脚本,各种for循环和字符串处理,写得我头都大了。后来用PowerShell的话,一行Get-ChildItem | Measure-Object -Property Length -Sum就搞定了。
CMD的另一个问题就是错误处理机制比较原始。很多时候命令执行失败了,你都不知道具体是什么原因,只能靠经验去猜测。
两者的核心区别在哪里
最根本的区别就是数据处理方式不同。CMD处理的是文本流,而PowerShell处理的是对象流。这听起来可能有点抽象,我举个具体例子。
假设你要获取系统中占用内存最多的前5个进程:
用CMD的话,你需要:
tasklist /fo csv | findstr /v "Image Name" | sort /r /+5 | more +1
这还不一定能得到准确结果,因为文本处理很容易出错。
image-20250930213706570
用PowerShell就简单多了:
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5
看到区别了吧?PowerShell的语法更接近自然语言,而且每一步操作的都是完整的对象,不会丢失信息。
image-20250930213717108
PowerShell还有一个很棒的特性就是管道操作。CMD也有管道,但只能传递文本。PowerShell的管道可以传递完整的对象,这就意味着你可以把多个命令串联起来,形成强大的数据处理流水线。
PowerShell常用命令详解
说到PowerShell的命令,那真是太多了。我按照日常使用频率给大家介绍一些最实用的。
文件和目录操作
Get-ChildItem(别名:ls, dir, gci)是最常用的命令之一,用来列出文件和目录:
# 列出当前目录所有文件
Get-ChildItem
# 递归列出所有子目录的文件
Get-ChildItem -Recurse
# 只显示文件夹
Get-ChildItem -Directory
# 按大小排序显示文件
Get-ChildItem | Sort-Object Length -Descending
Set-Location(别名:cd, sl)用来切换目录,这个跟CMD差不多:
Set-Location C:\Windows
cd D:\Projects
Copy-Item(别名:cp, copy)复制文件或目录:
# 复制文件
Copy-Item "source.txt" "destination.txt"
# 复制整个目录
Copy-Item "C:\Source" "C:\Destination" -Recurse
Move-Item(别名:mv, move)移动或重命名文件:
Move-Item "old.txt" "new.txt"
Move-Item "C:\temp\file.txt" "D:\backup\"
Remove-Item(别名:rm, del)删除文件或目录:
# 删除文件
Remove-Item "file.txt"
# 强制删除目录及其内容
Remove-Item "C:\temp" -Recurse -Force
进程管理
Get-Process(别名:ps, gps)获取进程信息,这个我用得特别多:
# 获取所有进程
Get-Process
# 获取特定进程
Get-Process notepad
# 按内存使用量排序
Get-Process | Sort-Object WorkingSet -Descending
# 获取占用CPU最多的进程
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
Stop-Process(别名:kill)终止进程:
# 根据进程名终止
Stop-Process -Name notepad
# 根据进程ID终止
Stop-Process -Id 1234
# 强制终止
Stop-Process -Name chrome -Force
Start-Process启动新进程:
# 启动记事本
Start-Process notepad
# 以管理员权限启动PowerShell
Start-Process powershell -Verb RunAs
服务管理
Get-Service获取系统服务信息:
# 获取所有服务
Get-Service
# 获取正在运行的服务
Get-Service | Where-Object {$_.Status -eq "Running"}
# 获取特定服务
Get-Service -Name Spooler
Start-Service和Stop-Service用来启动和停止服务:
Start-Service -Name Spooler
Stop-Service -Name Spooler
Restart-Service -Name Spooler
网络相关
Test-Connection(类似ping)测试网络连通性:
Test-Connection baidu.com
Test-Connection -ComputerName 192.168.1.1 -Count 4
Get-NetAdapter获取网络适配器信息:
Get-NetAdapter
Get-NetAdapter | Where-Object {$_.Status -eq "Up"}
系统信息
Get-ComputerInfo获取计算机详细信息:
Get-ComputerInfo
image-20250930213903893
Get-WmiObject用来获取WMI信息,这个功能超级强大:
# 获取系统信息
Get-WmiObject -Class Win32_ComputerSystem
# 获取CPU信息
Get-WmiObject -Class Win32_Processor
# 获取内存信息
Get-WmiObject -Class Win32_PhysicalMemory
# 获取磁盘信息
Get-WmiObject -Class Win32_LogicalDisk
文本处理
Select-String(类似grep,这个很重要)在文本中搜索:
# 在文件中搜索文本
Select-String -Path "*.log" -Pattern "error"
# 搜索多个文件
Get-ChildItem *.txt | Select-String "keyword"
数据筛选和处理
Where-Object(别名:where, ?)用来过滤对象:
# 获取大于100MB的文件
Get-ChildItem | Where-Object {$_.Length -gt 100MB}
# 获取最近7天修改的文件
Get-ChildItem | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-7)}
Select-Object用来选择对象的特定属性:
# 只显示进程名和内存使用量
Get-Process | Select-Object Name, WorkingSet
# 获取前10个进程
Get-Process | Select-Object -First 10
Sort-Object用来排序:
# 按文件大小排序
Get-ChildItem | Sort-Object Length
# 按进程名排序
Get-Process | Sort-Object Name
Group-Object用来分组统计:
# 按文件扩展名分组
Get-ChildItem | Group-Object Extension
# 统计进程数量
Get-Process | Group-Object ProcessName | Sort-Object Count -Descending
Measure-Object用来统计:
# 统计文件总大小
Get-ChildItem | Measure-Object -Property Length -Sum
# 统计进程数量
Get-Process | Measure-Object
CMD常用命令对比
为了让大家更好地理解两者的区别,我把一些常用的CMD命令和对应的PowerShell命令做个对比。
目录操作
# CMD
dir
cd C:\Windows
md newfolder
rd oldfolder
# PowerShell
Get-ChildItem
Set-Location C:\Windows
New-Item -ItemType Directory -Name newfolder
Remove-Item oldfolder
文件操作
# CMD
copy source.txt dest.txt
move old.txt new.txt
del file.txt
type file.txt
# PowerShell
Copy-Item source.txt dest.txt
Move-Item old.txt new.txt
Remove-Item file.txt
Get-Content file.txt
系统信息
# CMD
systeminfo
tasklist
taskkill /f /im notepad.exe
net start
net stop spooler
# PowerShell
Get-ComputerInfo
Get-Process
Stop-Process -Name notepad
Get-Service
Stop-Service spooler
网络命令
# CMD
ping google.com
ipconfig
netstat -an
# PowerShell
Test-Connection google.com
Get-NetIPConfiguration
Get-NetTCPConnection
#查看端口是否被占用
netstat -ano|findstr :80
实际应用场景对比
我来分享几个实际工作中遇到的场景,看看两者的差异。
场景一:批量重命名文件
假设你要把一个目录下所有的.txt文件重命名为.bak文件。
CMD的做法:
for %f in (*.txt) do ren "%f" "%~nf.bak"
PowerShell的做法:
Get-ChildItem *.txt | Rename-Item -NewName {$_.Name -replace '\.txt$','.bak'}
PowerShell的版本更直观,而且支持正则表达式,处理复杂的重命名规则更方便。
场景二:系统信息收集
如果要收集系统的硬件信息,CMD基本上只能调用systeminfo命令,然后用findstr过滤,很不方便。
PowerShell可以直接用WMI:
Get-WmiObject -Class Win32_ComputerSystem
Get-WmiObject -Class Win32_Processor
Get-WmiObject -Class Win32_PhysicalMemory
返回的都是结构化的对象,可以直接访问各种属性。
场景三:日志分析
这个我印象特别深刻。有一次服务器出问题,需要分析IIS日志找出异常请求。用CMD的话只能用findstr做简单的文本搜索,很难做复杂的统计分析。
PowerShell就不一样了,可以把日志解析成对象,然后用Group-Object、Where-Object等命令做各种统计:
Import-Csv "iis.log" -Delimiter " " |
Where-Object {$_.sc_status -eq "500"} |
Group-Object cs_uri_stem |
Sort-Object Count -Descending
这样就能快速找出哪些页面出现500错误最多。
场景四:批量管理服务器
这是PowerShell最强大的功能之一。假设你需要在多台服务器上执行相同的操作:
# 定义服务器列表
$servers = "Server01", "Server02", "Server03"
# 批量获取服务器信息
Invoke-Command -ComputerName $servers -ScriptBlock {
Get-WmiObject -Class Win32_LogicalDisk |
Where-Object {$_.DriveType -eq 3} |
Select-Object DeviceID, Size, FreeSpace
}
# 批量重启服务
Invoke-Command -ComputerName $servers -ScriptBlock {
Restart-Service -Name Spooler
}
这在CMD时代是不可能实现的,你只能一台台登录去操作。
PowerShell高级功能
除了基本命令,PowerShell还有很多高级功能值得了解。
变量和数组
PowerShell支持变量,这让脚本编写变得更加灵活:
# 定义变量
$name = "John"
$age = 30
# 定义数组
$servers = @("Server01", "Server02", "Server03")
$numbers = 1..10
# 哈希表
$user = @{
Name = "John"
Age = 30
Department = "IT"
}
条件判断和循环
# if语句
if ($age -gt 18) {
Write-Host "Adult"
} else {
Write-Host "Minor"
}
# foreach循环
foreach ($server in $servers) {
Test-Connection $server
}
# while循环
$i = 1
while ($i -le 10) {
Write-Host $i
$i++
}
函数定义
function Get-DiskSpace {
param(
[string]$ComputerName = $env:COMPUTERNAME
)
Get-WmiObject -Class Win32_LogicalDisk -ComputerName $ComputerName |
Where-Object {$_.DriveType -eq 3} |
Select-Object DeviceID,
@{Name="Size(GB)";Expression={[math]::Round($_.Size/1GB,2)}},
@{Name="FreeSpace(GB)";Expression={[math]::Round($_.FreeSpace/1GB,2)}}
}
错误处理
PowerShell的错误处理比CMD强大多了:
try {
Get-Content "nonexistent.txt"
} catch {
Write-Host "File not found: $($_.Exception.Message)"
} finally {
Write-Host "Cleanup completed"
}
模块和脚本
PowerShell支持模块化编程,你可以安装各种第三方模块:
# 安装模块
Install-Module -Name Az
# 导入模块
Import-Module Az
# 查看可用模块
Get-Module -ListAvailable
学习建议和注意事项
如果你现在还在用CMD,我强烈建议开始学习PowerShell。不过刚开始可能会有点不适应,因为PowerShell的语法和传统的命令行差别还是挺大的。
我当时学PowerShell的时候,最大的困惑就是那些动词-名词的命令格式,比如Get-Process、Set-Location这些。后来发现这其实是PowerShell的一大优势,命令名称很规范,容易记忆和理解。
PowerShell有个很好用的功能叫做Get-Help,遇到不懂的命令直接用这个查帮助:
# 获取命令帮助
Get-Help Get-Process
# 获取详细帮助
Get-Help Get-Process -Detailed
# 获取示例
Get-Help Get-Process -Examples
# 在线帮助
Get-Help Get-Process -Online
Get-Help
还有Get-Command可以搜索命令,Get-Member可以查看对象的属性和方法:
# 搜索包含"process"的命令
Get-Command *process*
# 查看Get-Process返回对象的属性和方法
Get-Process | Get-Member
# 按动词分组查看命令
Get-Command | Group-Object Verb
不过也要注意,PowerShell的功能虽然强大,但学习曲线相对陡峭一些。特别是涉及到.NET编程的部分,需要一定的编程基础。但即使不懂编程,掌握基本的PowerShell命令也能大大提高工作效率。
还有一点就是执行策略的问题。默认情况下PowerShell不允许执行脚本,需要用Set-ExecutionPolicy命令修改策略:
# 查看当前执行策略
Get-ExecutionPolicy
# 设置执行策略(需要管理员权限)
Set-ExecutionPolicy RemoteSigned
这是出于安全考虑,但刚开始用的时候可能会遇到这个坑。
PowerShell实用技巧
在日常使用中,我总结了一些实用的技巧,能让你的工作效率大大提升。
Tab补全
PowerShell的Tab补全功能非常强大,不仅可以补全命令名,还能补全参数名和文件路径:
# 输入Get-Proc然后按Tab,会自动补全为Get-Process
# 输入Get-Process -然后按Tab,会循环显示所有可用参数
历史命令
PowerShell会记录你执行过的命令,可以用以下方式查看和使用:
# 查看命令历史
Get-History
# 执行历史中的特定命令
Invoke-History 5
# 搜索历史命令
Get-History | Where-Object {$_.CommandLine -like "*process*"}
别名使用
PowerShell为很多常用命令定义了别名,让CMD用户更容易过渡:
# 查看所有别名
Get-Alias
# 查看特定别名
Get-Alias dir
# 创建自定义别名
New-Alias -Name np -Value notepad
输出格式化
PowerShell提供了多种格式化输出的方式:
# 表格格式(默认)
Get-Process | Format-Table
# 列表格式
Get-Process | Format-List
# 宽表格格式
Get-Process | Format-Wide
# 自定义表格列
Get-Process | Format-Table Name, CPU, WorkingSet
# 输出到网格视图(图形界面)
Get-Process | Out-GridView
管道操作技巧
管道是PowerShell最强大的特性之一,掌握好管道操作能让你事半功倍:
# 多级管道
Get-ChildItem |
Where-Object {$_.Length -gt 1MB} |
Sort-Object Length -Descending |
Select-Object Name, Length |
Format-Table -AutoSize
# 将结果保存到文件
Get-Process | Export-Csv "processes.csv"
# 将结果转换为HTML
Get-Service | ConvertTo-Html | Out-File "services.html"
正则表达式
PowerShell对正则表达式有很好的支持:
# 使用-match操作符
"192.168.1.1" -match "\d+\.\d+\.\d+\.\d+"
# 在Select-String中使用正则
Get-Content "log.txt" | Select-String "\d{4}-\d{2}-\d{2}"
# 替换操作
"Hello World" -replace "World", "PowerShell"
常见问题和解决方案
在使用PowerShell的过程中,经常会遇到一些问题,我把常见的几个列出来。
问题1:脚本执行被阻止
这是最常见的问题,解决方法是修改执行策略:
# 临时允许执行脚本
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
# 永久修改(需要管理员权限)
Set-ExecutionPolicy RemoteSigned
问题2:中文乱码
有时候PowerShell显示中文会出现乱码,可以这样解决:
# 设置控制台编码
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# 或者在脚本开头添加
$OutputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::UTF8
问题3:远程连接失败
使用PowerShell远程管理时可能遇到连接问题:
# 启用PowerShell远程管理
Enable-PSRemoting -Force
# 添加信任的主机
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.168.1.*"
# 测试远程连接
Test-WSMan -ComputerName "RemoteServer"
问题4:内存占用过高
PowerShell有时会占用较多内存,特别是处理大量数据时:
# 强制垃圾回收
[System.GC]::Collect()
# 使用流式处理代替一次性加载
Get-Content "largefile.txt" -ReadCount 1000 | ForEach-Object {
# 处理每1000行
}
未来发展趋势
从微软的战略来看,PowerShell明显是未来的方向。Windows 10开始,右键菜单中的"在此处打开命令窗口"已经改成了"在此处打开PowerShell窗口"。Windows Server的管理也越来越依赖PowerShell。
特别是云计算和自动化运维的兴起,PowerShell的优势更加明显。Azure PowerShell、AWS Tools for PowerShell等工具让你可以用统一的方式管理不同的云平台:
# Azure管理
Connect-AzAccount
Get-AzVM
New-AzResourceGroup -Name "MyRG" -Location "East US"
# AWS管理
Set-AWSCredential -AccessKey "your-key" -SecretKey "your-secret"
Get-EC2Instance
New-EC2Instance -ImageId "ami-12345678" -InstanceType "t2.micro"
我觉得CMD不会完全消失,毕竟它简单轻量,在某些场景下还是有用的。但对于系统管理员和运维工程师来说,掌握PowerShell已经是必备技能了。
现在PowerShell Core还支持跨平台,这意味着你在Windows上学会的PowerShell技能,在Linux和macOS上也能用。这对于混合环境的管理来说是个巨大的优势。
而且随着容器化和微服务架构的普及,PowerShell在Docker和Kubernetes管理方面也有很好的支持:
# Docker管理
docker ps | ConvertFrom-String | Where-Object {$_.P2 -like "*nginx*"}
# Kubernetes管理
kubectl get pods | ConvertFrom-String | Where-Object {$_.P3 -eq "Running"}
学习资源推荐
如果你想深入学习PowerShell,我推荐几个不错的资源:
官方文档
微软的PowerShell官方文档是最权威的学习资料,而且有中文版本。
文档地址:https://learn.microsoft.com/zh-cn/powershell/
在线教程
PowerShell Gallery有很多实用的脚本和模块,可以学习别人的代码。
地址:https://www.powershellgallery.com/
实践项目
最好的学习方法就是实践,可以从自动化日常工作开始,比如:
社区交流
Stack Overflow、Reddit的PowerShell社区都很活跃,遇到问题可以去提问。
总结
说了这么多,简单总结一下:PowerShell和CMD最大的区别就是数据处理方式不同,PowerShell面向对象,功能更强大,语法更现代化。虽然学习成本稍高一些,但绝对值得投入时间去学习。
PowerShell的命令虽然看起来复杂,但遵循统一的动词-名词格式,掌握了规律后其实很好记忆。而且它的帮助系统非常完善,Get-Help命令能解决大部分问题。
如果你现在还在纠结要不要学PowerShell,我的建议是赶紧开始吧。不管是日常的系统管理,还是复杂的自动化任务,PowerShell都能让你事半功倍。
当然,这不意味着要完全抛弃CMD。在某些简单场景下,CMD可能更直接一些。关键是要根据实际需求选择合适的工具。
最近老是用PowerShell,我记得以前都是用cmd的,PowerShell和CMD到底有什么区别,为什么现在大家都在推荐用PowerShell。说实话,刚开始接触Windows系统管理的时候,我也是一脸懵逼,黑框框不都一样吗?今天就跟大家聊聊这个话题,相信看完之后你会对这两个工具有个清晰的认识。
PowerShell究竟是什么东西
PowerShell说白了就是微软开发的一个命令行工具和脚本语言,但它可不是简单的命令行那么简单。我记得第一次用PowerShell的时候,输入Get-Process命令,看到那整齐的表格输出,当时就觉得这玩意儿不一般。
image-20250930213512332
跟传统的CMD比起来,PowerShell最大的特点就是面向对象。什么意思呢?就是说它处理的不是简单的文本,而是对象。比如你用Get-Service命令获取服务列表,返回的每一行都是一个完整的服务对象,包含了服务名、状态、启动类型等各种属性。
PowerShell基于.NET Framework构建,这意味着你可以直接调用.NET的各种类库和方法。有一次我需要批量处理Excel文件,用PowerShell直接调用Excel的COM对象,几行代码就搞定了,要是用CMD的话...想都不敢想。
现在PowerShell已经发展到7.x版本了,而且还支持跨平台,Linux和macOS上也能跑。微软把它开源了,这在以前是不可想象的事情。
image-20250930213601819
CMD的历史和局限性
CMD其实就是Command Prompt,它的历史可以追溯到DOS时代。说起来也挺有意思,我刚工作那会儿还在用Windows XP,那时候PowerShell还没普及,大家都是用CMD做各种操作。
CMD的工作方式很简单粗暴,就是执行命令然后返回文本。比如你用dir命令列出文件,返回的就是一堆文本信息,想要进一步处理的话就得用各种文本处理工具,非常麻烦。
我记得有一次需要统计某个目录下所有文件的大小,用CMD写了一个批处理脚本,各种for循环和字符串处理,写得我头都大了。后来用PowerShell的话,一行Get-ChildItem | Measure-Object -Property Length -Sum就搞定了。
CMD的另一个问题就是错误处理机制比较原始。很多时候命令执行失败了,你都不知道具体是什么原因,只能靠经验去猜测。
两者的核心区别在哪里
最根本的区别就是数据处理方式不同。CMD处理的是文本流,而PowerShell处理的是对象流。这听起来可能有点抽象,我举个具体例子。
假设你要获取系统中占用内存最多的前5个进程:
用CMD的话,你需要:
tasklist /fo csv | findstr /v "Image Name" | sort /r /+5 | more +1
这还不一定能得到准确结果,因为文本处理很容易出错。
image-20250930213706570
用PowerShell就简单多了:
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5
看到区别了吧?PowerShell的语法更接近自然语言,而且每一步操作的都是完整的对象,不会丢失信息。
image-20250930213717108
PowerShell还有一个很棒的特性就是管道操作。CMD也有管道,但只能传递文本。PowerShell的管道可以传递完整的对象,这就意味着你可以把多个命令串联起来,形成强大的数据处理流水线。
PowerShell常用命令详解
说到PowerShell的命令,那真是太多了。我按照日常使用频率给大家介绍一些最实用的。
文件和目录操作
Get-ChildItem(别名:ls, dir, gci)是最常用的命令之一,用来列出文件和目录:
# 列出当前目录所有文件
Get-ChildItem
# 递归列出所有子目录的文件
Get-ChildItem -Recurse
# 只显示文件夹
Get-ChildItem -Directory
# 按大小排序显示文件
Get-ChildItem | Sort-Object Length -Descending
Set-Location(别名:cd, sl)用来切换目录,这个跟CMD差不多:
Set-Location C:\Windows
cd D:\Projects
Copy-Item(别名:cp, copy)复制文件或目录:
# 复制文件
Copy-Item "source.txt" "destination.txt"
# 复制整个目录
Copy-Item "C:\Source" "C:\Destination" -Recurse
Move-Item(别名:mv, move)移动或重命名文件:
Move-Item "old.txt" "new.txt"
Move-Item "C:\temp\file.txt" "D:\backup\"
Remove-Item(别名:rm, del)删除文件或目录:
# 删除文件
Remove-Item "file.txt"
# 强制删除目录及其内容
Remove-Item "C:\temp" -Recurse -Force
进程管理
Get-Process(别名:ps, gps)获取进程信息,这个我用得特别多:
# 获取所有进程
Get-Process
# 获取特定进程
Get-Process notepad
# 按内存使用量排序
Get-Process | Sort-Object WorkingSet -Descending
# 获取占用CPU最多的进程
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
Stop-Process(别名:kill)终止进程:
# 根据进程名终止
Stop-Process -Name notepad
# 根据进程ID终止
Stop-Process -Id 1234
# 强制终止
Stop-Process -Name chrome -Force
Start-Process启动新进程:
# 启动记事本
Start-Process notepad
# 以管理员权限启动PowerShell
Start-Process powershell -Verb RunAs
服务管理
Get-Service获取系统服务信息:
# 获取所有服务
Get-Service
# 获取正在运行的服务
Get-Service | Where-Object {$_.Status -eq "Running"}
# 获取特定服务
Get-Service -Name Spooler
Start-Service和Stop-Service用来启动和停止服务:
Start-Service -Name Spooler
Stop-Service -Name Spooler
Restart-Service -Name Spooler
网络相关
Test-Connection(类似ping)测试网络连通性:
Test-Connection baidu.com
Test-Connection -ComputerName 192.168.1.1 -Count 4
Get-NetAdapter获取网络适配器信息:
Get-NetAdapter
Get-NetAdapter | Where-Object {$_.Status -eq "Up"}
系统信息
Get-ComputerInfo获取计算机详细信息:
Get-ComputerInfo
image-20250930213903893
Get-WmiObject用来获取WMI信息,这个功能超级强大:
# 获取系统信息
Get-WmiObject -Class Win32_ComputerSystem
# 获取CPU信息
Get-WmiObject -Class Win32_Processor
# 获取内存信息
Get-WmiObject -Class Win32_PhysicalMemory
# 获取磁盘信息
Get-WmiObject -Class Win32_LogicalDisk
文本处理
Select-String(类似grep,这个很重要)在文本中搜索:
# 在文件中搜索文本
Select-String -Path "*.log" -Pattern "error"
# 搜索多个文件
Get-ChildItem *.txt | Select-String "keyword"
数据筛选和处理
Where-Object(别名:where, ?)用来过滤对象:
# 获取大于100MB的文件
Get-ChildItem | Where-Object {$_.Length -gt 100MB}
# 获取最近7天修改的文件
Get-ChildItem | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-7)}
Select-Object用来选择对象的特定属性:
# 只显示进程名和内存使用量
Get-Process | Select-Object Name, WorkingSet
# 获取前10个进程
Get-Process | Select-Object -First 10
Sort-Object用来排序:
# 按文件大小排序
Get-ChildItem | Sort-Object Length
# 按进程名排序
Get-Process | Sort-Object Name
Group-Object用来分组统计:
# 按文件扩展名分组
Get-ChildItem | Group-Object Extension
# 统计进程数量
Get-Process | Group-Object ProcessName | Sort-Object Count -Descending
Measure-Object用来统计:
# 统计文件总大小
Get-ChildItem | Measure-Object -Property Length -Sum
# 统计进程数量
Get-Process | Measure-Object
CMD常用命令对比
为了让大家更好地理解两者的区别,我把一些常用的CMD命令和对应的PowerShell命令做个对比。
目录操作
# CMD
dir
cd C:\Windows
md newfolder
rd oldfolder
# PowerShell
Get-ChildItem
Set-Location C:\Windows
New-Item -ItemType Directory -Name newfolder
Remove-Item oldfolder
文件操作
# CMD
copy source.txt dest.txt
move old.txt new.txt
del file.txt
type file.txt
# PowerShell
Copy-Item source.txt dest.txt
Move-Item old.txt new.txt
Remove-Item file.txt
Get-Content file.txt
系统信息
# CMD
systeminfo
tasklist
taskkill /f /im notepad.exe
net start
net stop spooler
# PowerShell
Get-ComputerInfo
Get-Process
Stop-Process -Name notepad
Get-Service
Stop-Service spooler
网络命令
# CMD
ping google.com
ipconfig
netstat -an
# PowerShell
Test-Connection google.com
Get-NetIPConfiguration
Get-NetTCPConnection
#查看端口是否被占用
netstat -ano|findstr :80
实际应用场景对比
我来分享几个实际工作中遇到的场景,看看两者的差异。
场景一:批量重命名文件
假设你要把一个目录下所有的.txt文件重命名为.bak文件。
CMD的做法:
for %f in (*.txt) do ren "%f" "%~nf.bak"
PowerShell的做法:
Get-ChildItem *.txt | Rename-Item -NewName {$_.Name -replace '\.txt$','.bak'}
PowerShell的版本更直观,而且支持正则表达式,处理复杂的重命名规则更方便。
场景二:系统信息收集
如果要收集系统的硬件信息,CMD基本上只能调用systeminfo命令,然后用findstr过滤,很不方便。
PowerShell可以直接用WMI:
Get-WmiObject -Class Win32_ComputerSystem
Get-WmiObject -Class Win32_Processor
Get-WmiObject -Class Win32_PhysicalMemory
返回的都是结构化的对象,可以直接访问各种属性。
场景三:日志分析
这个我印象特别深刻。有一次服务器出问题,需要分析IIS日志找出异常请求。用CMD的话只能用findstr做简单的文本搜索,很难做复杂的统计分析。
PowerShell就不一样了,可以把日志解析成对象,然后用Group-Object、Where-Object等命令做各种统计:
Import-Csv "iis.log" -Delimiter " " |
Where-Object {$_.sc_status -eq "500"} |
Group-Object cs_uri_stem |
Sort-Object Count -Descending
这样就能快速找出哪些页面出现500错误最多。
场景四:批量管理服务器
这是PowerShell最强大的功能之一。假设你需要在多台服务器上执行相同的操作:
# 定义服务器列表
$servers = "Server01", "Server02", "Server03"
# 批量获取服务器信息
Invoke-Command -ComputerName $servers -ScriptBlock {
Get-WmiObject -Class Win32_LogicalDisk |
Where-Object {$_.DriveType -eq 3} |
Select-Object DeviceID, Size, FreeSpace
}
# 批量重启服务
Invoke-Command -ComputerName $servers -ScriptBlock {
Restart-Service -Name Spooler
}
这在CMD时代是不可能实现的,你只能一台台登录去操作。
PowerShell高级功能
除了基本命令,PowerShell还有很多高级功能值得了解。
变量和数组
PowerShell支持变量,这让脚本编写变得更加灵活:
# 定义变量
$name = "John"
$age = 30
# 定义数组
$servers = @("Server01", "Server02", "Server03")
$numbers = 1..10
# 哈希表
$user = @{
Name = "John"
Age = 30
Department = "IT"
}
条件判断和循环
# if语句
if ($age -gt 18) {
Write-Host "Adult"
} else {
Write-Host "Minor"
}
# foreach循环
foreach ($server in $servers) {
Test-Connection $server
}
# while循环
$i = 1
while ($i -le 10) {
Write-Host $i
$i++
}
函数定义
function Get-DiskSpace {
param(
[string]$ComputerName = $env:COMPUTERNAME
)
Get-WmiObject -Class Win32_LogicalDisk -ComputerName $ComputerName |
Where-Object {$_.DriveType -eq 3} |
Select-Object DeviceID,
@{Name="Size(GB)";Expression={[math]::Round($_.Size/1GB,2)}},
@{Name="FreeSpace(GB)";Expression={[math]::Round($_.FreeSpace/1GB,2)}}
}
错误处理
PowerShell的错误处理比CMD强大多了:
try {
Get-Content "nonexistent.txt"
} catch {
Write-Host "File not found: $($_.Exception.Message)"
} finally {
Write-Host "Cleanup completed"
}
模块和脚本
PowerShell支持模块化编程,你可以安装各种第三方模块:
# 安装模块
Install-Module -Name Az
# 导入模块
Import-Module Az
# 查看可用模块
Get-Module -ListAvailable
学习建议和注意事项
如果你现在还在用CMD,我强烈建议开始学习PowerShell。不过刚开始可能会有点不适应,因为PowerShell的语法和传统的命令行差别还是挺大的。
我当时学PowerShell的时候,最大的困惑就是那些动词-名词的命令格式,比如Get-Process、Set-Location这些。后来发现这其实是PowerShell的一大优势,命令名称很规范,容易记忆和理解。
PowerShell有个很好用的功能叫做Get-Help,遇到不懂的命令直接用这个查帮助:
# 获取命令帮助
Get-Help Get-Process
# 获取详细帮助
Get-Help Get-Process -Detailed
# 获取示例
Get-Help Get-Process -Examples
# 在线帮助
Get-Help Get-Process -Online
Get-Help
还有Get-Command可以搜索命令,Get-Member可以查看对象的属性和方法:
# 搜索包含"process"的命令
Get-Command *process*
# 查看Get-Process返回对象的属性和方法
Get-Process | Get-Member
# 按动词分组查看命令
Get-Command | Group-Object Verb
不过也要注意,PowerShell的功能虽然强大,但学习曲线相对陡峭一些。特别是涉及到.NET编程的部分,需要一定的编程基础。但即使不懂编程,掌握基本的PowerShell命令也能大大提高工作效率。
还有一点就是执行策略的问题。默认情况下PowerShell不允许执行脚本,需要用Set-ExecutionPolicy命令修改策略:
# 查看当前执行策略
Get-ExecutionPolicy
# 设置执行策略(需要管理员权限)
Set-ExecutionPolicy RemoteSigned
这是出于安全考虑,但刚开始用的时候可能会遇到这个坑。
PowerShell实用技巧
在日常使用中,我总结了一些实用的技巧,能让你的工作效率大大提升。
Tab补全
PowerShell的Tab补全功能非常强大,不仅可以补全命令名,还能补全参数名和文件路径:
# 输入Get-Proc然后按Tab,会自动补全为Get-Process
# 输入Get-Process -然后按Tab,会循环显示所有可用参数
历史命令
PowerShell会记录你执行过的命令,可以用以下方式查看和使用:
# 查看命令历史
Get-History
# 执行历史中的特定命令
Invoke-History 5
# 搜索历史命令
Get-History | Where-Object {$_.CommandLine -like "*process*"}
别名使用
PowerShell为很多常用命令定义了别名,让CMD用户更容易过渡:
# 查看所有别名
Get-Alias
# 查看特定别名
Get-Alias dir
# 创建自定义别名
New-Alias -Name np -Value notepad
输出格式化
PowerShell提供了多种格式化输出的方式:
# 表格格式(默认)
Get-Process | Format-Table
# 列表格式
Get-Process | Format-List
# 宽表格格式
Get-Process | Format-Wide
# 自定义表格列
Get-Process | Format-Table Name, CPU, WorkingSet
# 输出到网格视图(图形界面)
Get-Process | Out-GridView
管道操作技巧
管道是PowerShell最强大的特性之一,掌握好管道操作能让你事半功倍:
# 多级管道
Get-ChildItem |
Where-Object {$_.Length -gt 1MB} |
Sort-Object Length -Descending |
Select-Object Name, Length |
Format-Table -AutoSize
# 将结果保存到文件
Get-Process | Export-Csv "processes.csv"
# 将结果转换为HTML
Get-Service | ConvertTo-Html | Out-File "services.html"
正则表达式
PowerShell对正则表达式有很好的支持:
# 使用-match操作符
"192.168.1.1" -match "\d+\.\d+\.\d+\.\d+"
# 在Select-String中使用正则
Get-Content "log.txt" | Select-String "\d{4}-\d{2}-\d{2}"
# 替换操作
"Hello World" -replace "World", "PowerShell"
常见问题和解决方案
在使用PowerShell的过程中,经常会遇到一些问题,我把常见的几个列出来。
问题1:脚本执行被阻止
这是最常见的问题,解决方法是修改执行策略:
# 临时允许执行脚本
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
# 永久修改(需要管理员权限)
Set-ExecutionPolicy RemoteSigned
问题2:中文乱码
有时候PowerShell显示中文会出现乱码,可以这样解决:
# 设置控制台编码
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# 或者在脚本开头添加
$OutputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::UTF8
问题3:远程连接失败
使用PowerShell远程管理时可能遇到连接问题:
# 启用PowerShell远程管理
Enable-PSRemoting -Force
# 添加信任的主机
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.168.1.*"
# 测试远程连接
Test-WSMan -ComputerName "RemoteServer"
问题4:内存占用过高
PowerShell有时会占用较多内存,特别是处理大量数据时:
# 强制垃圾回收
[System.GC]::Collect()
# 使用流式处理代替一次性加载
Get-Content "largefile.txt" -ReadCount 1000 | ForEach-Object {
# 处理每1000行
}
未来发展趋势
从微软的战略来看,PowerShell明显是未来的方向。Windows 10开始,右键菜单中的"在此处打开命令窗口"已经改成了"在此处打开PowerShell窗口"。Windows Server的管理也越来越依赖PowerShell。
特别是云计算和自动化运维的兴起,PowerShell的优势更加明显。Azure PowerShell、AWS Tools for PowerShell等工具让你可以用统一的方式管理不同的云平台:
# Azure管理
Connect-AzAccount
Get-AzVM
New-AzResourceGroup -Name "MyRG" -Location "East US"
# AWS管理
Set-AWSCredential -AccessKey "your-key" -SecretKey "your-secret"
Get-EC2Instance
New-EC2Instance -ImageId "ami-12345678" -InstanceType "t2.micro"
我觉得CMD不会完全消失,毕竟它简单轻量,在某些场景下还是有用的。但对于系统管理员和运维工程师来说,掌握PowerShell已经是必备技能了。
现在PowerShell Core还支持跨平台,这意味着你在Windows上学会的PowerShell技能,在Linux和macOS上也能用。这对于混合环境的管理来说是个巨大的优势。
而且随着容器化和微服务架构的普及,PowerShell在Docker和Kubernetes管理方面也有很好的支持:
# Docker管理
docker ps | ConvertFrom-String | Where-Object {$_.P2 -like "*nginx*"}
# Kubernetes管理
kubectl get pods | ConvertFrom-String | Where-Object {$_.P3 -eq "Running"}
学习资源推荐
如果你想深入学习PowerShell,我推荐几个不错的资源:
官方文档
微软的PowerShell官方文档是最权威的学习资料,而且有中文版本。
文档地址:https://learn.microsoft.com/zh-cn/powershell/
在线教程
PowerShell Gallery有很多实用的脚本和模块,可以学习别人的代码。
地址:https://www.powershellgallery.com/
实践项目
最好的学习方法就是实践,可以从自动化日常工作开始,比如:
社区交流
Stack Overflow、Reddit的PowerShell社区都很活跃,遇到问题可以去提问。
总结
说了这么多,简单总结一下:PowerShell和CMD最大的区别就是数据处理方式不同,PowerShell面向对象,功能更强大,语法更现代化。虽然学习成本稍高一些,但绝对值得投入时间去学习。
PowerShell的命令虽然看起来复杂,但遵循统一的动词-名词格式,掌握了规律后其实很好记忆。而且它的帮助系统非常完善,Get-Help命令能解决大部分问题。
如果你现在还在纠结要不要学PowerShell,我的建议是赶紧开始吧。不管是日常的系统管理,还是复杂的自动化任务,PowerShell都能让你事半功倍。
当然,这不意味着要完全抛弃CMD。在某些简单场景下,CMD可能更直接一些。关键是要根据实际需求选择合适的工具。
阅读原文:原文链接
该文章在 2025/10/9 13:24:43 编辑过