Skip to content
Learni
View all tutorials
Scripting et Automatisation

How to Create Advanced PowerShell Scripts in 2026

Lire en français

Introduction

PowerShell has become the essential tool for automating system administration and DevOps tasks. In 2026, the focus is on robust, maintainable, and reusable scripts. This tutorial guides you step by step through creating advanced scripts that leverage modern PowerShell 7 features: functions with CmdletBinding, POO classes, centralized error handling, and professional module creation. Every example is immediately executable and suitable for production environments.

Prerequisites

  • PowerShell 7.4 or higher installed
  • Intermediate PowerShell knowledge (functions, pipelines)
  • VS Code editor with PowerShell extension
  • Script execution rights (Set-ExecutionPolicy)

Advanced Function with CmdletBinding

Get-SystemInfo.ps1
function Get-SystemInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string[]]$ComputerName,
        [switch]$IncludeProcesses
    )
    begin {
        Write-Verbose "Starting information collection"
    }
    process {
        foreach ($computer in $ComputerName) {
            $os = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $computer
            $result = [PSCustomObject]@{
                ComputerName = $computer
                OSVersion    = $os.Version
                Uptime       = (Get-Date) - $os.LastBootUpTime
            }
            if ($IncludeProcesses) {
                $result | Add-Member -MemberType NoteProperty -Name Processes -Value (Get-Process -ComputerName $computer)
            }
            Write-Output $result
        }
    }
}

This function uses CmdletBinding to support -Verbose and -Debug. Parameters are strongly typed and the pipeline is handled via process. The returned object is structured for later use.

Advanced Parameter Validation

Get-SystemInfo.ps1
function Get-SystemInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidatePattern('^[A-Za-z0-9-]+$')]
        [string[]]$ComputerName,
        [ValidateRange(1, 100)]
        [int]$Timeout = 30
    )
    # Function body unchanged
}

ValidatePattern and ValidateRange prevent invalid input before execution. These attributes provide clear, automatic error messages.

Centralized Error Handling

Invoke-SafeCommand.ps1
function Invoke-SafeCommand {
    [CmdletBinding()]
    param([scriptblock]$ScriptBlock)
    try {
        & $ScriptBlock
    }
    catch [System.Management.Automation.RuntimeException] {
        Write-Error "Execution error: $($_.Exception.Message)" -ErrorAction Stop
    }
    catch {
        Write-Error "Unexpected error: $($_.Exception.Message)" -ErrorAction Stop
    }
    finally {
        Write-Verbose "Execution completed"
    }
}

The try/catch/finally structure with specific exception typing ensures precise handling and the ability to stop the script via ErrorAction Stop.

Defining a PowerShell Class

SystemReport.ps1
class SystemReport {
    [string]$ComputerName
    [datetime]$Timestamp
    hidden [int]$InternalId
    SystemReport([string]$name) {
        $this.ComputerName = $name
        $this.Timestamp = Get-Date
        $this.InternalId = Get-Random
    }
    [string] ToString() {
        return "Report for $($this.ComputerName) generated on $($this.Timestamp)"
    }
}

Classes enable an object-oriented approach with encapsulation. The hidden keyword protects internal properties while maintaining code readability.

Creating a Complete PowerShell Module

MyAdminTools.psm1
function Get-SystemInfo { <# function code here #> }
function Invoke-SafeCommand { <# code here #> }
Export-ModuleMember -Function Get-SystemInfo, Invoke-SafeCommand
# Associated .psd1 file:
# @{ ModuleVersion = '1.0.0'; RootModule = 'MyAdminTools.psm1'; FunctionsToExport = '*' }

A well-structured module exposes only public functions via Export-ModuleMember. The .psd1 manifest file versions and documents the module for professional distribution.

Best Practices

  • Always use [CmdletBinding()] and typed parameters
  • Implement explicit error handling with try/catch
  • Document every function with help comments
  • Version modules and use a .psd1 manifest
  • Systematically test with Pester before deployment

Common Mistakes to Avoid

  • Omitting pipeline support in advanced functions
  • Using Write-Host instead of Write-Output or Write-Verbose
  • Failing to validate user input with Validate* attributes
  • Ignoring remote session management with Enter-PSSession or Invoke-Command

Going Further

Deepen your skills with our certified training on PowerShell automation and DevOps. Discover our Learni courses.