「Windows自动化之王:PowerShell极简美学」
PowerShell 是微软开发的强大脚本语言和命令行工具,专为系统管理和自动化任务设计。以下是 PowerShell 脚本的基础知识:
1. 基本概念
- PowerShell:既是命令行shell,也是脚本语言
- .ps1 文件:PowerShell 脚本文件的扩展名
- Cmdlet:PowerShell 内置命令,格式为"动词-名词"(如 Get-Process)
2. 基本语法
变量
$variable = "值" # 定义变量
$var1, $var2 = 1, 2 # 多变量赋值
注释
# 单行注释
<#
多行
注释
#>
输出
Write-Host "Hello, PowerShell!" # 输出到控制台
"Hello" # 直接输出字符串
3. 常用Cmdlet示例
Get-Process # 获取运行中的进程
Get-Service # 获取服务状态
Get-ChildItem # 列出目录内容(类似dir)
Get-Help Get-Process # 获取帮助信息
4. 控制结构
条件语句
if ($value -eq 10) {Write-Host "值是10"
} elseif ($value -gt 10) {Write-Host "值大于10"
} else {Write-Host "值小于10"
}
循环
# for循环
for ($i=0; $i -lt 10; $i++) {Write-Host $i
}# foreach循环
$array = 1..5
foreach ($item in $array) {Write-Host $item
}# while循环
$i = 0
while ($i -lt 5) {Write-Host $i$i++
}
5. 函数
function Say-Hello {param ([string]$Name = "World")Write-Host "Hello, $Name!"
}Say-Hello -Name "Alice"
6. 管道操作
PowerShell 的强大特性之一,允许将一个命令的输出作为另一个命令的输入:
Get-Process | Where-Object { $_.CPU -gt 100 } | Sort-Object CPU -Descending
7. 脚本执行策略
默认情况下,PowerShell 限制脚本执行,可以查看和修改执行策略:
Get-ExecutionPolicy # 查看当前策略
Set-ExecutionPolicy RemoteSigned # 设置为允许本地脚本运行
PowerShell 脚本基础
PowerShell 是微软开发的强大脚本语言和命令行工具,专为系统管理和自动化任务设计。以下是 PowerShell 脚本的基础知识:
1. 基本概念
-
•
PowerShell:既是命令行shell,也是脚本语言
-
•
.ps1 文件:PowerShell 脚本文件的扩展名
-
•
Cmdlet:PowerShell 内置命令,格式为"动词-名词"(如 Get-Process)
2. 基本语法
变量
powershell
复制
$variable = "值" # 定义变量
$var1, $var2 = 1, 2 # 多变量赋值
注释
powershell
复制
# 单行注释
<#
多行
注释
#>
输出
powershell
复制
Write-Host "Hello, PowerShell!" # 输出到控制台
"Hello" # 直接输出字符串
3. 常用Cmdlet示例
powershell
复制
Get-Process # 获取运行中的进程
Get-Service # 获取服务状态
Get-ChildItem # 列出目录内容(类似dir)
Get-Help Get-Process # 获取帮助信息
4. 控制结构
条件语句
powershell
复制
if ($value -eq 10) {Write-Host "值是10"
} elseif ($value -gt 10) {Write-Host "值大于10"
} else {Write-Host "值小于10"
}
循环
powershell
复制
# for循环
for ($i=0; $i -lt 10; $i++) {Write-Host $i
}# foreach循环
$array = 1..5
foreach ($item in $array) {Write-Host $item
}# while循环
$i = 0
while ($i -lt 5) {Write-Host $i$i++
}
5. 函数
powershell
复制
function Say-Hello {param ([string]$Name = "World")Write-Host "Hello, $Name!"
}Say-Hello -Name "Alice"
6. 管道操作
PowerShell 的强大特性之一,允许将一个命令的输出作为另一个命令的输入:
powershell
复制
Get-Process | Where-Object { $_.CPU -gt 100 } | Sort-Object CPU -Descending
7. 脚本执行策略
默认情况下,PowerShell 限制脚本执行,可以查看和修改执行策略:
powershell
复制
Get-ExecutionPolicy # 查看当前策略
Set-ExecutionPolicy RemoteSigned # 设置为允许本地脚本运行
8. 运行脚本
.\script.ps1 # 运行当前目录下的脚本
9. 常用操作符
- 比较运算符:
-eq
(等于),-ne
(不等于),-gt
(大于),-lt
(小于) - 逻辑运算符:
-and
,-or
,-not
- 字符串操作符:
-like
,-match
(正则匹配)
10. 错误处理
try {# 可能出错的代码Get-Item "不存在的文件.txt" -ErrorAction Stop
}
catch {Write-Host "发生错误: $_"
}
finally {# 清理代码
}
11 高级变量操作
哈希表(Hashtable)
$user = @{Name = "张三"Age = 30Department = "IT"
}
$user.Name # 访问属性
$user["Age"] = 31 # 修改值
$user.Keys # 获取所有键
$user.Values # 获取所有值
数组操作
$numbers = 1..10
$numbers += 11 # 添加元素
$numbers -join "," # 合并为字符串
$numbers -split "," # 分割字符串为数组
$numbers.Where({$_ -gt 5}) # 筛选大于5的元素
12. 高级函数特性
参数验证
function Get-UserInfo {param ([Parameter(Mandatory=$true)][ValidateSet("Admin","User","Guest")][string]$Role,[ValidateRange(18,65)][int]$Age,[ValidatePattern("[a-z]+")][string]$Username)# 函数体
}
管道输入
function Process-Files {param ([Parameter(ValueFromPipeline=$true)][string]$FilePath)process {"处理文件: $_"}
}Get-ChildItem | Select-Object -ExpandProperty FullName | Process-Files
3. 模块开发
创建模块
-
创建
MyModule.psm1
文件function Get-MyInfo {"这是我的自定义模块" }Export-ModuleMember -Function Get-MyInfo
-
创建模块清单
MyModule.psd1
@{ModuleVersion = '1.0'RootModule = 'MyModule.psm1'FunctionsToExport = @('Get-MyInfo') }
-
使用模块
Import-Module .\MyModule.psd1
Get-MyInfo
14. 远程管理
远程会话
$session = New-PSSession -ComputerName Server01
Invoke-Command -Session $session -ScriptBlock { Get-Process }
Enter-PSSession -Session $session # 交互式会话
Exit-PSSession
Remove-PSSession $session
远程文件传输
Copy-Item -Path "C:\local\file.txt" -Destination "\\Server01\C$\remote\" -ToSession $session
15. 错误处理进阶
自定义错误
function Test-Error {[CmdletBinding()]param()$ErrorActionPreference = "Stop"try {if (Test-Path "nonexistent") {# 业务逻辑}else {throw [System.IO.FileNotFoundException] "文件未找到"}}catch [System.IO.FileNotFoundException] {Write-Warning "特定文件未找到错误: $_"}catch {Write-Error "其他错误: $_"$PSCmdlet.ThrowTerminatingError($_)}finally {# 清理资源}
}
16. 工作流(Workflow)
workflow Backup-Files {param([string[]]$Paths)parallel {foreach -parallel ($path in $Paths) {sequence {"备份 $path"Start-Sleep -Seconds 2"完成 $path 备份"}}}
}Backup-Files -Paths "C:\Data","D:\Logs"
17. 与.NET集成
调用.NET类
[System.IO.File]::WriteAllText("C:\test.txt", "Hello .NET")
[math]::Sqrt(16) # 调用数学函数
创建自定义对象
$obj = New-Object PSObject -Property @{Name = "PowerShell"Version = $PSVersionTable.PSVersion
}
$obj | Add-Member -MemberType ScriptMethod -Name "Greet" -Value { "Hello from $($this.Name)" }
$obj.Greet()
18. 性能优化技巧
批量操作
# 低效方式
1..1000 | ForEach-Object { Get-Process -Id $_ }# 高效方式
Get-Process -Id (1..1000)
使用Where()方法代替Where-Object
# 较慢
Get-Process | Where-Object { $_.CPU -gt 100 }# 较快
(Get-Process).Where({ $_.CPU -gt 100 })
19. 安全最佳实践
安全字符串
$secureString = Read-Host "输入密码" -AsSecureString
$credential = New-Object System.Management.Automation.PSCredential ("username", $secureString)
脚本签名
$cert = New-SelfSignedCertificate -Type CodeSigningCert -Subject "CN=PowerShell Script Signing"
Set-AuthenticodeSignature -FilePath .\script.ps1 -Certificate $cert
20. 调试技巧
设置断点
Set-PSBreakpoint -Script .\script.ps1 -Line 10
Set-PSBreakpoint -Command Get-Process
调试模式
$DebugPreference = "Continue"
Write-Debug "调试信息"
使用ISE或VSCode调试
psedit .\script.ps1 # 在ISE中打开
code .\script.ps1 # 在VSCode中打开
PowerShell 的强大之处在于它的灵活性和与Windows生态系统的深度集成。掌握这些进阶技巧后,您可以构建复杂的自动化解决方案,管理系统配置,甚至开发完整的应用程序。
21. 高级模块开发
类基模块(PS 5.0+)
# MyAdvancedModule.psm1
class AdvancedCalculator {[int]$MemoryAdvancedCalculator() {$this.Memory = 0}[int] Add([int]$a, [int]$b) {return $a + $b}[void] StoreToMemory([int]$value) {$this.Memory = $value}
}function New-AdvancedCalculator {return [AdvancedCalculator]::new()
}Export-ModuleMember -Function New-AdvancedCalculator
动态模块
$module = New-Module -Name DynamicModule -ScriptBlock {function Get-DynamicData {"动态生成的数据: $(Get-Date)"}Export-ModuleMember -Function Get-DynamicData
}Import-Module $module
Get-DynamicData
22. 高级错误处理和日志
结构化错误处理
function Invoke-RobustOperation {[CmdletBinding()]param()$ErrorActionPreference = 'Stop'$WarningPreference = 'Continue'try {# 业务逻辑Write-Verbose "开始执行操作" -Verboseif (-not (Test-Path "required.file")) {Write-Warning "缺少必要文件"throw [System.IO.FileNotFoundException]::new("required.file not found")}# 模拟成功操作return @{Success=$true; Data="操作结果"}}catch [System.IO.FileNotFoundException] {Write-Error "文件系统错误: $($_.Exception.Message)" -ErrorAction Continuereturn @{Success=$false; Error="FileError"}}catch [System.UnauthorizedAccessException] {Write-Error "权限错误: $($_.Exception.Message)"return @{Success=$false; Error="AccessError"}}catch {Write-Error "未预期的错误: $($_.Exception.GetType().Name)"$PSCmdlet.ThrowTerminatingError($_)}finally {Write-Verbose "操作完成" -Verbose}
}
高级日志系统
class Logger {static [void] WriteLog([string]$Message, [string]$Level = "INFO") {$logEntry = @{Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"Level = $LevelMessage = $MessageUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name}$logJson = $logEntry | ConvertTo-Json -CompressAdd-Content -Path "C:\logs\application.log" -Value $logJson}
}# 使用日志
[Logger]::WriteLog("应用程序启动", "INFO")
[Logger]::WriteLog("检测到配置问题", "WARN")
23. 性能优化大师技巧
并行处理优化
# 使用 ForEach-Object -Parallel (PS 7+)
$computers = @('Server01', 'Server02', 'Server03')
$results = $computers | ForEach-Object -Parallel {$session = New-PSSession -ComputerName $_try {Invoke-Command -Session $session -ScriptBlock {Get-CimInstance -ClassName Win32_ComputerSystem}}finally {Remove-PSSession $session}
} -ThrottleLimit 5# 使用 Runspaces(传统并行)
$runspacePool = [RunspaceFactory]::CreateRunspacePool(1, 5)
$runspacePool.Open()$scripts = @()
1..10 | ForEach-Object {$powerShell = [PowerShell]::Create().AddScript({param($id)Start-Sleep -Seconds 2return "任务 $id 完成"}).AddArgument($_)$powerShell.RunspacePool = $runspacePool$scripts += @{PowerShell = $powerShellAsyncResult = $powerShell.BeginInvoke()}
}$results = $scripts | ForEach-Object {$_.PowerShell.EndInvoke($_.AsyncResult)
}$runspacePool.Close()
4. 安全与加密进阶
安全凭证管理
# 使用 Windows Credential Manager
function Save-SecureCredential {param([string]$Target,[PSCredential]$Credential)cmdkey /generic:$Target /user:$($Credential.UserName) /pass:$($Credential.GetNetworkCredential().Password)
}function Get-SecureCredential {param([string]$Target)$cred = cmdkey /list | Where-Object { $_ -match $Target }if ($cred) {# 解析凭证信息return $cred}
}# AES 加密数据
function Protect-Data {param([string]$Data,[string]$KeyPath = "C:\secure\key.txt")$key = New-Object Byte[] 32[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($key)$key | Set-Content $KeyPath -Encoding Byte$secureString = ConvertTo-SecureString $Data -AsPlainText -Force$encryptedData = ConvertFrom-SecureString $secureString -Key $keyreturn @{EncryptedData = $encryptedDataKeyPath = $KeyPath}
}
25. 高级文本和数据处理
自定义格式化视图
# 创建格式文件 .format.ps1xml
$formatData = @'
<Configuration><ViewDefinitions><View><Name>CustomProcessView</Name><ViewSelectedBy><TypeName>System.Diagnostics.Process</TypeName></ViewSelectedBy><TableControl><TableHeaders><TableColumnHeader><Label>进程名</Label></TableColumnHeader><TableColumnHeader><Label>CPU使用率</Label></TableColumnHeader></TableHeaders><TableRowEntries><TableRowEntry><TableColumnItems><TableColumnItem><PropertyName>ProcessName</PropertyName></TableColumnItem><TableColumnItem><ScriptBlock>{$_.CPU.ToString("N2") + " %"}</ScriptBlock></TableColumnItem></TableColumnItems></TableRowEntry></TableRowEntries></TableControl></View></ViewDefinitions>
</Configuration>
'@$formatData | Out-File -FilePath "CustomProcess.format.ps1xml"
Update-FormatData -PrependPath "CustomProcess.format.ps1xml"
26. 与 REST API 深度集成
高级 API 客户端
class ApiClient {[string]$BaseUri[hashtable]$Headers[int]$Timeout = 30ApiClient([string]$BaseUri) {$this.BaseUri = $BaseUri$this.Headers = @{'Content-Type' = 'application/json''Accept' = 'application/json'}}[pscustomobject] InvokeApi([string]$Method, [string]$Endpoint, [object]$Body) {$uri = "$($this.BaseUri)/$Endpoint"$params = @{Uri = $uriMethod = $MethodHeaders = $this.HeadersTimeoutSec = $this.TimeoutContentType = 'application/json'}if ($Body) {$params.Body = $Body | ConvertTo-Json -Depth 10}try {$response = Invoke-RestMethod @paramsreturn $response}catch {Write-Error "API调用失败: $($_.Exception.Message)"throw}}[void] AddAuthToken([string]$Token) {$this.Headers['Authorization'] = "Bearer $Token"}
}# 使用示例
$apiClient = [ApiClient]::new("https://api.example.com")
$apiClient.AddAuthToken("your-token")
$data = $apiClient.InvokeApi("GET", "users")
27. 动态参数和高级参数绑定
动态参数
function Get-DynamicData {[CmdletBinding()]param([Parameter(Mandatory=$true)][string]$DataType)dynamicparam {$paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionaryif ($DataType -eq "User") {$attribute = New-Object System.Management.Automation.ParameterAttribute$attribute.Mandatory = $true$attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]$attributeCollection.Add($attribute)$departmentParam = New-Object System.Management.Automation.RuntimeDefinedParameter("Department",[string],$attributeCollection)$paramDictionary.Add("Department", $departmentParam)}return $paramDictionary}process {# 处理逻辑}
}
28. 高级调试和诊断
性能分析器
function Measure-ScriptPerformance {param([scriptblock]$ScriptBlock,[int]$Iterations = 100)$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()$memoryBefore = [System.GC]::GetTotalMemory($true)1..$Iterations | ForEach-Object {& $ScriptBlock}$stopwatch.Stop()$memoryAfter = [System.GC]::GetTotalMemory($true)$memoryUsed = $memoryAfter - $memoryBeforereturn [PSCustomObject]@{TotalTime = $stopwatch.ElapsedAverageTime = $stopwatch.Elapsed / $IterationsMemoryUsage = $memoryUsedIterations = $Iterations}
}# 使用示例
$result = Measure-ScriptPerformance -ScriptBlock {Get-Process | Where-Object { $_.CPU -gt 10 }
} -Iterations 10
29. 跨平台高级特性(PowerShell 7+)
跨平台文件操作
function Get-CrossPlatformInfo {if ($IsWindows) {return Get-CimInstance -ClassName Win32_OperatingSystem}elseif ($IsLinux) {return Get-Content /etc/os-release | ConvertFrom-StringData}elseif ($IsMacOS) {return system_profiler SPSoftwareDataType}
}# 使用 .NET Core 的跨平台特性
function Test-IsAdministrator {if ($IsWindows) {$identity = [Security.Principal.WindowsIdentity]::GetCurrent()$principal = New-Object Security.Principal.WindowsPrincipal($identity)return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)}else {return ($(id -u) -eq 0)}
}
30. 自定义类型扩展
扩展现有类型
# 为字符串类型添加新方法
Update-TypeData -TypeName System.String -MemberType ScriptMethod -MemberName Reverse -Value {$chars = $this.ToCharArray()[array]::Reverse($chars)return -join $chars
}# 为进程对象添加计算属性
Update-TypeData -TypeName System.Diagnostics.Process -MemberType ScriptProperty -MemberName MemoryMB -Value {return [math]::Round($this.WorkingSet64 / 1MB, 2)
}# 使用扩展
"hello".Reverse() # 输出 "olleh"
(Get-Process)[0].MemoryMB # 显示内存使用(MB)