Behind the PowerShell Pipeline

Behind the PowerShell Pipeline

Archives
Log in
Subscribe
November 13, 2026

November PowerShell Tool Of The Month

In this issue:

  • Overview
  • Introduction
  • Stepper
  • Scaffolding a Stepper Script
  • Stepping Your Script
  • Running a Stepper Script
    • Artifacts
    • Restarting the Script
  • Validating the Script
  • Summary

Overview

In this issue we look at a PowerShell module that you can use to structure a script file to continue should there be problem or interruption. This is very useful for long running scripts that break on step 7 with only one step to go. Using the module, you can write your script so that it will resume where it left off.

Introduction

It is time to look at another PowerShell tool of the month. This month's tool is a cross-platform PowerShell module that lets you structure script files into resumable steps. Say you have a long running script that encounters an error 60% through. Wouldn't you like to resume where the script left off? That is the concept behind Stepper. Let's take a look at what this project has to offer.

Stepper

You can find the project's GitHub repository at https://github.com/jakehildreth/Stepper. I think the project is well-documented and the author has opened up Discussions. Before using the module I encourage you to at least look at the project's README file.

Even though you can write a script that supports Stepper without initially installing the module, I encourage you to manually install the module from the PowerShell Gallery. Especially if your pattern is to use Install-PSResource instead of Install-Module.

Scaffolding a Stepper Script

In order to use a script with the Stepper module, it must be structured a specific way. The best way to get started is to create a script template.

New-StepperScript -path .\stepTemplate.ps1

I created a template with the thought that I could copy the file to start new scripts. But you can just as easily create the foundation for your script. This is the basic layout.

<#
.SYNOPSIS
    Brief description of what this script does.

.DESCRIPTION
    Detailed description of this script.

.NOTES
    This script uses the Stepper module to enable resumable execution.
    See https://github.com/jakehildreth/Stepper for more information.
#>
[CmdletBinding()]
param()

#region Stepper ignore
if (-not (Get-Module -Name Stepper) -and -not (Get-Module -ListAvailable -Name Stepper)) { Install-Module Stepper -Force }
Start-Stepper
#endregion Stepper ignore

New-Step {
    # Step 1: Describe what this step does
}

New-Step {
    # Step 2: Describe what this step does
}

Stop-Stepper

Do not remove or modify the first region that tests for the module. This section is a required bootstrap section and if you remove or modify it, you will "break" the script. I'll show you in a bit how to fix it, another Stepper feature.

For a more complete script outline run:

New-StepperScript -path .\stepTemplate2.ps1 -Showcase

This creates a script file with additional guidance.

<#
.SYNOPSIS
    Brief description of what this script does.

.DESCRIPTION
    Detailed description of this script.

.NOTES
    This script uses the Stepper module to enable resumable execution.
    See https://github.com/jakehildreth/Stepper for more information.
#>
[CmdletBinding()]
param()

#region Stepper ignore
if (-not (Get-Module -Name Stepper) -and -not (Get-Module -ListAvailable -Name Stepper)) { Install-Module Stepper -Force }
Start-Stepper
#endregion Stepper ignore

# Example: named step
New-Step 'Step 1: Collect data' {
    # $Stepper.<var> persists values across steps automatically
    $Stepper.ServerName = 'web-01'
    $Stepper.Result     = Invoke-SomeOperation
}

# Example: retry with backoff
New-Step 'Step 2: Deploy' -Retry -RetryInterval 30 -MaxRetries 3 {
    # Reference a value stored in a previous step
    Deploy-App -Server $Stepper.ServerName -Package $Stepper.Result

    # Example: suppress logging for this step
    # New-Step 'Step X: Sensitive operation' -NoLog {
    #     # logging is disabled for this step only
    # }
}

# Example: exclude code from Stepper's unmanaged-code detection
#region Stepper ignore
# Any executable code here is ignored by Stepper's analysis
# $debugVar = 'helper value used outside steps'
#endregion Stepper ignore

Stop-Stepper

Stepping Your Script

Each "step" of your script should go inside the New-Step script block. This is a module command. You should not have any code execute outside one of these steps. By default, each step is logged, although you can skip logging a specific step.

New-Step 'Setup Environment' -NoLog {
    ...
}

> I am not going to cover every parameter of every feature.

Each step is executed and any output is persisted to disk. If script execution is interrupted, when you re-start the script it will resume at the next step.

Depending on what you need to do you can also configure New-Step to retry if there is an error. This is handy if you have to account for a transient network problem or waiting for some other process to complete. You can see sample syntax in the second script sample.

Want to read the full issue?
Already a paid subscriber? Click here to log in.
GitHub
Bluesky
LinkedIn
Mastodon
jdhitsolutions.github.io
Powered by Buttondown, the easiest way to start and grow your newsletter.