powershell-master

安装量: 97
排名: #8505

安装

npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill powershell-master

PowerShell Master 🚨 CRITICAL GUIDELINES Windows File Path Requirements

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 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.

🎯 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 Overview PowerShell Versions & Platforms

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: C:\Program Files\PowerShell\7\ (PS7) or C:\Windows\System32\WindowsPowerShell\v1.0\ (5.1) Linux: /opt/microsoft/powershell/7/ or /usr/bin/pwsh macOS: /usr/local/microsoft/powershell/7/ or /usr/local/bin/pwsh 🔧 Cross-Platform Best Practices 1. Path Handling

DO:

Use Join-Path for cross-platform paths

$configPath = Join-Path -Path $PSScriptRoot -ChildPath "config.json"

Use [System.IO.Path] for path manipulation

$fullPath = [System.IO.Path]::Combine($home, "documents", "file.txt")

Forward slashes work on all platforms in PowerShell 7+

$path = "$PSScriptRoot/subfolder/file.txt"

DON'T:

Hardcoded backslashes (Windows-only)

$path = "C:\Users\Name\file.txt"

Assume case-insensitive file systems

Get-ChildItem "MyFile.txt" # Works on Windows, fails on Linux/macOS if casing is wrong

  1. Platform Detection

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 ':' }

Check PowerShell version

