powershell-master

🚨 CRITICAL GUIDELINES

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "powershell-master" with this command: npx skills add josiahsiegel/claude-plugin-marketplace/josiahsiegel-claude-plugin-marketplace-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

[Environment]::SetEnvironmentVariable( "__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 {$_ -match "pattern"}

[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 {$_.Extension -eq ".log"}

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

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.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

tailwindcss-advanced-layouts

No summary provided by upstream source.

Repository SourceNeeds Review
General

tailwindcss-animations

No summary provided by upstream source.

Repository SourceNeeds Review
General

tailwindcss-mobile-first

No summary provided by upstream source.

Repository SourceNeeds Review
General

docker-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review