对 linux 的 shell 脚本比较熟悉后,发现 windows 的 powershell 也挺好用的。这里记录一些常用的脚本片段,方便以后查阅。
查看磁盘占用
类似 du -h --max-depth 1(Linux) 或 du -d1 -h(MacOS) 的功能,可以使用 PowerShell 脚本来查看当前目录下的文件夹大小:
可以
code $PROFILE打开 PowerShell 配置文件,将下面的函数添加进去,这样就可以在 PowerShell 中使用ds命令来查看当前目录下的文件夹大小。
function Get-FolderSize {
Write-Host '正在计算当前目录的空间占用,请稍候。。。' -ForegroundColor Yellow
# 统计当前目录下的文件(不在子文件夹中)
$currentFiles = Get-ChildItem -File -Force -ErrorAction SilentlyContinue
if ($currentFiles) {
$currentSize = ($currentFiles | Measure-Object -Property Length -Sum).Sum
} else {
$currentSize = 0
}
# 统计所有子文件夹
$folders = Get-ChildItem -Force | Where-Object { $_.PSIsContainer } | ForEach-Object {
$files = Get-ChildItem $_.FullName -Recurse -Force -File -ErrorAction SilentlyContinue
if ($files) {
$size = ($files | Measure-Object -Property Length -Sum).Sum
} else {
$size = 0
}
[PSCustomObject]@{
Name = $_.Name
SizeGB = [math]::Round($size / 1GB, 2)
SizeMB = [math]::Round($size / 1MB, 2)
}
}
# 添加当前目录文件统计
if ($currentSize -gt 0) {
$currentDirEntry = [PSCustomObject]@{
Name = "."
SizeGB = [math]::Round($currentSize / 1GB, 2)
SizeMB = [math]::Round($currentSize / 1MB, 2)
}
$allEntries = @($currentDirEntry) + $folders
} else {
$allEntries = $folders
}
# 按大小排序并显示
$allEntries | Sort-Object SizeGB -Descending | Format-Table -AutoSize
}
# 创建 alias
Set-Alias -Name ds -Value Get-FolderSize
C:\Program Files (x86)\Steam\steamapps\common:
Name SizeGB SizeMB
---- ------ ------
MonsterHunterWilds 154.94 158661.41
Baldurs Gate 3 144.74 148214.57
BlackMythWukong 140.48 143856.29
Monster Hunter World 98.39 100747.9
ForzaHorizon4 94.58 96844.94
Cyberpunk 2077 91.23 93415.27
ELDEN RING 66.2 67786.84
Palworld 29.5 30207.92
Hades 11.08 11348.39
Hades II 10.17 10410.33
wallpaper_engine 1.32 1348.01
Steamworks Shared 0.56 569.12
MonsterHunterWildsBetatest 0.44 451.38
Black Myth Wukong Benchmark Tool 0.04 41.16
Steam Controller Configs 0 0
放开某端口的防火墙
$port=2222
New-NetFirewallRule -DisplayName "Allow Port $port" -Direction Inbound -Protocol TCP -LocalPort $port -Action Allow
系统信息相关
查看 CPU 和内存使用情况
# CPU 使用率
Get-Counter '\Processor(_Total)\% Processor Time' -SampleInterval 1 -MaxSamples 3
# 内存使用情况
Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 10 Name, @{N='MemoryMB';E={[math]::Round($_.WorkingSet64/1MB,2)}}
# 系统内存概览
Get-CimInstance Win32_OperatingSystem | Select-Object @{N='TotalMemoryGB';E={[math]::Round($_.TotalVisibleMemorySize/1MB,2)}}, @{N='FreeMemoryGB';E={[math]::Round($_.FreePhysicalMemory/1MB,2)}}
查看磁盘使用情况
# 查看所有磁盘分区使用情况
Get-PSDrive -PSProvider FileSystem | Select-Object Name, @{N='UsedGB';E={[math]::Round($_.Used/1GB,2)}}, @{N='FreeGB';E={[math]::Round($_.Free/1GB,2)}}, @{N='TotalGB';E={[math]::Round(($_.Used+$_.Free)/1GB,2)}}
进程管理
查找并终止进程
# 按名称查找进程
Get-Process -Name *chrome* | Select-Object Id, ProcessName, CPU, @{N='MemoryMB';E={[math]::Round($_.WorkingSet64/1MB,2)}}
# 终止进程
Stop-Process -Name "进程名" -Force
# 按端口查找并终止进程
$port = 8080
Get-NetTCPConnection -LocalPort $port -ErrorAction SilentlyContinue | ForEach-Object {
$process = Get-Process -Id $_.OwningProcess
Write-Host "端口 $port 被进程占用: $($process.ProcessName) (PID: $($process.Id))"
# Stop-Process -Id $_.OwningProcess -Force # 取消注释以终止进程
}
查看端口占用
# 查看所有监听端口
Get-NetTCPConnection -State Listen | Select-Object LocalAddress, LocalPort, @{N='Process';E={(Get-Process -Id $_.OwningProcess).ProcessName}} | Sort-Object LocalPort
# 查看特定端口
Get-NetTCPConnection -LocalPort 80 -ErrorAction SilentlyContinue | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State, @{N='Process';E={(Get-Process -Id $_.OwningProcess).ProcessName}}
网络相关
测试网络连通性
# 类似 ping,但更强大
Test-NetConnection -ComputerName google.com -Port 443
# 批量测试多个主机
@("google.com", "github.com", "baidu.com") | ForEach-Object {
$result = Test-NetConnection -ComputerName $_ -Port 443 -WarningAction SilentlyContinue
[PSCustomObject]@{
Host = $_
TcpTestSucceeded = $result.TcpTestSucceeded
PingSucceeded = $result.PingSucceeded
RTT = $result.PingReplyDetails.RoundtripTime
}
} | Format-Table -AutoSize
查看网络配置
# 获取 IP 地址信息
Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -ne "127.0.0.1" } | Select-Object InterfaceAlias, IPAddress, PrefixLength
# 获取 DNS 服务器
Get-DnsClientServerAddress -AddressFamily IPv4 | Where-Object { $_.ServerAddresses } | Select-Object InterfaceAlias, ServerAddresses
# 获取默认网关
Get-NetRoute -DestinationPrefix "0.0.0.0/0" | Select-Object InterfaceAlias, NextHop
刷新 DNS 缓存
Clear-DnsClientCache
Write-Host "DNS 缓存已清除" -ForegroundColor Green
文件操作
批量重命名文件
# 批量添加前缀
Get-ChildItem -Filter "*.jpg" | Rename-Item -NewName { "prefix_" + $_.Name }
# 批量替换文件名中的字符
Get-ChildItem -Filter "*old*" | Rename-Item -NewName { $_.Name -replace "old", "new" }
# 按序号重命名
$i = 1; Get-ChildItem -Filter "*.png" | ForEach-Object { Rename-Item $_.FullName -NewName ("image_{0:D3}.png" -f $i++)}
查找大文件
# 查找当前目录下大于 100MB 的文件
Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.Length -gt 100MB } | Sort-Object Length -Descending | Select-Object @{N='SizeMB';E={[math]::Round($_.Length/1MB,2)}}, FullName | Format-Table -AutoSize
计算文件哈希
# 计算 MD5
Get-FileHash -Path "文件路径" -Algorithm MD5
# 计算 SHA256
Get-FileHash -Path "文件路径" -Algorithm SHA256
# 批量计算当前目录所有文件的哈希
Get-ChildItem -File | Get-FileHash -Algorithm MD5 | Select-Object Hash, @{N='FileName';E={Split-Path $_.Path -Leaf}}
压缩和解压
# 压缩文件夹
Compress-Archive -Path "源文件夹" -DestinationPath "目标.zip"
# 解压缩
Expand-Archive -Path "源.zip" -DestinationPath "目标文件夹"
# 追加文件到现有压缩包
Compress-Archive -Path "新文件" -Update -DestinationPath "现有.zip"
服务管理
查看和管理服务
# 查看所有正在运行的服务
Get-Service | Where-Object { $_.Status -eq "Running" } | Sort-Object DisplayName
# 按名称搜索服务
Get-Service -Name "*ssh*" | Select-Object Name, DisplayName, Status, StartType
# 启动/停止/重启服务
Start-Service -Name "服务名"
Stop-Service -Name "服务名"
Restart-Service -Name "服务名"
# 设置服务启动类型
Set-Service -Name "服务名" -StartupType Automatic # Manual / Disabled
环境变量
查看和设置环境变量
# 查看所有环境变量
Get-ChildItem Env: | Sort-Object Name
# 查看特定环境变量
$env:PATH -split ";"
# 临时设置环境变量(仅当前会话)
$env:MY_VAR = "my_value"
# 永久设置用户环境变量
[Environment]::SetEnvironmentVariable("MY_VAR", "my_value", "User")
# 永久设置系统环境变量(需要管理员权限)
[Environment]::SetEnvironmentVariable("MY_VAR", "my_value", "Machine")
# 添加路径到 PATH(永久,用户级别)
$currentPath = [Environment]::GetEnvironmentVariable("PATH", "User")
[Environment]::SetEnvironmentVariable("PATH", "$currentPath;C:\新路径", "User")
计划任务
创建计划任务
# 创建一个每天运行的计划任务
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:\Scripts\backup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "03:00"
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest
Register-ScheduledTask -TaskName "每日备份" -Action $action -Trigger $trigger -Principal $principal
# 查看计划任务
Get-ScheduledTask | Where-Object { $_.TaskName -like "*备份*" }
# 删除计划任务
Unregister-ScheduledTask -TaskName "每日备份" -Confirm:$false
剪贴板操作
# 复制到剪贴板
"要复制的内容" | Set-Clipboard
# 从剪贴板获取内容
Get-Clipboard
# 将命令输出复制到剪贴板
Get-Process | Out-String | Set-Clipboard
下载文件
# 使用 Invoke-WebRequest 下载
Invoke-WebRequest -Uri "https://example.com/file.zip" -OutFile "file.zip"
# 带进度条的下载
$ProgressPreference = 'Continue'
Invoke-WebRequest -Uri "https://example.com/file.zip" -OutFile "file.zip"
# 使用 curl(PowerShell 7+)或 Start-BitsTransfer(后台下载)
Start-BitsTransfer -Source "https://example.com/file.zip" -Destination "file.zip"
实用小函数
快速打开常用目录
# 添加到 $PROFILE
function hosts { notepad C:\Windows\System32\drivers\etc\hosts }
function downloads { Set-Location $env:USERPROFILE\Downloads }
function desktop { Set-Location $env:USERPROFILE\Desktop }
function projects { Set-Location D:\Projects } # 自定义你的项目目录
快速创建文件(类似 Linux touch)
function touch {
param([string]$Path)
if (Test-Path $Path) {
(Get-Item $Path).LastWriteTime = Get-Date
} else {
New-Item -ItemType File -Path $Path
}
}
历史命令搜索
# 搜索历史命令
Get-History | Where-Object { $_.CommandLine -like "*关键词*" }
# 查看所有历史命令(包括之前的会话)
Get-Content (Get-PSReadlineOption).HistorySavePath | Select-String "关键词"
生成随机密码
function New-RandomPassword {
param([int]$Length = 16)
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*'
-join (1..$Length | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })
}
# 使用
New-RandomPassword -Length 20
快速 Base64 编解码
# 编码
function ConvertTo-Base64 { param([string]$Text) [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Text)) }
# 解码
function ConvertFrom-Base64 { param([string]$Base64) [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($Base64)) }