if ($PSVersionTable.PSVersion.Major -ge 7) { # PowerShell 7+ features }

  1. Avoid Aliases in Scripts

DON'T use aliases (they may differ across platforms)

ls | ? {$.Length -gt 1MB} | % {$.Name}

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.

  1. Text Encoding

PowerShell 7+ uses UTF-8 by default

"Hello" | Out-File -FilePath output.txt

For PowerShell 5.1 compatibility, specify encoding

"Hello" | Out-File -FilePath output.txt -Encoding UTF8

Best practice: Always specify encoding for cross-platform scripts

$content | Set-Content -Path $file -Encoding UTF8NoBOM

  1. Environment Variables (Cross-Platform)

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

AVOID: These are platform-specific

$env:USERNAME # Windows only $env:USER # Linux/macOS only

Environment variable names are CASE-SENSITIVE on Linux/macOS

$env:PATH # Correct on Linux/macOS $env:Path # May not work on Linux/macOS

  1. Shell Detection (Windows: PowerShell vs Git Bash)

CRITICAL: On Windows, distinguish between PowerShell and Git Bash/MSYS2 environments:

PowerShell detection (most reliable)

if ($env:PSModulePath -and ($env:PSModulePath -split ';').Count -ge 3) { Write-Host "Running in PowerShell" }

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:

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.

  1. Line Endings

PowerShell handles line endings automatically

But be explicit for git or cross-platform tools

git config core.autocrlf input # Linux/macOS git config core.autocrlf true # Windows

📦 Module Management (PSResourceGet & PSGallery) PSResourceGet - Modern Package Manager (2025)

PSResourceGet is 2x faster than PowerShellGet and actively maintained:

PSResourceGet ships with PowerShell 7.4+ (or install manually)

Install-Module -Name Microsoft.PowerShell.PSResourceGet -Force

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

Compatibility: Your old Install-Module commands still work

They automatically call PSResourceGet internally

Install-Module -Name Az -Scope CurrentUser # Works, uses PSResourceGet

Finding Modules

PSResourceGet (Modern)

Find-PSResource -Name "Azure" Find-PSResource -Tag "Security" Find-PSResource -Name Az | Select-Object Name, Version, PublishedDate

Legacy PowerShellGet (still works)

Find-Module -Name "Azure" Find-Command -Name Get-AzVM

Installing Modules

RECOMMENDED: PSResourceGet (2x faster)

Install-PSResource -Name Az -Scope CurrentUser -TrustRepository Install-PSResource -Name Microsoft.Graph -Version 2.32.0

Legacy: PowerShellGet (slower, but still works)

Install-Module -Name Az -Scope CurrentUser -Force Install-Module -Name Pester -Scope AllUsers # Requires elevation

Managing Installed Modules

List installed (PSResourceGet)

Get-InstalledPSResource Get-InstalledPSResource -Name Az

Update modules (PSResourceGet)

Update-PSResource -Name Az Update-PSResource # Updates all

Uninstall (PSResourceGet)

Uninstall-PSResource -Name OldModule -AllVersions

Import module

Import-Module -Name Az.Accounts

Offline Installation

Save module (works with both)

Save-PSResource -Name Az -Path C:\OfflineModules

Or: Save-Module -Name Az -Path C:\OfflineModules

Install from saved location

Install-PSResource -Name Az -Path C:\OfflineModules

🌟 Popular PowerShell Modules Azure (Az Module 14.5.0)

Latest: Az 14.5.0 (October 2025) with zone redundancy and symbolic links

Install Azure module 14.5.0

Install-PSResource -Name Az -Scope CurrentUser

Or: Install-Module -Name Az -Scope CurrentUser -Force

Connect to Azure

Connect-AzAccount

Common operations

Get-AzVM Get-AzResourceGroup New-AzResourceGroup -Name "MyRG" -Location "EastUS"

NEW in Az 14.5: Zone redundancy for storage

New-AzStorageAccount -ResourceGroupName "MyRG" -Name "storage123" ` -Location "EastUS" -SkuName "Standard_LRS" -EnableZoneRedundancy

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, deployments Microsoft Graph (Microsoft.Graph 2.32.0)

CRITICAL: MSOnline and AzureAD modules retired (March-May 2025). Use Microsoft.Graph instead.

Install Microsoft Graph 2.32.0 (October 2025)

Install-PSResource -Name Microsoft.Graph -Scope CurrentUser

Or: Install-Module -Name Microsoft.Graph -Scope CurrentUser

Connect with required scopes

Connect-MgGraph -Scopes "User.Read.All", "Group.ReadWrite.All"

Common operations

Get-MgUser Get-MgGroup New-MgUser -DisplayName "John Doe" -UserPrincipalName "john@domain.com" -MailNickname "john" Get-MgTeam

Migration from AzureAD/MSOnline

OLD: Connect-AzureAD / Connect-MsolService

NEW: Connect-MgGraph

OLD: Get-AzureADUser / Get-MsolUser

NEW: Get-MgUser

PnP PowerShell (SharePoint/Teams)

Install PnP PowerShell

Install-Module -Name PnP.PowerShell -Scope CurrentUser

Connect to SharePoint Online

Connect-PnPOnline -Url "https://tenant.sharepoint.com/sites/site" -Interactive

Common operations

Get-PnPList Get-PnPFile -Url "/sites/site/Shared Documents/file.docx" Add-PnPListItem -List "Tasks" -Values @{"Title"="New Task"}

AWS Tools for PowerShell

Install AWS Tools

Install-Module -Name AWS.Tools.Installer -Force Install-AWSToolsModule AWS.Tools.EC2,AWS.Tools.S3

Configure credentials

Set-AWSCredential -AccessKey $accessKey -SecretKey $secretKey -StoreAs default

Common operations

Get-EC2Instance Get-S3Bucket New-S3Bucket -BucketName "my-bucket"

Other Popular Modules

Pester (Testing framework)

Install-Module -Name Pester -Force

PSScriptAnalyzer (Code analysis)

Install-Module -Name PSScriptAnalyzer

ImportExcel (Excel manipulation without Excel)

Install-Module -Name ImportExcel

PowerShellGet 3.x (Modern package management)

Install-Module -Name Microsoft.PowerShell.PSResourceGet

🚀 CI/CD Integration GitHub Actions 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

Multi-Platform Matrix:

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.ps1

Azure DevOps Pipelines 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:

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 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 Cmdlet Structure

Verb-Noun pattern

Get-ChildItem Set-Location New-Item Remove-Item

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

Variables & Data Types

Variables (loosely typed)

$string = "Hello World" $number = 42 $array = @(1, 2, 3, 4, 5) $hashtable = @{Name="John"; Age=30}

Strongly typed

[string]$name = "John" [int]$age = 30 [datetime]$date = Get-Date

Special variables

$PSScriptRoot # Directory containing the script $PSCommandPath # Full path to the script $args # Script arguments $_ # Current pipeline object

Operators

Comparison operators

-eq # Equal -ne # Not equal -gt # Greater than -lt # Less than -match # Regex match -like # Wildcard match -contains # Array contains

Logical operators

-and -or -not

PowerShell 7+ ternary operator

$result = $condition ? "true" : "false"

Null-coalescing (PS 7+)

$value = $null ?? "default"

Control Flow

If-ElseIf-Else

if ($condition) { # Code } elseif ($otherCondition) { # Code } else { # Code }

Switch

switch ($value) { 1 { "One" } 2 { "Two" } {$_ -gt 10} { "Greater than 10" } default { "Other" } }

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)

Functions 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

Pipeline basics

Get-Process | Where-Object {$_.CPU -gt 100} | Select-Object Name, CPU

Simplified syntax (PS 3.0+)

Get-Process | Where CPU -gt 100 | Select Name, CPU

ForEach-Object

Get-ChildItem | ForEach-Object { Write-Host $_.Name }

Simplified (PS 4.0+)

Get-ChildItem | % Name

Group, Sort, Measure

Get-Process | Group-Object ProcessName Get-Service | Sort-Object Status Get-ChildItem | Measure-Object -Property Length -Sum

Error Handling

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 }

Error action preference

$ErrorActionPreference = "Stop" # Treat all errors as terminating $ErrorActionPreference = "Continue" # Default $ErrorActionPreference = "SilentlyContinue" # Suppress errors

🔒 Security Best Practices (2025 Standards) Modern Security Framework (JEA + WDAC + Logging)

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 Just Enough Administration (JEA)

Required for production environments in 2025:

Create JEA session configuration file

New-PSSessionConfigurationFile -SessionType RestrictedRemoteServer -Path "C:\JEA\HelpDesk.pssc" -VisibleCmdlets @{ Name = 'Restart-Service' Parameters = @{ Name = 'Name'; ValidateSet = 'Spooler', 'Wuauserv' } }, @{ Name = 'Get-Service' } -LanguageMode NoLanguage -ExecutionPolicy RemoteSigned

Register JEA endpoint

Register-PSSessionConfiguration -Name HelpDesk -Path "C:\JEA\HelpDesk.pssc" -Force

Connect with limited privileges

Enter-PSSession -ComputerName Server01 -ConfigurationName HelpDesk

Windows Defender Application Control (WDAC)

Replaces AppLocker for PowerShell script control:

Create WDAC policy for approved scripts

New-CIPolicy -FilePath "C:\WDAC\PowerShellPolicy.xml" -ScanPath "C:\ApprovedScripts" -Level FilePublisher ` -Fallback Hash

Convert to binary

ConvertFrom-CIPolicy -XmlFilePath "C:\WDAC\PowerShellPolicy.xml" ` -BinaryFilePath "C:\Windows\System32\CodeIntegrity\SIPolicy.p7b"

Deploy via Group Policy or MDM

Constrained Language Mode

Recommended for all non-admin users:

Check current language mode

$ExecutionContext.SessionState.LanguageMode

Output: FullLanguage (admin) or ConstrainedLanguage (standard user)

Enable system-wide via environment variable

"__PSLockdownPolicy",
"4",
[System.EnvironmentVariableTarget]::Machine

)

Script Block Logging

Enable for security auditing:

Enable via Group Policy or Registry

HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging

EnableScriptBlockLogging = 1

EnableScriptBlockInvocationLogging = 1

Check logs

Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" | Where-Object Id -eq 4104 | # Script Block Logging Select-Object TimeCreated, Message -First 10

Execution Policy

Check current execution policy

Get-ExecutionPolicy

Set for current user (no admin needed)

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Bypass for single session (use sparingly)

pwsh -ExecutionPolicy Bypass -File script.ps1

Credential Management

NEVER hardcode credentials

BAD: $password = "MyP@ssw0rd"

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

Legacy: Get-Credential for interactive

$cred = Get-Credential

Azure Key Vault for production

$vaultName = "MyKeyVault" $secret = Get-AzKeyVaultSecret -VaultName $vaultName -Name "DatabasePassword" $secret.SecretValue

Input Validation 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)

Get code signing certificate

$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert

Sign script

Set-AuthenticodeSignature -FilePath script.ps1 -Certificate $cert

⚡ Performance Optimization PowerShell 7+ Features

Parallel ForEach (PS 7+)

1..10 | ForEach-Object -Parallel { Start-Sleep -Seconds 1 "Processed $_" } -ThrottleLimit 5

Ternary operator

$result = $value ? "true" : "false"

Null-coalescing

$name = $userName ?? "default"

Null-conditional member access

$length = $string?.Length

Efficient Filtering

Use .NET methods for performance

Instead of: Get-Content large.txt | Where-Object

[System.IO.File]::ReadLines("large.txt") | Where-Object {$_ -match "pattern"}

Use -Filter parameter when available

Get-ChildItem -Path C:\ -Filter *.log -Recurse

Instead of: Get-ChildItem -Path C:\ -Recurse | Where-Object

ArrayList vs Array

Arrays are immutable - slow for additions

$array = @() 1..1000 | ForEach-Object { $array += $_ } # SLOW

Use ArrayList for dynamic collections

$list = [System.Collections.ArrayList]::new() 1..1000 | ForEach-Object { [void]$list.Add($_) } # FAST

Or use generic List

$list = [System.Collections.Generic.List[int]]::new() 1..1000 | ForEach-Object { $list.Add($_) }

🧪 Testing with Pester

Install Pester

Install-Module -Name Pester -Force

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
    }
}

}

Run tests

Invoke-Pester -Path ./tests Invoke-Pester -Path ./tests -OutputFormat NUnitXml -OutputFile TestResults.xml

Code coverage

Invoke-Pester -Path ./tests -CodeCoverage ./src/*.ps1

📝 Script Requirements & Versioning

Require specific PowerShell version

Requires -Version 7.0

Require modules

Requires -Modules Az.Accounts, Az.Compute

Require admin/elevated privileges (Windows)

Requires -RunAsAdministrator

Combine multiple requirements

Requires -Version 7.0

Requires -Modules @{ModuleName='Pester'; ModuleVersion='5.0.0'}

Use strict mode

Set-StrictMode -Version Latest

🎓 Common Cmdlets Reference File System 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 Get-Process (ps, gps) Stop-Process (kill, spps) Start-Process (start, saps) Wait-Process

Service Management Get-Service (gsv) Start-Service (sasv) Stop-Service (spsv) Restart-Service (srsv) Set-Service

Network Test-Connection (ping) Test-NetConnection Invoke-WebRequest (curl, wget, iwr) Invoke-RestMethod (irm)

Object Manipulation 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

GET request

$response = Invoke-RestMethod -Uri "https://api.example.com/data" -Method Get

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"

With headers and authentication

$headers = @{ "Authorization" = "Bearer $token" "Accept" = "application/json" }

$response = Invoke-RestMethod -Uri $url -Headers $headers

Download file

Invoke-WebRequest -Uri $url -OutFile "file.zip"

🏗️ Script Structure Best Practices <# .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 )

Script-level error handling

$ErrorActionPreference = "Stop"

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 }

📚 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 Module Discovery

Find modules by keyword

Find-Module -Tag "Azure" Find-Module -Tag "Security"

Explore commands in a module

Get-Command -Module Az.Compute Get-Command -Verb Get -Noun VM

Get command help

Get-Help Get-AzVM -Full Get-Help Get-AzVM -Examples Get-Help Get-AzVM -Online

Update Help System

Update help files (requires internet)

Update-Help -Force -ErrorAction SilentlyContinue

Update help for specific modules

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 ✅ Pre-Flight Checklist for Scripts

Before running any PowerShell script, ensure:

✅ Platform Detection - Use $IsWindows, $IsLinux, $IsMacOS ✅ Version Check - #Requires -Version 7.0 if needed ✅ Module Requirements - #Requires -Modules specified ✅ Error Handling - try/catch blocks in place ✅ Input Validation - Parameter validation attributes used ✅ No Aliases - Full cmdlet names in scripts ✅ Path Handling - Use Join-Path or [IO.Path]::Combine() ✅ Encoding Specified - UTF-8 for cross-platform ✅ Credentials Secure - Never hardcoded ✅ Verbose Logging - Write-Verbose for debugging 🚨 Common Pitfalls & Solutions Pitfall: Out-GridView Search Broken in 7.5

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

Get-Process | Where-Object CPU -gt 100 | Format-Table

Or export to CSV and use external tools

Get-Process | Export-Csv processes.csv -NoTypeInformation

Pitfall: Case Sensitivity

Linux/macOS are case-sensitive

This fails on Linux if file is "File.txt"

Get-Content "file.txt"

Solution: Use exact casing or Test-Path first

if (Test-Path "file.txt") { Get-Content "file.txt" }

Pitfall: Execution Policy

Solution: Set for current user

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Or bypass for session

powershell.exe -ExecutionPolicy Bypass -File script.ps1

Pitfall: Module Import Failures

Solution: Check module availability and install

if (-not (Get-Module -ListAvailable -Name Az)) { Install-Module -Name Az -Force -Scope CurrentUser } Import-Module -Name Az

Pitfall: Array Concatenation Performance

Bad: $array += $item (recreates array each time)

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.

返回排行榜