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



