Retry.psm1

[CmdletBinding()]
param()
$scriptName = 'Retry'
Write-Verbose "[$scriptName] - Importing module"

#region - From [functions] - [public]
Write-Verbose "[$scriptName] - [functions] - [public] - Processing folder"

#region - From [functions] - [public] - [Invoke-Retry]
Write-Verbose "[$scriptName] - [functions] - [public] - [Invoke-Retry] - Importing"

function Invoke-Retry {
    <#
        .SYNOPSIS
        Runs a scriptblock with a retry mechanism.

        .DESCRIPTION
        Runs a scriptblock with a retry mechanism.
        If the scriptblock fails, it will retry the scriptblock a number of times with a delay between each try.
        If a catch scriptblock is provided, it will run that scriptblock if the scriptblock fails.

        .EXAMPLE
        Retry -Count 5 -Delay 5 -Run {
            Invoke-RestMethod -Uri 'https://api.myip.com/'
        }
    #>

    [CmdletBinding()]
    [Alias('Retry')]
    param(
        # The scriptblock to run
        [Parameter(Mandatory)]
        [scriptblock] $Run,

        # The number of tries to make
        [Parameter()]
        [int] $Count = 3,

        # The delay between tries in seconds
        [Parameter()]
        [int] $Delay = 5,

        # A scriptblock to run if it fails
        [Parameter()]
        [scriptblock] $Catch = {},

        # A scriptblock to run after the scriptblock has run
        [Parameter()]
        [scriptblock] $Finally = {}
    )

    $ErrorActionPreference = 'Stop'

    for ($i = 0; $i -lt $Count; $i++) {
        try {
            & $Run
            break
        } catch {
            Write-Warning "The command:"
            Write-Warning $Run.ToString()
            Write-Warning "failed with error: $_"
            & $Catch
            if ($i -eq $Count - 1) {
                throw
            }

            Write-Warning "Retrying in $Delay seconds..."
            Start-Sleep -Seconds $Delay
        }
    }
    & $Finally
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Invoke-Retry] - Done"
#endregion - From [functions] - [public] - [Invoke-Retry]

Write-Verbose "[$scriptName] - [functions] - [public] - Done"
#endregion - From [functions] - [public]


$exports = @{
    Alias    = '*'
    Cmdlet   = ''
    Function = 'Invoke-Retry'
}
Export-ModuleMember @exports