WprHelpers.ps1
|
function Invoke-WprNative { [CmdletBinding()] param( [Parameter(Mandatory)] [string[]]$Arguments, [Parameter(Mandatory)] [string]$Operation ) # Convert native failures ourselves, without changing caller preferences or exit state. $PSNativeCommandUseErrorActionPreference = $false $ErrorActionPreference = 'Stop' $previousExitCode = Get-Variable LASTEXITCODE -Scope Global -ErrorAction Ignore $previousValue = if ($previousExitCode) { $previousExitCode.Value } else { $null } try { $global:LASTEXITCODE = $null try { $output = @(& sudo @Arguments 2>&1) $exitCode = $global:LASTEXITCODE } catch { $PSCmdlet.ThrowTerminatingError([System.Management.Automation.ErrorRecord]::new( [System.InvalidOperationException]::new("WPR $Operation could not be invoked through sudo: $($_.Exception.Message)", $_.Exception), 'WprInvocationFailed', [System.Management.Automation.ErrorCategory]::ResourceUnavailable, $Arguments)) } } finally { if ($previousExitCode) { $global:LASTEXITCODE = $previousValue } else { Remove-Variable LASTEXITCODE -Scope Global -ErrorAction Stop -WhatIf:$false -Confirm:$false } } if ($exitCode -isnot [int]) { $PSCmdlet.ThrowTerminatingError([System.Management.Automation.ErrorRecord]::new( [System.InvalidOperationException]::new("WPR $Operation did not report a native exit code; the outcome is unknown."), 'WprExitCodeUnavailable', [System.Management.Automation.ErrorCategory]::InvalidResult, $Arguments)) } if ($exitCode -ne 0) { $PSCmdlet.ThrowTerminatingError([System.Management.Automation.ErrorRecord]::new( [System.InvalidOperationException]::new("WPR $Operation failed with sudo exit code $exitCode. $($output -join [Environment]::NewLine)"), 'WprCommandFailed', [System.Management.Automation.ErrorCategory]::InvalidOperation, $Arguments)) } $output } function Start-WindowsPerformanceRecorder { <# .SYNOPSIS Starts WPR recording .DESCRIPTION Starts WPR through sudo. Invocation failures and nonzero exit codes produce PowerShell errors independently of the native-error preference. Use -ErrorAction Stop to catch them. Native output is returned only on success. .PARAMETER PerformanceProfile A built-in WPR profile name or path to a user-defined profile. .PARAMETER FileMode Specifies that recording is done in file mode. (The default mode is memory.) By using this option, the data is recorded to an unbounded file, which can grow in size until it fills the disk. .EXAMPLE Start-WindowsPerformanceRecorder -PerformanceProfile C:\my.wprp -FileMode Starts a WPR recording with a custom profile in file mode. .NOTES Windows only. Preserves the caller's preferences and LASTEXITCODE. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [Alias('Profile')] [ValidateNotNullOrEmpty()] [string]$PerformanceProfile, [switch]$FileMode ) process { Assert-WindowsOnly -CommandName $MyInvocation.MyCommand.Name $arguments = @('wpr', '-start', $PerformanceProfile) if ($FileMode) { $arguments += '-filemode' } if ($PSCmdlet.ShouldProcess($PerformanceProfile, 'Start WPR recording')) { try { Invoke-WprNative -Arguments $arguments -Operation 'start' } catch { $PSCmdlet.WriteError($_) } } } } function Stop-WindowsPerformanceRecorder { <# .SYNOPSIS Stops WPR recording and merges all the recording into the given file .DESCRIPTION Stops the active WPR recording session and merges all captured data into the specified ETL file. Invocation failures and nonzero exit codes produce PowerShell errors independently of the native-error preference. Use -ErrorAction Stop to catch them. Native output is returned only on success. .PARAMETER File Required nonblank event trace log (ETL) output filename. .EXAMPLE Stop-WindowsPerformanceRecorder -File C:\trace.etl Stops the recording and saves the trace to C:\trace.etl. .NOTES Windows only. Preserves the caller's preferences and LASTEXITCODE. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [ValidateNotNullOrWhiteSpace()] [string]$File ) process { Assert-WindowsOnly -CommandName $MyInvocation.MyCommand.Name if ($PSCmdlet.ShouldProcess($File, 'Stop WPR recording')) { try { Invoke-WprNative -Arguments @('wpr', '-stop', $File) -Operation 'stop' } catch { $PSCmdlet.WriteError($_) } } } } |