powershell-master
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePowerShell Master
PowerShell 精通指南
🚨 CRITICAL GUIDELINES
🚨 重要指南
Windows File Path Requirements
Windows 文件路径要求
MANDATORY: Always Use Backslashes on Windows for File Paths
When using Edit or Write tools on Windows, you MUST use backslashes () in file paths, NOT forward slashes ().
\/Examples:
- ❌ WRONG:
D:/repos/project/file.tsx - ✅ CORRECT:
D:\repos\project\file.tsx
This applies to:
- Edit tool file_path parameter
- Write tool file_path parameter
- All file operations on Windows systems
强制要求:在Windows系统中操作文件路径时必须使用反斜杠()
\在Windows系统中使用编辑或写入工具时,文件路径必须使用反斜杠(),不能使用正斜杠()。
\/示例:
- ❌ 错误:
D:/repos/project/file.tsx - ✅ 正确:
D:\repos\project\file.tsx
此要求适用于:
- 编辑工具的file_path参数
- 写入工具的file_path参数
- Windows系统上的所有文件操作
Documentation Guidelines
文档编写指南
NEVER create new documentation files unless explicitly requested by the user.
- Priority: Update existing README.md files rather than creating new documentation
- Repository cleanliness: Keep repository root clean - only README.md unless user requests otherwise
- Style: Documentation should be concise, direct, and professional - avoid AI-generated tone
- User preference: Only create additional .md files when user specifically asks for documentation
Complete PowerShell expertise across all platforms for scripting, automation, CI/CD, and cloud management.
除非用户明确要求,否则绝不创建新的文档文件。
- 优先级:优先更新现有README.md文件,而非创建新文档
- 仓库整洁性:保持仓库根目录整洁 - 除非用户要求,否则仅保留README.md
- 风格:文档应简洁、直接、专业 - 避免AI生成的冗余语气
- 用户偏好:仅当用户明确要求文档时,才创建额外的.md文件
跨所有平台的完整PowerShell专业能力,涵盖脚本编写、自动化、CI/CD和云管理。
🎯 When to Activate
🎯 启用场景
PROACTIVELY activate for ANY PowerShell-related task:
- ✅ PowerShell Scripts - Creating, reviewing, optimizing any .ps1 file
- ✅ Cmdlets & Modules - Finding, installing, using any PowerShell modules
- ✅ Cross-Platform - Windows, Linux, macOS PowerShell tasks
- ✅ CI/CD Integration - GitHub Actions, Azure DevOps, Bitbucket Pipelines
- ✅ Cloud Automation - Azure (Az), AWS, Microsoft 365 (Microsoft.Graph)
- ✅ Module Management - PSGallery search, installation, updates
- ✅ Script Debugging - Troubleshooting, performance, security
- ✅ Best Practices - Code quality, standards, production-ready scripts
在任何与PowerShell相关的任务中主动启用:
- ✅ PowerShell脚本 - 创建、审核、优化任何.ps1文件
- ✅ Cmdlet与模块 - 查找、安装、使用任何PowerShell模块
- ✅ 跨平台支持 - Windows、Linux、macOS系统下的PowerShell任务
- ✅ CI/CD集成 - GitHub Actions、Azure DevOps、Bitbucket流水线
- ✅ 云自动化 - Azure(Az)、AWS、Microsoft 365(Microsoft.Graph)
- ✅ 模块管理 - PSGallery搜索、安装、更新
- ✅ 脚本调试 - 故障排查、性能优化、安全检查
- ✅ 最佳实践 - 代码质量、标准规范、生产级脚本
📋 PowerShell Overview
📋 PowerShell 概述
PowerShell Versions & Platforms
PowerShell 版本与平台
PowerShell 7+ (Recommended)
- Cross-platform: Windows, Linux, macOS
- Open source, actively developed
- Better performance than PowerShell 5.1
- UTF-8 by default
- Parallel execution support
- Ternary operators, null-coalescing
Windows PowerShell 5.1 (Legacy)
- Windows-only
- Ships with Windows
- UTF-16LE default encoding
- Required for some Windows-specific modules
Installation Locations:
- Windows: (PS7) or
C:\Program Files\PowerShell\7\(5.1)C:\Windows\System32\WindowsPowerShell\v1.0\ - Linux: or
/opt/microsoft/powershell/7//usr/bin/pwsh - macOS: or
/usr/local/microsoft/powershell/7//usr/local/bin/pwsh
PowerShell 7+(推荐)
- 跨平台:Windows、Linux、macOS
- 开源、持续开发
- 性能优于PowerShell 5.1
- 默认使用UTF-8编码
- 支持并行执行
- 支持三元运算符、空合并运算符
Windows PowerShell 5.1(遗留版本)
- 仅支持Windows系统
- 随Windows系统预装
- 默认使用UTF-16LE编码
- 部分Windows专属模块依赖此版本
安装路径:
- Windows: (PS7)或
C:\Program Files\PowerShell\7\(5.1)C:\Windows\System32\WindowsPowerShell\v1.0\ - Linux: 或
/opt/microsoft/powershell/7//usr/bin/pwsh - macOS: 或
/usr/local/microsoft/powershell/7//usr/local/bin/pwsh
🔧 Cross-Platform Best Practices
🔧 跨平台最佳实践
1. Path Handling
1. 路径处理
DO:
powershell
undefined推荐做法:
powershell
undefinedUse Join-Path for cross-platform paths
Use Join-Path for cross-platform paths
$configPath = Join-Path -Path $PSScriptRoot -ChildPath "config.json"
$configPath = Join-Path -Path $PSScriptRoot -ChildPath "config.json"
Use [System.IO.Path] for path manipulation
Use [System.IO.Path] for path manipulation
$fullPath = [System.IO.Path]::Combine($home, "documents", "file.txt")
$fullPath = [System.IO.Path]::Combine($home, "documents", "file.txt")
Forward slashes work on all platforms in PowerShell 7+
Forward slashes work on all platforms in PowerShell 7+
$path = "$PSScriptRoot/subfolder/file.txt"
**DON'T:**
```powershell$path = "$PSScriptRoot/subfolder/file.txt"
**不推荐做法:**
```powershellHardcoded backslashes (Windows-only)
Hardcoded backslashes (Windows-only)
$path = "C:\Users\Name\file.txt"
$path = "C:\Users\Name\file.txt"
Assume case-insensitive file systems
Assume case-insensitive file systems
Get-ChildItem "MyFile.txt" # Works on Windows, fails on Linux/macOS if casing is wrong
undefinedGet-ChildItem "MyFile.txt" # Works on Windows, fails on Linux/macOS if casing is wrong
undefined2. Platform Detection
2. 平台检测
powershell
undefinedpowershell
undefinedUse automatic variables
Use automatic variables
if ($IsWindows) {
# Windows-specific code
$env:Path -split ';'
}
elseif ($IsLinux) {
# Linux-specific code
$env:PATH -split ':'
}
elseif ($IsMacOS) {
# macOS-specific code
$env:PATH -split ':'
}
if ($IsWindows) {
# Windows-specific code
$env:Path -split ';'
}
elseif ($IsLinux) {
# Linux-specific code
$env:PATH -split ':'
}
elseif ($IsMacOS) {
# macOS-specific code
$env:PATH -split ':'
}
Check PowerShell version
Check PowerShell version
if ($PSVersionTable.PSVersion.Major -ge 7) {
# PowerShell 7+ features
}
undefinedif ($PSVersionTable.PSVersion.Major -ge 7) {
# PowerShell 7+ features
}
undefined3. Avoid Aliases in Scripts
3. 脚本中避免使用别名
powershell
undefinedpowershell
undefinedDON'T use aliases (they may differ across platforms)
DON'T use aliases (they may differ across platforms)
ls | ? {$.Length -gt 1MB} | % {$.Name}
ls | ? {$.Length -gt 1MB} | % {$.Name}
DO use full cmdlet names
DO use full cmdlet names
Get-ChildItem | Where-Object {$.Length -gt 1MB} | ForEach-Object {$.Name}
**Why:** On Linux/macOS, aliases might invoke native commands instead of PowerShell cmdlets, causing unexpected results.Get-ChildItem | Where-Object {$.Length -gt 1MB} | ForEach-Object {$.Name}
**原因:** 在Linux/macOS系统中,别名可能会调用原生命令而非PowerShell cmdlet,导致意外结果。4. Text Encoding
4. 文本编码
powershell
undefinedpowershell
undefinedPowerShell 7+ uses UTF-8 by default
PowerShell 7+ uses UTF-8 by default
"Hello" | Out-File -FilePath output.txt
"Hello" | Out-File -FilePath output.txt
For PowerShell 5.1 compatibility, specify encoding
For PowerShell 5.1 compatibility, specify encoding
"Hello" | Out-File -FilePath output.txt -Encoding UTF8
"Hello" | Out-File -FilePath output.txt -Encoding UTF8
Best practice: Always specify encoding for cross-platform scripts
Best practice: Always specify encoding for cross-platform scripts
$content | Set-Content -Path $file -Encoding UTF8NoBOM
undefined$content | Set-Content -Path $file -Encoding UTF8NoBOM
undefined5. Environment Variables (Cross-Platform)
5. 环境变量(跨平台)
powershell
undefinedpowershell
undefinedBEST PRACTICE: Use .NET Environment class for cross-platform compatibility
BEST PRACTICE: Use .NET Environment class for cross-platform compatibility
[Environment]::UserName # Works on all platforms
[Environment]::MachineName # Works on all platforms
[IO.Path]::GetTempPath() # Works on all platforms
[Environment]::UserName # Works on all platforms
[Environment]::MachineName # Works on all platforms
[IO.Path]::GetTempPath() # Works on all platforms
AVOID: These are platform-specific
AVOID: These are platform-specific
$env:USERNAME # Windows only
$env:USER # Linux/macOS only
$env:USERNAME # Windows only
$env:USER # Linux/macOS only
Environment variable names are CASE-SENSITIVE on Linux/macOS
Environment variable names are CASE-SENSITIVE on Linux/macOS
$env:PATH # Correct on Linux/macOS
$env:Path # May not work on Linux/macOS
undefined$env:PATH # Correct on Linux/macOS
$env:Path # May not work on Linux/macOS
undefined6. Shell Detection (Windows: PowerShell vs Git Bash)
6. Shell检测(Windows:PowerShell vs Git Bash)
CRITICAL: On Windows, distinguish between PowerShell and Git Bash/MSYS2 environments:
powershell
undefined关键提示: 在Windows系统中,需区分PowerShell和Git Bash/MSYS2环境:
powershell
undefinedPowerShell detection (most reliable)
PowerShell detection (most reliable)
if ($env:PSModulePath -and ($env:PSModulePath -split ';').Count -ge 3) {
Write-Host "Running in PowerShell"
}
if ($env:PSModulePath -and ($env:PSModulePath -split ';').Count -ge 3) {
Write-Host "Running in PowerShell"
}
Platform-specific automatic variables (PowerShell 7+)
Platform-specific automatic variables (PowerShell 7+)
if ($IsWindows) {
# Windows-specific code
}
elseif ($IsLinux) {
# Linux-specific code
}
elseif ($IsMacOS) {
# macOS-specific code
}
**Git Bash/MSYS2 Detection:**
```bashif ($IsWindows) {
# Windows-specific code
}
elseif ($IsLinux) {
# Linux-specific code
}
elseif ($IsMacOS) {
# macOS-specific code
}
**Git Bash/MSYS2检测:**
```bashBash detection - check MSYSTEM environment variable
Bash detection - check MSYSTEM environment variable
if [ -n "$MSYSTEM" ]; then
echo "Running in Git Bash/MSYS2: $MSYSTEM"
# MSYSTEM values: MINGW64, MINGW32, MSYS
fi
**When to Use Each Shell:**
- **PowerShell:** Windows automation, Azure/M365, PSGallery modules, object pipelines
- **Git Bash:** Git operations, Unix tools (sed/awk/grep), POSIX scripts, text processing
**Path Handling Differences:**
- **PowerShell:** `C:\Users\John` or `C:/Users/John` (both work in PS 7+)
- **Git Bash:** `/c/Users/John` (Unix-style, auto-converts to Windows when calling Windows tools)
See `powershell-shell-detection` skill for comprehensive cross-shell guidance.if [ -n "$MSYSTEM" ]; then
echo "Running in Git Bash/MSYS2: $MSYSTEM"
# MSYSTEM values: MINGW64, MINGW32, MSYS
fi
**各Shell适用场景:**
- **PowerShell:** Windows自动化、Azure/M365管理、PSGallery模块、对象流水线
- **Git Bash:** Git操作、Unix工具(sed/awk/grep)、POSIX脚本、文本处理
**路径处理差异:**
- **PowerShell:** `C:\Users\John` 或 `C:/Users/John`(在PS 7+中均有效)
- **Git Bash:** `/c/Users/John`(Unix风格,调用Windows工具时自动转换)
如需全面的跨Shell指导,请查看`powershell-shell-detection`技能。7. Line Endings
7. 行尾格式
powershell
undefinedpowershell
undefinedPowerShell handles line endings automatically
PowerShell handles line endings automatically
But be explicit for git or cross-platform tools
But be explicit for git or cross-platform tools
git config core.autocrlf input # Linux/macOS
git config core.autocrlf true # Windows
---git config core.autocrlf input # Linux/macOS
git config core.autocrlf true # Windows
---📦 Module Management (PSResourceGet & PSGallery)
📦 模块管理(PSResourceGet & PSGallery)
PSResourceGet - Modern Package Manager (2025)
PSResourceGet - 现代包管理器(2025)
PSResourceGet is 2x faster than PowerShellGet and actively maintained:
powershell
undefinedPSResourceGet 比PowerShellGet快2倍,且持续维护:
powershell
undefinedPSResourceGet ships with PowerShell 7.4+ (or install manually)
PSResourceGet ships with PowerShell 7.4+ (or install manually)
Install-Module -Name Microsoft.PowerShell.PSResourceGet -Force
Install-Module -Name Microsoft.PowerShell.PSResourceGet -Force
Modern commands (PSResourceGet)
Modern commands (PSResourceGet)
Install-PSResource -Name Az -Scope CurrentUser # 2x faster
Find-PSResource -Name "Azure" # Faster search
Update-PSResource -Name Az # Batch updates
Get-InstalledPSResource # List installed
Uninstall-PSResource -Name OldModule # Clean uninstall
Install-PSResource -Name Az -Scope CurrentUser # 2x faster
Find-PSResource -Name "Azure" # Faster search
Update-PSResource -Name Az # Batch updates
Get-InstalledPSResource # List installed
Uninstall-PSResource -Name OldModule # Clean uninstall
Compatibility: Your old Install-Module commands still work
Compatibility: Your old Install-Module commands still work
They automatically call PSResourceGet internally
They automatically call PSResourceGet internally
Install-Module -Name Az -Scope CurrentUser # Works, uses PSResourceGet
undefinedInstall-Module -Name Az -Scope CurrentUser # Works, uses PSResourceGet
undefinedFinding Modules
查找模块
powershell
undefinedpowershell
undefinedPSResourceGet (Modern)
PSResourceGet (Modern)
Find-PSResource -Name "Azure"
Find-PSResource -Tag "Security"
Find-PSResource -Name Az | Select-Object Name, Version, PublishedDate
Find-PSResource -Name "Azure"
Find-PSResource -Tag "Security"
Find-PSResource -Name Az | Select-Object Name, Version, PublishedDate
Legacy PowerShellGet (still works)
Legacy PowerShellGet (still works)
Find-Module -Name "Azure"
Find-Command -Name Get-AzVM
undefinedFind-Module -Name "Azure"
Find-Command -Name Get-AzVM
undefinedInstalling Modules
安装模块
powershell
undefinedpowershell
undefinedRECOMMENDED: PSResourceGet (2x faster)
RECOMMENDED: PSResourceGet (2x faster)
Install-PSResource -Name Az -Scope CurrentUser -TrustRepository
Install-PSResource -Name Microsoft.Graph -Version 2.32.0
Install-PSResource -Name Az -Scope CurrentUser -TrustRepository
Install-PSResource -Name Microsoft.Graph -Version 2.32.0
Legacy: PowerShellGet (slower, but still works)
Legacy: PowerShellGet (slower, but still works)
Install-Module -Name Az -Scope CurrentUser -Force
Install-Module -Name Pester -Scope AllUsers # Requires elevation
undefinedInstall-Module -Name Az -Scope CurrentUser -Force
Install-Module -Name Pester -Scope AllUsers # Requires elevation
undefinedManaging Installed Modules
管理已安装模块
powershell
undefinedpowershell
undefinedList installed (PSResourceGet)
List installed (PSResourceGet)
Get-InstalledPSResource
Get-InstalledPSResource -Name Az
Get-InstalledPSResource
Get-InstalledPSResource -Name Az
Update modules (PSResourceGet)
Update modules (PSResourceGet)
Update-PSResource -Name Az
Update-PSResource # Updates all
Update-PSResource -Name Az
Update-PSResource # Updates all
Uninstall (PSResourceGet)
Uninstall (PSResourceGet)
Uninstall-PSResource -Name OldModule -AllVersions
Uninstall-PSResource -Name OldModule -AllVersions
Import module
Import module
Import-Module -Name Az.Accounts
undefinedImport-Module -Name Az.Accounts
undefinedOffline Installation
离线安装
powershell
undefinedpowershell
undefinedSave module (works with both)
Save module (works with both)
Save-PSResource -Name Az -Path C:\OfflineModules
Save-PSResource -Name Az -Path C:\OfflineModules
Or: Save-Module -Name Az -Path C:\OfflineModules
Or: Save-Module -Name Az -Path C:\OfflineModules
Install from saved location
Install from saved location
Install-PSResource -Name Az -Path C:\OfflineModules
---Install-PSResource -Name Az -Path C:\OfflineModules
---🌟 Popular PowerShell Modules
🌟 热门PowerShell模块
Azure (Az Module 14.5.0)
Azure(Az Module 14.5.0)
Latest: Az 14.5.0 (October 2025) with zone redundancy and symbolic links
powershell
undefined最新版本: Az 14.5.0(2025年10月),支持区域冗余和符号链接
powershell
undefinedInstall Azure module 14.5.0
Install Azure module 14.5.0
Install-PSResource -Name Az -Scope CurrentUser
Install-PSResource -Name Az -Scope CurrentUser
Or: Install-Module -Name Az -Scope CurrentUser -Force
Or: Install-Module -Name Az -Scope CurrentUser -Force
Connect to Azure
Connect to Azure
Connect-AzAccount
Connect-AzAccount
Common operations
Common operations
Get-AzVM
Get-AzResourceGroup
New-AzResourceGroup -Name "MyRG" -Location "EastUS"
Get-AzVM
Get-AzResourceGroup
New-AzResourceGroup -Name "MyRG" -Location "EastUS"
NEW in Az 14.5: Zone redundancy for storage
NEW in Az 14.5: Zone redundancy for storage
New-AzStorageAccount -ResourceGroupName "MyRG" -Name "storage123" `
-Location "EastUS" -SkuName "Standard_LRS" -EnableZoneRedundancy
New-AzStorageAccount -ResourceGroupName "MyRG" -Name "storage123" `
-Location "EastUS" -SkuName "Standard_LRS" -EnableZoneRedundancy
NEW in Az 14.5: Symbolic links in NFS File Share
NEW in Az 14.5: Symbolic links in NFS File Share
New-AzStorageFileSymbolicLink -Context $ctx -ShareName "nfsshare" `
-Path "symlink" -Target "/target/path"
**Key Submodules:**
- `Az.Accounts` - Authentication (MFA required Sep 2025+)
- `Az.Compute` - VMs, scale sets
- `Az.Storage` - Storage accounts (zone redundancy support)
- `Az.Network` - Virtual networks, NSGs
- `Az.KeyVault` - Key Vault operations
- `Az.Resources` - Resource groups, deploymentsNew-AzStorageFileSymbolicLink -Context $ctx -ShareName "nfsshare" `
-Path "symlink" -Target "/target/path"
**核心子模块:**
- `Az.Accounts` - 身份验证(2025年9月起强制要求MFA)
- `Az.Compute` - 虚拟机、规模集
- `Az.Storage` - 存储账户(支持区域冗余)
- `Az.Network` - 虚拟网络、网络安全组
- `Az.KeyVault` - 密钥保管库操作
- `Az.Resources` - 资源组、部署Microsoft Graph (Microsoft.Graph 2.32.0)
Microsoft Graph(Microsoft.Graph 2.32.0)
CRITICAL: MSOnline and AzureAD modules retired (March-May 2025). Use Microsoft.Graph instead.
powershell
undefined关键提示: MSOnline和AzureAD模块已退役(2025年3-5月)。请使用Microsoft.Graph替代。
powershell
undefinedInstall Microsoft Graph 2.32.0 (October 2025)
Install Microsoft Graph 2.32.0 (October 2025)
Install-PSResource -Name Microsoft.Graph -Scope CurrentUser
Install-PSResource -Name Microsoft.Graph -Scope CurrentUser
Or: Install-Module -Name Microsoft.Graph -Scope CurrentUser
Or: Install-Module -Name Microsoft.Graph -Scope CurrentUser
Connect with required scopes
Connect with required scopes
Connect-MgGraph -Scopes "User.Read.All", "Group.ReadWrite.All"
Connect-MgGraph -Scopes "User.Read.All", "Group.ReadWrite.All"
Common operations
Common operations
Get-MgUser
Get-MgGroup
New-MgUser -DisplayName "John Doe" -UserPrincipalName "john@domain.com" -MailNickname "john"
Get-MgTeam
Get-MgUser
Get-MgGroup
New-MgUser -DisplayName "John Doe" -UserPrincipalName "john@domain.com" -MailNickname "john"
Get-MgTeam
Migration from AzureAD/MSOnline
Migration from AzureAD/MSOnline
OLD: Connect-AzureAD / Connect-MsolService
OLD: Connect-AzureAD / Connect-MsolService
NEW: Connect-MgGraph
NEW: Connect-MgGraph
OLD: Get-AzureADUser / Get-MsolUser
OLD: Get-AzureADUser / Get-MsolUser
NEW: Get-MgUser
NEW: Get-MgUser
undefinedundefinedPnP PowerShell (SharePoint/Teams)
PnP PowerShell(SharePoint/Teams)
powershell
undefinedpowershell
undefinedInstall PnP PowerShell
Install PnP PowerShell
Install-Module -Name PnP.PowerShell -Scope CurrentUser
Install-Module -Name PnP.PowerShell -Scope CurrentUser
Connect to SharePoint Online
Connect to SharePoint Online
Connect-PnPOnline -Url "https://tenant.sharepoint.com/sites/site" -Interactive
Connect-PnPOnline -Url "https://tenant.sharepoint.com/sites/site" -Interactive
Common operations
Common operations
Get-PnPList
Get-PnPFile -Url "/sites/site/Shared Documents/file.docx"
Add-PnPListItem -List "Tasks" -Values @{"Title"="New Task"}
undefinedGet-PnPList
Get-PnPFile -Url "/sites/site/Shared Documents/file.docx"
Add-PnPListItem -List "Tasks" -Values @{"Title"="New Task"}
undefinedAWS Tools for PowerShell
AWS Tools for PowerShell
powershell
undefinedpowershell
undefinedInstall AWS Tools
Install AWS Tools
Install-Module -Name AWS.Tools.Installer -Force
Install-AWSToolsModule AWS.Tools.EC2,AWS.Tools.S3
Install-Module -Name AWS.Tools.Installer -Force
Install-AWSToolsModule AWS.Tools.EC2,AWS.Tools.S3
Configure credentials
Configure credentials
Set-AWSCredential -AccessKey $accessKey -SecretKey $secretKey -StoreAs default
Set-AWSCredential -AccessKey $accessKey -SecretKey $secretKey -StoreAs default
Common operations
Common operations
Get-EC2Instance
Get-S3Bucket
New-S3Bucket -BucketName "my-bucket"
undefinedGet-EC2Instance
Get-S3Bucket
New-S3Bucket -BucketName "my-bucket"
undefinedOther Popular Modules
其他热门模块
powershell
undefinedpowershell
undefinedPester (Testing framework)
Pester (Testing framework)
Install-Module -Name Pester -Force
Install-Module -Name Pester -Force
PSScriptAnalyzer (Code analysis)
PSScriptAnalyzer (Code analysis)
Install-Module -Name PSScriptAnalyzer
Install-Module -Name PSScriptAnalyzer
ImportExcel (Excel manipulation without Excel)
ImportExcel (Excel manipulation without Excel)
Install-Module -Name ImportExcel
Install-Module -Name ImportExcel
PowerShellGet 3.x (Modern package management)
PowerShellGet 3.x (Modern package management)
Install-Module -Name Microsoft.PowerShell.PSResourceGet
---Install-Module -Name Microsoft.PowerShell.PSResourceGet
---🚀 CI/CD Integration
🚀 CI/CD 集成
GitHub Actions
GitHub Actions
yaml
name: PowerShell CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install PowerShell modules
shell: pwsh
run: |
Install-Module -Name Pester -Force -Scope CurrentUser
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser
- name: Run Pester tests
shell: pwsh
run: |
Invoke-Pester -Path ./tests -OutputFormat NUnitXml -OutputFile TestResults.xml
- name: Run PSScriptAnalyzer
shell: pwsh
run: |
Invoke-ScriptAnalyzer -Path . -Recurse -ReportSummaryMulti-Platform Matrix:
yaml
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Test on ${{ matrix.os }}
shell: pwsh
run: |
./test-script.ps1yaml
name: PowerShell CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install PowerShell modules
shell: pwsh
run: |
Install-Module -Name Pester -Force -Scope CurrentUser
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser
- name: Run Pester tests
shell: pwsh
run: |
Invoke-Pester -Path ./tests -OutputFormat NUnitXml -OutputFile TestResults.xml
- name: Run PSScriptAnalyzer
shell: pwsh
run: |
Invoke-ScriptAnalyzer -Path . -Recurse -ReportSummary多平台矩阵:
yaml
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Test on ${{ matrix.os }}
shell: pwsh
run: |
./test-script.ps1Azure DevOps Pipelines
Azure DevOps 流水线
yaml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
Install-Module -Name Pester -Force -Scope CurrentUser
Invoke-Pester -Path ./tests -OutputFormat NUnitXml
displayName: 'Run Pester Tests'
- task: PowerShell@2
inputs:
filePath: '$(System.DefaultWorkingDirectory)/build.ps1'
arguments: '-Configuration Release'
displayName: 'Run Build Script'
- task: PublishTestResults@2
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '**/TestResults.xml'Cross-Platform Pipeline:
yaml
strategy:
matrix:
linux:
imageName: 'ubuntu-latest'
windows:
imageName: 'windows-latest'
mac:
imageName: 'macos-latest'
pool:
vmImage: $(imageName)
steps:
- pwsh: |
Write-Host "Running on $($PSVersionTable.OS)"
./test-script.ps1
displayName: 'Cross-platform test'yaml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
Install-Module -Name Pester -Force -Scope CurrentUser
Invoke-Pester -Path ./tests -OutputFormat NUnitXml
displayName: 'Run Pester Tests'
- task: PowerShell@2
inputs:
filePath: '$(System.DefaultWorkingDirectory)/build.ps1'
arguments: '-Configuration Release'
displayName: 'Run Build Script'
- task: PublishTestResults@2
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '**/TestResults.xml'跨平台流水线:
yaml
strategy:
matrix:
linux:
imageName: 'ubuntu-latest'
windows:
imageName: 'windows-latest'
mac:
imageName: 'macos-latest'
pool:
vmImage: $(imageName)
steps:
- pwsh: |
Write-Host "Running on $($PSVersionTable.OS)"
./test-script.ps1
displayName: 'Cross-platform test'Bitbucket Pipelines
Bitbucket 流水线
yaml
image: mcr.microsoft.com/powershell:latest
pipelines:
default:
- step:
name: Test with PowerShell
script:
- pwsh -Command "Install-Module -Name Pester -Force"
- pwsh -Command "Invoke-Pester -Path ./tests"
- step:
name: Deploy
deployment: production
script:
- pwsh -File ./deploy.ps1yaml
image: mcr.microsoft.com/powershell:latest
pipelines:
default:
- step:
name: Test with PowerShell
script:
- pwsh -Command "Install-Module -Name Pester -Force"
- pwsh -Command "Invoke-Pester -Path ./tests"
- step:
name: Deploy
deployment: production
script:
- pwsh -File ./deploy.ps1💻 PowerShell Syntax & Cmdlets
💻 PowerShell 语法与Cmdlet
Cmdlet Structure
Cmdlet 结构
powershell
undefinedpowershell
undefinedVerb-Noun pattern
Verb-Noun pattern
Get-ChildItem
Set-Location
New-Item
Remove-Item
Get-ChildItem
Set-Location
New-Item
Remove-Item
Common parameters (available on all cmdlets)
Common parameters (available on all cmdlets)
Get-Process -Verbose
Set-Content -Path file.txt -WhatIf
Remove-Item -Path folder -Confirm
Invoke-RestMethod -Uri $url -ErrorAction Stop
undefinedGet-Process -Verbose
Set-Content -Path file.txt -WhatIf
Remove-Item -Path folder -Confirm
Invoke-RestMethod -Uri $url -ErrorAction Stop
undefinedVariables & Data Types
变量与数据类型
powershell
undefinedpowershell
undefinedVariables (loosely typed)
Variables (loosely typed)
$string = "Hello World"
$number = 42
$array = @(1, 2, 3, 4, 5)
$hashtable = @{Name="John"; Age=30}
$string = "Hello World"
$number = 42
$array = @(1, 2, 3, 4, 5)
$hashtable = @{Name="John"; Age=30}
Strongly typed
Strongly typed
[string]$name = "John"
[int]$age = 30
[datetime]$date = Get-Date
[string]$name = "John"
[int]$age = 30
[datetime]$date = Get-Date
Special variables
Special variables
$PSScriptRoot # Directory containing the script
$PSCommandPath # Full path to the script
$args # Script arguments
$_ # Current pipeline object
undefined$PSScriptRoot # Directory containing the script
$PSCommandPath # Full path to the script
$args # Script arguments
$_ # Current pipeline object
undefinedOperators
运算符
powershell
undefinedpowershell
undefinedComparison operators
Comparison operators
-eq # Equal
-ne # Not equal
-gt # Greater than
-lt # Less than
-match # Regex match
-like # Wildcard match
-contains # Array contains
-eq # Equal
-ne # Not equal
-gt # Greater than
-lt # Less than
-match # Regex match
-like # Wildcard match
-contains # Array contains
Logical operators
Logical operators
-and
-or
-not
-and
-or
-not
PowerShell 7+ ternary operator
PowerShell 7+ ternary operator
$result = $condition ? "true" : "false"
$result = $condition ? "true" : "false"
Null-coalescing (PS 7+)
Null-coalescing (PS 7+)
$value = $null ?? "default"
undefined$value = $null ?? "default"
undefinedControl Flow
控制流
powershell
undefinedpowershell
undefinedIf-ElseIf-Else
If-ElseIf-Else
if ($condition) {
# Code
} elseif ($otherCondition) {
# Code
} else {
# Code
}
if ($condition) {
# Code
} elseif ($otherCondition) {
# Code
} else {
# Code
}
Switch
Switch
switch ($value) {
1 { "One" }
2 { "Two" }
{$_ -gt 10} { "Greater than 10" }
default { "Other" }
}
switch ($value) {
1 { "One" }
2 { "Two" }
{$_ -gt 10} { "Greater than 10" }
default { "Other" }
}
Loops
Loops
foreach ($item in $collection) {
# Process item
}
for ($i = 0; $i -lt 10; $i++) {
# Loop code
}
while ($condition) {
# Loop code
}
do {
# Loop code
} while ($condition)
undefinedforeach ($item in $collection) {
# Process item
}
for ($i = 0; $i -lt 10; $i++) {
# Loop code
}
while ($condition) {
# Loop code
}
do {
# Loop code
} while ($condition)
undefinedFunctions
函数
powershell
function Get-Something {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$Name,
[Parameter()]
[int]$Count = 1,
[Parameter(ValueFromPipeline=$true)]
[string[]]$InputObject
)
begin {
# Initialization
}
process {
# Process each pipeline object
foreach ($item in $InputObject) {
# Work with $item
}
}
end {
# Cleanup
return $result
}
}powershell
function Get-Something {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$Name,
[Parameter()]
[int]$Count = 1,
[Parameter(ValueFromPipeline=$true)]
[string[]]$InputObject
)
begin {
# Initialization
}
process {
# Process each pipeline object
foreach ($item in $InputObject) {
# Work with $item
}
}
end {
# Cleanup
return $result
}
}Pipeline & Filtering
流水线与过滤
powershell
undefinedpowershell
undefinedPipeline basics
Pipeline basics
Get-Process | Where-Object {$_.CPU -gt 100} | Select-Object Name, CPU
Get-Process | Where-Object {$_.CPU -gt 100} | Select-Object Name, CPU
Simplified syntax (PS 3.0+)
Simplified syntax (PS 3.0+)
Get-Process | Where CPU -gt 100 | Select Name, CPU
Get-Process | Where CPU -gt 100 | Select Name, CPU
ForEach-Object
ForEach-Object
Get-ChildItem | ForEach-Object {
Write-Host $_.Name
}
Get-ChildItem | ForEach-Object {
Write-Host $_.Name
}
Simplified (PS 4.0+)
Simplified (PS 4.0+)
Get-ChildItem | % Name
Get-ChildItem | % Name
Group, Sort, Measure
Group, Sort, Measure
Get-Process | Group-Object ProcessName
Get-Service | Sort-Object Status
Get-ChildItem | Measure-Object -Property Length -Sum
undefinedGet-Process | Group-Object ProcessName
Get-Service | Sort-Object Status
Get-ChildItem | Measure-Object -Property Length -Sum
undefinedError Handling
错误处理
powershell
undefinedpowershell
undefinedTry-Catch-Finally
Try-Catch-Finally
try {
Get-Content -Path "nonexistent.txt" -ErrorAction Stop
}
catch [System.IO.FileNotFoundException] {
Write-Error "File not found"
}
catch {
Write-Error "An error occurred: $_"
}
finally {
# Cleanup code
}
try {
Get-Content -Path "nonexistent.txt" -ErrorAction Stop
}
catch [System.IO.FileNotFoundException] {
Write-Error "File not found"
}
catch {
Write-Error "An error occurred: $_"
}
finally {
# Cleanup code
}
Error action preference
Error action preference
$ErrorActionPreference = "Stop" # Treat all errors as terminating
$ErrorActionPreference = "Continue" # Default
$ErrorActionPreference = "SilentlyContinue" # Suppress errors
---$ErrorActionPreference = "Stop" # Treat all errors as terminating
$ErrorActionPreference = "Continue" # Default
$ErrorActionPreference = "SilentlyContinue" # Suppress errors
---🔒 Security Best Practices (2025 Standards)
🔒 安全最佳实践(2025标准)
Modern Security Framework (JEA + WDAC + Logging)
现代安全框架(JEA + WDAC + 日志记录)
2025 Security Requirements:
- JEA - Just Enough Administration for role-based access
- WDAC - Windows Defender Application Control for script approval
- Constrained Language Mode - For non-admin users
- Script Block Logging - For audit trails
2025年安全要求:
- JEA - 最小权限管理(Just Enough Administration),基于角色的访问控制
- WDAC - Windows Defender应用控制,用于脚本审批
- 受限语言模式 - 针对非管理员用户
- 脚本块日志 - 用于审计追踪
Just Enough Administration (JEA)
最小权限管理(JEA)
Required for production environments in 2025:
powershell
undefined2025年生产环境强制要求:
powershell
undefinedCreate JEA session configuration file
Create JEA session configuration file
New-PSSessionConfigurationFile -SessionType RestrictedRemoteServer
-VisibleCmdlets @{
Name = 'Restart-Service'
Parameters = @{ Name = 'Name'; ValidateSet = 'Spooler', 'Wuauserv' }
}, @{
Name = 'Get-Service'
}
-ExecutionPolicy RemoteSigned
-Path "C:\JEA\HelpDesk.pssc" -LanguageMode NoLanguageNew-PSSessionConfigurationFile -SessionType RestrictedRemoteServer
-VisibleCmdlets @{
Name = 'Restart-Service'
Parameters = @{ Name = 'Name'; ValidateSet = 'Spooler', 'Wuauserv' }
}, @{
Name = 'Get-Service'
}
-ExecutionPolicy RemoteSigned
-Path "C:\JEA\HelpDesk.pssc" -LanguageMode NoLanguageRegister JEA endpoint
Register JEA endpoint
Register-PSSessionConfiguration -Name HelpDesk
-Force
-Path "C:\JEA\HelpDesk.pssc"Register-PSSessionConfiguration -Name HelpDesk
-Force
-Path "C:\JEA\HelpDesk.pssc"Connect with limited privileges
Connect with limited privileges
Enter-PSSession -ComputerName Server01 -ConfigurationName HelpDesk
undefinedEnter-PSSession -ComputerName Server01 -ConfigurationName HelpDesk
undefinedWindows Defender Application Control (WDAC)
Windows Defender应用控制(WDAC)
Replaces AppLocker for PowerShell script control:
powershell
undefined替代AppLocker用于PowerShell脚本控制:
powershell
undefinedCreate WDAC policy for approved scripts
Create WDAC policy for approved scripts
New-CIPolicy -FilePath "C:\WDAC\PowerShellPolicy.xml"
-Level FilePublisher `
-Fallback Hash
-ScanPath "C:\ApprovedScripts"New-CIPolicy -FilePath "C:\WDAC\PowerShellPolicy.xml"
-Level FilePublisher `
-Fallback Hash
-ScanPath "C:\ApprovedScripts"Convert to binary
Convert to binary
ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\PowerShellPolicy.xml" `
-BinaryFilePath "C:\Windows\System32\CodeIntegrity\SIPolicy.p7b"
ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\PowerShellPolicy.xml" `
-BinaryFilePath "C:\Windows\System32\CodeIntegrity\SIPolicy.p7b"
Deploy via Group Policy or MDM
Deploy via Group Policy or MDM
undefinedundefinedConstrained Language Mode
受限语言模式
Recommended for all non-admin users:
powershell
undefined推荐所有非管理员用户使用:
powershell
undefinedCheck current language mode
Check current language mode
$ExecutionContext.SessionState.LanguageMode
$ExecutionContext.SessionState.LanguageMode
Output: FullLanguage (admin) or ConstrainedLanguage (standard user)
Output: FullLanguage (admin) or ConstrainedLanguage (standard user)
Enable system-wide via environment variable
Enable system-wide via environment variable
[Environment]::SetEnvironmentVariable(
"__PSLockdownPolicy",
"4",
[System.EnvironmentVariableTarget]::Machine
)
undefined[Environment]::SetEnvironmentVariable(
"__PSLockdownPolicy",
"4",
[System.EnvironmentVariableTarget]::Machine
)
undefinedScript Block Logging
脚本块日志
Enable for security auditing:
powershell
undefined启用用于安全审计:
powershell
undefinedEnable via Group Policy or Registry
Enable via Group Policy or Registry
HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging
HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging
EnableScriptBlockLogging = 1
EnableScriptBlockLogging = 1
EnableScriptBlockInvocationLogging = 1
EnableScriptBlockInvocationLogging = 1
Check logs
Check logs
Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" |
Where-Object Id -eq 4104 | # Script Block Logging
Select-Object TimeCreated, Message -First 10
undefinedGet-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" |
Where-Object Id -eq 4104 | # Script Block Logging
Select-Object TimeCreated, Message -First 10
undefinedExecution Policy
执行策略
powershell
undefinedpowershell
undefinedCheck current execution policy
Check current execution policy
Get-ExecutionPolicy
Get-ExecutionPolicy
Set for current user (no admin needed)
Set for current user (no admin needed)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Bypass for single session (use sparingly)
Bypass for single session (use sparingly)
pwsh -ExecutionPolicy Bypass -File script.ps1
undefinedpwsh -ExecutionPolicy Bypass -File script.ps1
undefinedCredential Management
凭据管理
powershell
undefinedpowershell
undefinedNEVER hardcode credentials
NEVER hardcode credentials
BAD: $password = "MyP@ssw0rd"
BAD: $password = "MyP@ssw0rd"
Use SecretManagement module (modern approach)
Use SecretManagement module (modern approach)
Install-PSResource -Name Microsoft.PowerShell.SecretManagement
Install-PSResource -Name SecretManagement.KeyVault
Register-SecretVault -Name AzureKeyVault -ModuleName SecretManagement.KeyVault
$secret = Get-Secret -Name "DatabasePassword" -Vault AzureKeyVault
Install-PSResource -Name Microsoft.PowerShell.SecretManagement
Install-PSResource -Name SecretManagement.KeyVault
Register-SecretVault -Name AzureKeyVault -ModuleName SecretManagement.KeyVault
$secret = Get-Secret -Name "DatabasePassword" -Vault AzureKeyVault
Legacy: Get-Credential for interactive
Legacy: Get-Credential for interactive
$cred = Get-Credential
$cred = Get-Credential
Azure Key Vault for production
Azure Key Vault for production
$vaultName = "MyKeyVault"
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name "DatabasePassword"
$secret.SecretValue
undefined$vaultName = "MyKeyVault"
$secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name "DatabasePassword"
$secret.SecretValue
undefinedInput Validation
输入验证
powershell
function Do-Something {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$Name,
[Parameter()]
[ValidateRange(1, 100)]
[int]$Count,
[Parameter()]
[ValidateSet("Option1", "Option2", "Option3")]
[string]$Option,
[Parameter()]
[ValidatePattern('^\d{3}-\d{3}-\d{4}$')]
[string]$PhoneNumber
)
}powershell
function Do-Something {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$Name,
[Parameter()]
[ValidateRange(1, 100)]
[int]$Count,
[Parameter()]
[ValidateSet("Option1", "Option2", "Option3")]
[string]$Option,
[Parameter()]
[ValidatePattern('^\d{3}-\d{3}-\d{4}$')]
[string]$PhoneNumber
)
}Code Signing (Production)
代码签名(生产环境)
powershell
undefinedpowershell
undefinedGet code signing certificate
Get code signing certificate
$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert
$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert
Sign script
Sign script
Set-AuthenticodeSignature -FilePath script.ps1 -Certificate $cert
---Set-AuthenticodeSignature -FilePath script.ps1 -Certificate $cert
---⚡ Performance Optimization
⚡ 性能优化
PowerShell 7+ Features
PowerShell 7+ 特性
powershell
undefinedpowershell
undefinedParallel ForEach (PS 7+)
Parallel ForEach (PS 7+)
1..10 | ForEach-Object -Parallel {
Start-Sleep -Seconds 1
"Processed $_"
} -ThrottleLimit 5
1..10 | ForEach-Object -Parallel {
Start-Sleep -Seconds 1
"Processed $_"
} -ThrottleLimit 5
Ternary operator
Ternary operator
$result = $value ? "true" : "false"
$result = $value ? "true" : "false"
Null-coalescing
Null-coalescing
$name = $userName ?? "default"
$name = $userName ?? "default"
Null-conditional member access
Null-conditional member access
$length = $string?.Length
undefined$length = $string?.Length
undefinedEfficient Filtering
高效过滤
powershell
undefinedpowershell
undefinedUse .NET methods for performance
Use .NET methods for performance
Instead of: Get-Content large.txt | Where-Object {$_ -match "pattern"}
Instead of: Get-Content large.txt | Where-Object {$_ -match "pattern"}
[System.IO.File]::ReadLines("large.txt") | Where-Object {$_ -match "pattern"}
[System.IO.File]::ReadLines("large.txt") | Where-Object {$_ -match "pattern"}
Use -Filter parameter when available
Use -Filter parameter when available
Get-ChildItem -Path C:\ -Filter *.log -Recurse
Get-ChildItem -Path C:\ -Filter *.log -Recurse
Instead of: Get-ChildItem -Path C:\ -Recurse | Where-Object {$_.Extension -eq ".log"}
Instead of: Get-ChildItem -Path C:\ -Recurse | Where-Object {$_.Extension -eq ".log"}
undefinedundefinedArrayList vs Array
ArrayList vs Array
powershell
undefinedpowershell
undefinedArrays are immutable - slow for additions
Arrays are immutable - slow for additions
$array = @()
1..1000 | ForEach-Object { $array += $_ } # SLOW
$array = @()
1..1000 | ForEach-Object { $array += $_ } # SLOW
Use ArrayList for dynamic collections
Use ArrayList for dynamic collections
$list = [System.Collections.ArrayList]::new()
1..1000 | ForEach-Object { [void]$list.Add($_) } # FAST
$list = [System.Collections.ArrayList]::new()
1..1000 | ForEach-Object { [void]$list.Add($_) } # FAST
Or use generic List
Or use generic List
$list = [System.Collections.Generic.List[int]]::new()
1..1000 | ForEach-Object { $list.Add($_) }
---$list = [System.Collections.Generic.List[int]]::new()
1..1000 | ForEach-Object { $list.Add($_) }
---🧪 Testing with Pester
🧪 使用Pester进行测试
powershell
undefinedpowershell
undefinedInstall Pester
Install Pester
Install-Module -Name Pester -Force
Install-Module -Name Pester -Force
Basic test structure
Basic test structure
Describe "Get-Something Tests" {
Context "When input is valid" {
It "Should return expected value" {
$result = Get-Something -Name "Test"
$result | Should -Be "Expected"
}
}
Context "When input is invalid" {
It "Should throw an error" {
{ Get-Something -Name $null } | Should -Throw
}
}}
Describe "Get-Something Tests" {
Context "When input is valid" {
It "Should return expected value" {
$result = Get-Something -Name "Test"
$result | Should -Be "Expected"
}
}
Context "When input is invalid" {
It "Should throw an error" {
{ Get-Something -Name $null } | Should -Throw
}
}}
Run tests
Run tests
Invoke-Pester -Path ./tests
Invoke-Pester -Path ./tests -OutputFormat NUnitXml -OutputFile TestResults.xml
Invoke-Pester -Path ./tests
Invoke-Pester -Path ./tests -OutputFormat NUnitXml -OutputFile TestResults.xml
Code coverage
Code coverage
Invoke-Pester -Path ./tests -CodeCoverage ./src/*.ps1
---Invoke-Pester -Path ./tests -CodeCoverage ./src/*.ps1
---📝 Script Requirements & Versioning
📝 脚本要求与版本控制
powershell
undefinedpowershell
undefinedRequire specific PowerShell version
Require specific PowerShell version
#Requires -Version 7.0
#Requires -Version 7.0
Require modules
Require modules
#Requires -Modules Az.Accounts, Az.Compute
#Requires -Modules Az.Accounts, Az.Compute
Require admin/elevated privileges (Windows)
Require admin/elevated privileges (Windows)
#Requires -RunAsAdministrator
#Requires -RunAsAdministrator
Combine multiple requirements
Combine multiple requirements
#Requires -Version 7.0
#Requires -Modules @{ModuleName='Pester'; ModuleVersion='5.0.0'}
#Requires -Version 7.0
#Requires -Modules @{ModuleName='Pester'; ModuleVersion='5.0.0'}
Use strict mode
Use strict mode
Set-StrictMode -Version Latest
---Set-StrictMode -Version Latest
---🎓 Common Cmdlets Reference
🎓 常用Cmdlet参考
File System
文件系统
powershell
Get-ChildItem (gci, ls, dir)
Set-Location (cd, sl)
New-Item (ni)
Remove-Item (rm, del)
Copy-Item (cp, copy)
Move-Item (mv, move)
Rename-Item (rn, ren)
Get-Content (gc, cat, type)
Set-Content (sc)
Add-Content (ac)powershell
Get-ChildItem (gci, ls, dir)
Set-Location (cd, sl)
New-Item (ni)
Remove-Item (rm, del)
Copy-Item (cp, copy)
Move-Item (mv, move)
Rename-Item (rn, ren)
Get-Content (gc, cat, type)
Set-Content (sc)
Add-Content (ac)Process Management
进程管理
powershell
Get-Process (ps, gps)
Stop-Process (kill, spps)
Start-Process (start, saps)
Wait-Processpowershell
Get-Process (ps, gps)
Stop-Process (kill, spps)
Start-Process (start, saps)
Wait-ProcessService Management
服务管理
powershell
Get-Service (gsv)
Start-Service (sasv)
Stop-Service (spsv)
Restart-Service (srsv)
Set-Servicepowershell
Get-Service (gsv)
Start-Service (sasv)
Stop-Service (spsv)
Restart-Service (srsv)
Set-ServiceNetwork
网络
powershell
Test-Connection (ping)
Test-NetConnection
Invoke-WebRequest (curl, wget, iwr)
Invoke-RestMethod (irm)powershell
Test-Connection (ping)
Test-NetConnection
Invoke-WebRequest (curl, wget, iwr)
Invoke-RestMethod (irm)Object Manipulation
对象操作
powershell
Select-Object (select)
Where-Object (where, ?)
ForEach-Object (foreach, %)
Sort-Object (sort)
Group-Object (group)
Measure-Object (measure)
Compare-Object (compare, diff)powershell
Select-Object (select)
Where-Object (where, ?)
ForEach-Object (foreach, %)
Sort-Object (sort)
Group-Object (group)
Measure-Object (measure)
Compare-Object (compare, diff)🌐 REST API & Web Requests
🌐 REST API 与 Web 请求
powershell
undefinedpowershell
undefinedGET request
GET request
$response = Invoke-RestMethod -Uri "https://api.example.com/data" -Method Get
$response = Invoke-RestMethod -Uri "https://api.example.com/data" -Method Get
POST with JSON body
POST with JSON body
$body = @{
name = "John"
age = 30
} | ConvertTo-Json
$response = Invoke-RestMethod -Uri "https://api.example.com/users" `
-Method Post -Body $body -ContentType "application/json"
$body = @{
name = "John"
age = 30
} | ConvertTo-Json
$response = Invoke-RestMethod -Uri "https://api.example.com/users" `
-Method Post -Body $body -ContentType "application/json"
With headers and authentication
With headers and authentication
$headers = @{
"Authorization" = "Bearer $token"
"Accept" = "application/json"
}
$response = Invoke-RestMethod -Uri $url -Headers $headers
$headers = @{
"Authorization" = "Bearer $token"
"Accept" = "application/json"
}
$response = Invoke-RestMethod -Uri $url -Headers $headers
Download file
Download file
Invoke-WebRequest -Uri $url -OutFile "file.zip"
---Invoke-WebRequest -Uri $url -OutFile "file.zip"
---🏗️ Script Structure Best Practices
🏗️ 脚本结构最佳实践
powershell
<#
.SYNOPSIS
Brief description
.DESCRIPTION
Detailed description
.PARAMETER Name
Parameter description
.EXAMPLE
PS> .\script.ps1 -Name "John"
Example usage
.NOTES
Author: Your Name
Version: 1.0.0
Date: 2025-01-01
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$Name
)powershell
<#
.SYNOPSIS
简要描述
.DESCRIPTION
详细描述
.PARAMETER Name
参数说明
.EXAMPLE
PS> .\script.ps1 -Name "John"
示例用法
.NOTES
作者:你的名字
版本:1.0.0
日期:2025-01-01
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$Name
)Script-level error handling
Script-level error handling
$ErrorActionPreference = "Stop"
$ErrorActionPreference = "Stop"
Use strict mode
Use strict mode
Set-StrictMode -Version Latest
try {
# Main script logic
Write-Verbose "Starting script"
# ... script code ...
Write-Verbose "Script completed successfully"}
catch {
Write-Error "Script failed: $_"
exit 1
}
finally {
# Cleanup
}
---Set-StrictMode -Version Latest
try {
# 主脚本逻辑
Write-Verbose "启动脚本"
# ... 脚本代码 ...
Write-Verbose "脚本执行成功"}
catch {
Write-Error "脚本执行失败:$_"
exit 1
}
finally {
# 清理操作
}
---📚 Additional Resources
📚 额外资源
Official Documentation
官方文档
- PowerShell Docs: https://learn.microsoft.com/powershell
- PowerShell Gallery: https://www.powershellgallery.com
- Az Module Docs: https://learn.microsoft.com/powershell/azure
- Microsoft Graph Docs: https://learn.microsoft.com/graph/powershell
- PowerShell 文档:https://learn.microsoft.com/powershell
- PowerShell Gallery:https://www.powershellgallery.com
- Az Module 文档:https://learn.microsoft.com/powershell/azure
- Microsoft Graph 文档:https://learn.microsoft.com/graph/powershell
Module Discovery
模块发现
powershell
undefinedpowershell
undefinedFind modules by keyword
Find modules by keyword
Find-Module -Tag "Azure"
Find-Module -Tag "Security"
Find-Module -Tag "Azure"
Find-Module -Tag "Security"
Explore commands in a module
Explore commands in a module
Get-Command -Module Az.Compute
Get-Command -Verb Get -Noun VM
Get-Command -Module Az.Compute
Get-Command -Verb Get -Noun VM
Get command help
Get command help
Get-Help Get-AzVM -Full
Get-Help Get-AzVM -Examples
Get-Help Get-AzVM -Online
undefinedGet-Help Get-AzVM -Full
Get-Help Get-AzVM -Examples
Get-Help Get-AzVM -Online
undefinedUpdate Help System
更新帮助系统
powershell
undefinedpowershell
undefinedUpdate help files (requires internet)
Update help files (requires internet)
Update-Help -Force -ErrorAction SilentlyContinue
Update-Help -Force -ErrorAction SilentlyContinue
Update help for specific modules
Update help for specific modules
Update-Help -Module Az -Force
---Update-Help -Module Az -Force
---🎯 Quick Decision Guide
🎯 快速决策指南
Use PowerShell 7+ when:
- Cross-platform compatibility needed
- New projects or scripts
- Performance is important
- Modern language features desired
Use Windows PowerShell 5.1 when:
- Windows-specific modules required (WSUS, GroupPolicy legacy)
- Corporate environments with strict version requirements
- Legacy script compatibility needed
Choose Azure CLI when:
- Simple one-liners needed
- JSON output preferred
- Bash scripting integration
Choose PowerShell Az module when:
- Complex automation required
- Object manipulation needed
- PowerShell scripting expertise available
- Reusable scripts and modules needed
选择PowerShell 7+的场景:
- 需要跨平台兼容性
- 新项目或新脚本
- 对性能有要求
- 需要现代语言特性
选择Windows PowerShell 5.1的场景:
- 依赖Windows专属模块(WSUS、GroupPolicy遗留版本)
- 企业环境有严格的版本要求
- 需要兼容遗留脚本
选择Azure CLI的场景:
- 需要简单的单行命令
- 偏好JSON输出
- 需要与Bash脚本集成
选择PowerShell Az模块的场景:
- 需要复杂的自动化
- 需要对象操作
- 具备PowerShell脚本专业能力
- 需要可复用的脚本和模块
✅ Pre-Flight Checklist for Scripts
✅ 脚本预检查清单
Before running any PowerShell script, ensure:
- ✅ Platform Detection - Use ,
$IsWindows,$IsLinux$IsMacOS - ✅ Version Check - if needed
#Requires -Version 7.0 - ✅ Module Requirements - specified
#Requires -Modules - ✅ Error Handling - blocks in place
try/catch - ✅ Input Validation - Parameter validation attributes used
- ✅ No Aliases - Full cmdlet names in scripts
- ✅ Path Handling - Use or
Join-Path[IO.Path]::Combine() - ✅ Encoding Specified - UTF-8 for cross-platform
- ✅ Credentials Secure - Never hardcoded
- ✅ Verbose Logging - for debugging
Write-Verbose
运行任何PowerShell脚本前,请确保:
- ✅ 平台检测 - 使用、
$IsWindows、$IsLinux$IsMacOS - ✅ 版本检查 - 如需特定版本,添加
#Requires -Version 7.0 - ✅ 模块依赖 - 明确要求
#Requires -Modules - ✅ 错误处理 - 包含块
try/catch - ✅ 输入验证 - 使用参数验证属性
- ✅ 无别名 - 脚本中使用完整cmdlet名称
- ✅ 路径处理 - 使用或
Join-Path[IO.Path]::Combine() - ✅ 编码指定 - 跨平台脚本使用UTF-8编码
- ✅ 凭据安全 - 绝不硬编码凭据
- ✅ 详细日志 - 使用用于调试
Write-Verbose
🚨 Common Pitfalls & Solutions
🚨 常见陷阱与解决方案
Pitfall: Out-GridView Search Broken in 7.5
陷阱:Out-GridView搜索在7.5版本中失效
powershell
undefinedpowershell
undefinedKnown Issue: Out-GridView search doesn't work in PowerShell 7.5 due to .NET 9 changes
Known Issue: Out-GridView search doesn't work in PowerShell 7.5 due to .NET 9 changes
Workaround: Use Where-Object or Select-Object for filtering
Workaround: Use Where-Object or Select-Object for filtering
Get-Process | Where-Object CPU -gt 100 | Format-Table
Get-Process | Where-Object CPU -gt 100 | Format-Table
Or export to CSV and use external tools
Or export to CSV and use external tools
Get-Process | Export-Csv processes.csv -NoTypeInformation
undefinedGet-Process | Export-Csv processes.csv -NoTypeInformation
undefinedPitfall: Case Sensitivity
陷阱:大小写敏感性
powershell
undefinedpowershell
undefinedLinux/macOS are case-sensitive
Linux/macOS are case-sensitive
This fails on Linux if file is "File.txt"
This fails on Linux if file is "File.txt"
Get-Content "file.txt"
Get-Content "file.txt"
Solution: Use exact casing or Test-Path first
Solution: Use exact casing or Test-Path first
if (Test-Path "file.txt") {
Get-Content "file.txt"
}
undefinedif (Test-Path "file.txt") {
Get-Content "file.txt"
}
undefinedPitfall: Execution Policy
陷阱:执行政策限制
powershell
undefinedpowershell
undefinedSolution: Set for current user
Solution: Set for current user
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Or bypass for session
Or bypass for session
powershell.exe -ExecutionPolicy Bypass -File script.ps1
undefinedpowershell.exe -ExecutionPolicy Bypass -File script.ps1
undefinedPitfall: Module Import Failures
陷阱:模块导入失败
powershell
undefinedpowershell
undefinedSolution: Check module availability and install
Solution: Check module availability and install
if (-not (Get-Module -ListAvailable -Name Az)) {
Install-Module -Name Az -Force -Scope CurrentUser
}
Import-Module -Name Az
undefinedif (-not (Get-Module -ListAvailable -Name Az)) {
Install-Module -Name Az -Force -Scope CurrentUser
}
Import-Module -Name Az
undefinedPitfall: Array Concatenation Performance
陷阱:数组拼接性能问题
powershell
undefinedpowershell
undefinedBad: $array += $item (recreates array each time)
Bad: $array += $item (recreates array each time)
Good: Use ArrayList or List
Good: Use ArrayList or List
$list = [System.Collections.Generic.List[object]]::new()
$list.Add($item)
---
Remember: ALWAYS research latest PowerShell documentation and module versions before implementing solutions. The PowerShell ecosystem evolves rapidly, and best practices are updated frequently.$list = [System.Collections.Generic.List[object]]::new()
$list.Add($item)
---
注意:在实施解决方案前,请务必查阅最新的PowerShell文档和模块版本。PowerShell生态系统发展迅速,最佳实践会频繁更新。