liveBook · Manning

Wrapper

As explained in Practical Automation with PowerShell: Effective scripting from the console to the cloud

A wrapper function is a function that provides a simplified or specialized interface around other operations or functions.

A wrapper function places a simpler, specialized interface around repeated operations. In PowerShell automation, it can hide file paths, format data, select configurations, or invoke another tool. section 6.3.3 section 9.4.4

A practical wrapper typically:

  • Discovers module-owned configuration files instead of requiring callers to provide full paths. section 6.3.3
  • Accepts either named configurations or interactive selections, then delegates execution to the underlying configuration function. section 6.3.3
  • Transforms performance-counter objects into the JSON shape expected by a Python graphing script. section 9.4.4
  • Centralizes executable paths, script paths, titles, temporary output paths, and typed input parameters. section 9.4.4

Configuration and graphing wrappers

Invoke-ServerConfig can enumerate JSON files under the module's Configurations directory, accept one or more names, offer a selection interface when needed, and call Set-ServerConfig. New-TimeseriesGraph can receive PerformanceCounterSampleSet objects, extract timestamps and cooked values, serialize them to compressed JSON, and pass that data to timeseries.py through Start-Process. section 6.3.3 section 9.4.4

Listing 6.16 Invoke-ServerConfig
Function Invoke-ServerConfig{
    [CmdletBinding()] 
    [OutputType([object])]
    param(
        [string[]]$Config = $null
    )
    [System.Collections.Generic.List[PSObject]]$selection = @()
    $Path = @{                                                   #1
        Path      = $PSScriptRoot
        ChildPath = 'Configurations'
    }
    $ConfigPath = Join-Path @Path
 
    $ChildItem = @{                                              #2
        Path   = $ConfigPath
        Filter = '*.JSON'
    }
    $Configurations = Get-ChildItem @ChildItem
 
    if(-not [string]::IsNullOrEmpty($Config)){                   #3
        foreach($c in $Config){
            $Configurations | Where-Object{ $_.BaseName -eq $Config } |
                ForEach-Object { $selection.Add($_) }
        }
    }
 
    if($selection.Count -eq 0){                                  #4
        $Configurations | Select-Object BaseName, FullName |
            Out-GridView -PassThru | ForEach-Object { $selection.Add($_) }
    }
 
    $Log = "$($env:COMPUTERNAME)-Config.log"                     #5
    $LogFile = Join-Path -Path $($env:SystemDrive) -ChildPath $Log
 
    foreach($json in $selection){                                #6
        Set-ServerConfig -ConfigJson $json.FullName -LogFile $LogFile
    }
}

Inspect the complete Invoke-ServerConfig implementation, including module-relative path construction, JSON discovery, named selection, and fallback selection behavior. section 6.3.3

Listing 9.3 New-TimeseriesGraph
Function New-TimeseriesGraph {
    [CmdletBinding()]
    [OutputType()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$PyPath,
        [Parameter(Mandatory = $true)]
        [string]$ScriptPath,
        [Parameter(Mandatory = $true)]
        [string]$Title,
        [Parameter(Mandatory = $true)]
    [Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSampleSet[]]
        $CounterData
    )
 
    $CounterJson = $CounterData |                                  #1
        Select-Object Timestamp,
        @{l = 'Value'; e = { $_.CounterSamples.CookedValue } } |
        ConvertTo-Json -Compress
 
    $Guid = New-Guid                                               #2
 
    $path = @{                                                     #3
        Path = $env:TEMP
    }
    $picture = Join-Path @Path -ChildPath "$($Guid).PNG"
    $StandardOutput = Join-Path @Path -ChildPath "$($Guid)-Output.txt"
    $StandardError = Join-Path @Path -ChildPath "$($Guid)-Error.txt"
 
    $ArgumentList = @(                                             #4
        """$($ScriptPath)"""
        """$($picture)"""
        """$($Title)"""
        $CounterJson.Replace('"', '\"')
    )
    $Process = @{                                                  #5
        FilePath               = $PyPath
        ArgumentList           = $ArgumentList
        RedirectStandardOutput = $StandardOutput
        RedirectStandardError  = $StandardError
        NoNewWindow            = $true
        PassThru               = $true
    }
    $graph = Start-Process @Process
 
    $RuntimeSeconds = 30                                           #6
    $timer = [system.diagnostics.stopwatch]::StartNew()
    while ($graph.HasExited -eq $false) {
        if ($timer.Elapsed.TotalSeconds -gt $RuntimeSeconds) {
            $graph | Stop-Process -Force
            throw "The application did not exit in time"
        }
    }
    $timer.Stop()
 
    $OutputContent = Get-Content -Path $StandardOutput             #7
    $ErrorContent = Get-Content -Path $StandardError
    if ($ErrorContent) {
        Write-Error $ErrorContent                                  #8
    }
    elseif ($OutputContent | Where-Object { $_ -match 'File saved to :' }) {
        $output = $OutputContent |                                 #9
            Where-Object { $_ -match 'File saved to :' }
        $Return = $output.Substring($output.IndexOf(':') + 1).Trim()
    }
    else {
        Write-Error "Unknown error occurred"                       #10
    }
 
    Remove-Item -LiteralPath $StandardOutput -Force                #11
    Remove-Item -LiteralPath $StandardError -Force
 
    $Return
}

Inspect the New-TimeseriesGraph implementation, including typed counter input, JSON conversion, temporary PNG naming, and external process arguments. section 9.4.4

How Practical Automation with PowerShell: Effective scripting from the console to the cloud covers it

How deep it goes
Builds complete parameterized functions and data-flow logic, stopping short of general wrapper design theory.
Examples
Uses server configuration selection and processor-time graph generation as operational wrapper examples.
What it assumes
Assumes intermediate PowerShell and introduces neither basic functions nor external-tool fundamentals from zero.
What you can do after
Build it from scratch as reusable PowerShell functions that select configurations or prepare data for another executable.
How it connects
Connects PowerShell modules with JSON configuration, Get-Counter, ConvertTo-Json, Start-Process, and Python scripts.

Also explained in

Compare how 4 books explain wrapper →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Practical Automation with PowerShell: Effective scripting from the console to the cloud. The section links point to the parts of the book it draws on.