
Powershell Master
- 700 installs
- 49 repo stars
- Updated June 18, 2026
- josiahsiegel/claude-plugin-marketplace
powershell-master is a Claude Code skill that embeds reliable PowerShell steps into GitHub Actions, Azure DevOps, and Bitbucket CI/CD pipelines for developers who need Pester tests and PSScriptAnalyzer in multi-platform
About
powershell-master is a Claude Code skill from josiahsiegel/claude-plugin-marketplace that provides reference patterns for embedding PowerShell in GitHub Actions, Azure DevOps Pipelines, and Bitbucket Pipelines. The documentation shows how to install Pester and PSScriptAnalyzer modules, run Pester tests with NUnit XML output, and execute PSScriptAnalyzer lint passes inside CI jobs triggered on push and pull_request events. Developers reach for powershell-master when .NET, Windows automation, or cross-platform pwsh scripts need consistent test and lint stages across multiple CI vendors. The skill uses shell: pwsh in GitHub Actions examples and covers module installation scoped to CurrentUser for pipeline agents. Triggers include wiring PowerShell into GitHub Actions, Azure DevOps, or Bitbucket, or standardizing Pester and PSScriptAnalyzer steps across repositories that share PowerShell build logic.
- Ready-to-use YAML snippets for GitHub Actions with Pester and PSScriptAnalyzer
- Multi-platform matrix strategy supporting ubuntu, windows, and macos runners
- Azure DevOps pipeline examples using the PowerShell@2 task
- Cross-platform shell configuration using pwsh
- Reference patterns for installing and running PowerShell modules in CI
Powershell Master by the numbers
- 700 all-time installs (skills.sh)
- Ranked #210 of 1,440 DevOps & CI/CD skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill powershell-masterAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 700 |
|---|---|
| repo stars | ★ 49 |
| Security audit | 1 / 3 scanners passed |
| Last updated | June 18, 2026 |
| Repository | josiahsiegel/claude-plugin-marketplace ↗ |
How do you run Pester tests in GitHub Actions?
Embed reliable PowerShell steps into GitHub Actions, Azure DevOps, and multi-platform CI/CD pipelines.
Who is it for?
Developers maintaining PowerShell modules or automation scripts who need Pester and PSScriptAnalyzer running in GitHub Actions, Azure DevOps, or Bitbucket.
Skip if: Teams with no PowerShell in their stack or pipelines already fully templated without needing CI integration reference patterns.
When should I use this skill?
The user asks to add PowerShell, Pester, or PSScriptAnalyzer steps to GitHub Actions, Azure DevOps, or Bitbucket CI/CD pipelines.
What you get
CI pipeline YAML with Pester NUnit XML output, PSScriptAnalyzer lint stage, and cross-platform pwsh job steps.
- CI pipeline YAML
- Pester NUnit XML test output
- PSScriptAnalyzer lint results
By the numbers
- Covers 3 CI platforms: GitHub Actions, Azure DevOps, and Bitbucket Pipelines
- Documents Pester and PSScriptAnalyzer as standard pipeline test and lint modules
Files
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
---
Reference Map
Detailed material lives in references/. Load only what the current task needs.
| Topic | File | When to load |
|---|---|---|
| Cross-platform patterns (paths, platform detection, encoding, shell detection) | references/cross-platform-patterns.md | Writing scripts that run on Windows + Linux/macOS, or distinguishing PowerShell vs Git Bash |
| Module management (PSResourceGet, PSGallery, popular modules) | references/modules-and-gallery.md | Installing/finding modules, Az 14.5.0, Microsoft.Graph 2.32.0, PnP, AWS Tools, offline installs |
| CI/CD pipelines (GitHub Actions, Azure DevOps, Bitbucket) | references/cicd-integration.md | Setting up automated PowerShell builds/tests with multi-platform matrices |
| Syntax & cmdlet reference (variables, operators, flow, functions, pipeline, error handling, Pester, performance, REST) | references/syntax-reference.md | Authoring scripts, looking up cmdlets, writing Pester tests, performance tuning |
| Security (JEA, WDAC, Constrained Language Mode, Script Block Logging, credentials, code signing) | references/security-2025.md | Production security hardening, credential management, audit logging |
---
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) orC:\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
---
Core Workflow
1. Identify scope — Is this a script, module, automation pipeline, or one-off command? Note target platform(s). 2. Check version & modules — $PSVersionTable.PSVersion, Get-Module -ListAvailable. Confirm PowerShell 7+ unless legacy required. 3. Load the relevant reference(s) from the Reference Map above. Avoid loading material you do not need. 4. Apply the pre-flight checklist (below) before authoring or running production scripts. 5. Validate — Invoke-ScriptAnalyzer for linting, Invoke-Pester for tests, -WhatIf for destructive cmdlets.
---
Pre-Flight Checklist for Scripts
Before running any PowerShell script, ensure:
1. Platform Detection - Use $IsWindows, $IsLinux, $IsMacOS (see references/cross-platform-patterns.md) 2. Version Check - #Requires -Version 7.0 if needed 3. Module Requirements - #Requires -Modules specified 4. Error Handling - try/catch blocks in place 5. Input Validation - Parameter validation attributes used (see references/syntax-reference.md) 6. No Aliases - Full cmdlet names in scripts 7. Path Handling - Use Join-Path or [IO.Path]::Combine() 8. Encoding Specified - UTF-8 for cross-platform 9. Credentials Secure - Never hardcoded (see references/security-2025.md) 10. Verbose Logging - Write-Verbose for debugging
---
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
---
Minimal Script Skeleton
#Requires -Version 7.0
<#
.SYNOPSIS
Brief description
.DESCRIPTION
Detailed description
.PARAMETER Name
Parameter description
.EXAMPLE
PS> .\script.ps1 -Name "John"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$Name
)
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
try {
Write-Verbose "Starting script"
# ... main logic ...
Write-Verbose "Script completed successfully"
}
catch {
Write-Error "Script failed: $_"
exit 1
}
finally {
# Cleanup
}Expand this skeleton using patterns from references/syntax-reference.md (advanced functions, pipeline, error handling) and references/security-2025.md (input validation, credential handling).
---
Additional Resources
- 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
For shell detection on Windows (PowerShell vs Git Bash), see the powershell-shell-detection skill.
---
Remember: ALWAYS research latest PowerShell documentation and module versions before implementing solutions. The PowerShell ecosystem evolves rapidly, and best practices are updated frequently.
PowerShell CI/CD Integration
Reference for GitHub Actions, Azure DevOps Pipelines, and Bitbucket Pipelines with PowerShell.
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 -ReportSummaryMulti-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.ps1Azure 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.ps1PowerShell Cross-Platform Patterns
Reference for writing PowerShell that works on Windows, Linux, and macOS.
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 wrongPlatform 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
}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}On Linux/macOS, aliases might invoke native commands instead of PowerShell cmdlets, causing unexpected results.
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 UTF8NoBOMEnvironment 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/macOSShell Detection (Windows: PowerShell vs Git Bash)
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 (from bash):
# Bash detection - check MSYSTEM environment variable
if [ -n "$MSYSTEM" ]; then
echo "Running in Git Bash/MSYS2: $MSYSTEM"
# MSYSTEM values: MINGW64, MINGW32, MSYS
fiWhen 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\JohnorC:/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.
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 # WindowsCommon 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"
}PowerShell Module Management and Popular Modules
Reference for PSResourceGet, PSGallery, and key PowerShell modules in 2025-2026.
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 PSResourceGetFinding 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-AzVMInstalling 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 elevationManaging 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.AccountsOffline 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:\OfflineModulesPopular 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 setsAz.Storage- Storage accounts (zone redundancy support)Az.Network- Virtual networks, NSGsAz.KeyVault- Key Vault operationsAz.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-MgUserPnP 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.PSResourceGetModule 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 -OnlineUpdate Help System
# Update help files (requires internet)
Update-Help -Force -ErrorAction SilentlyContinue
# Update help for specific modules
Update-Help -Module Az -ForceCommon 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 AzPowerShell Security Best Practices (2025 Standards)
Reference for JEA, WDAC, Constrained Language Mode, Script Block Logging, credentials, validation, and code signing.
Modern Security Framework (JEA + WDAC + Logging)
2025 Security Requirements: 1. JEA - Just Enough Administration for role-based access 2. WDAC - Windows Defender Application Control for script approval 3. Constrained Language Mode - For non-admin users 4. 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 HelpDeskWindows 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 MDMConstrained 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 10Execution 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.ps1Credential 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.SecretValueInput 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 $certPowerShell Syntax and Cmdlets Reference
Detailed reference for PowerShell language constructs, common cmdlets, REST patterns, testing, and performance tips.
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 StopVariables & 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 objectOperators
# 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 -SumError 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 errorsPerformance 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?.LengthEfficient 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($_) }Common 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)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/*.ps1Script 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 LatestCommon 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-ProcessService Management
Get-Service (gsv)
Start-Service (sasv)
Stop-Service (spsv)
Restart-Service (srsv)
Set-ServiceNetwork
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
}Common Pitfalls
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 -NoTypeInformationExecution Policy
# Solution: Set for current user
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# Or bypass for session
powershell.exe -ExecutionPolicy Bypass -File script.ps1Related skills
How it compares
Choose powershell-master over generic CI templates when the pipeline must run PowerShell-specific Pester and PSScriptAnalyzer stages across multiple CI vendors.
FAQ
Which CI platforms does powershell-master cover?
powershell-master documents PowerShell integration for GitHub Actions, Azure DevOps Pipelines, and Bitbucket Pipelines. Each reference shows pwsh shell steps, module installation, and test or lint execution patterns portable across those three vendors.
What PowerShell test tools does the skill configure?
powershell-master configures Pester for unit tests with NUnit XML output and PSScriptAnalyzer for script linting inside CI jobs. Pipeline examples install both modules with Install-Module before Invoke-Pester and analyzer runs on push or pull_request triggers.
Is Powershell Master safe to install?
skills.sh reports 1 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.