Public/Start-tpcMonitor.ps1
|
function Start-tpcMonitor { <# .SYNOPSIS .DESCRIPTION Starts real-time performance counter monitoring for a single local or remote system. .PARAMETER ConfigName Name of the configuration template (without 'tpc_' prefix and '.json' extension). Cannot be combined with ConfigPath. .PARAMETER ConfigPath Absolute path to a JSON configuration file (pattern 'tpc_*.json'). Cannot be combined with ConfigName. .PARAMETER ComputerName DNS name of the remote computer to monitor. .PARAMETER Credential PSCredential for remote authentication. Only applicable with ComputerName. .PARAMETER UpdateInterval Seconds between counter updates. Default: 1. .PARAMETER Tui (Beta) Launches an interactive Terminal GUI (Terminal.Gui) instead of the scrolling console output. Shows a live table and 3-row sparklines per counter with Pause / Sparklines-toggle / Quit buttons. .PARAMETER ExportCsv Enables CSV export of counter values after each batch cycle (append mode, long format). .PARAMETER CsvPath Directory path for the CSV export file. Default: Desktop. .PARAMETER ExportHtml Enables HTML report export after each batch cycle using PSWriteHTML. The report contains a counter overview table, a combined chart and individual charts per counter. .PARAMETER HtmlPath Directory path for the HTML report file. Default: Desktop. .PARAMETER HtmlGroupBy Controls how individual tabs are grouped in the HTML report. 'Counter' (default): one tab per counter type, series per host — best for comparing hosts. 'Host': one tab per host, series per counter — best for viewing a single host's metrics. .EXAMPLE Start-tpcMonitor -ConfigName "CPU" Starts local CPU monitoring using the built-in CPU template. .EXAMPLE Start-tpcMonitor -ConfigPath "C:\MyConfigs\tpc_CustomCPU.json" Starts monitoring using a custom configuration file. .EXAMPLE Start-tpcMonitor -ConfigName "Memory" -ComputerName "Server01" -Credential $cred -UpdateInterval 2 Starts remote memory monitoring with 2-second intervals. .EXAMPLE Start-tpcMonitor -ConfigName "CPU" -Tui (Beta) Starts CPU monitoring in the interactive Terminal GUI. .EXAMPLE Start-tpcMonitor -ConfigName "CPU" -ExportCsv -CsvPath "C:\Exports" Starts CPU monitoring with CSV export to C:\Exports\psTPC_history.csv. .EXAMPLE Start-tpcMonitor -ConfigName "CPU" -ExportHtml Starts CPU monitoring with HTML report export to the Desktop after each cycle. .EXAMPLE Start-tpcMonitor -ConfigName "CPU" -ExportHtml -HtmlPath "C:\Reports" Starts CPU monitoring with HTML report export to C:\Reports\psTPC_CPU_report.html. #> [CmdletBinding()] param( [Parameter(ParameterSetName = 'ConfigName', Mandatory)] [Parameter(ParameterSetName = 'RemoteByName', Mandatory)] [string] $ConfigName, [Parameter(ParameterSetName = 'ConfigPath', Mandatory)] [Parameter(ParameterSetName = 'RemoteByPath', Mandatory)] [string] $ConfigPath, [Parameter(ParameterSetName = 'RemoteByName', Mandatory)] [Parameter(ParameterSetName = 'RemoteByPath', Mandatory)] [string] $ComputerName, [Parameter(ParameterSetName = 'RemoteByName')] [Parameter(ParameterSetName = 'RemoteByPath')] [pscredential] $Credential = $null, [int] $UpdateInterval = 1, [switch] $Tui, [switch] $ExportCsv, [string] $CsvPath = [Environment]::GetFolderPath('Desktop'), [switch] $ExportHtml, [string] $HtmlPath = [Environment]::GetFolderPath('Desktop'), [ValidateSet('Counter', 'Host')] [string] $HtmlGroupBy = 'Counter' ) $configParams = @{} $monitorType = 'local' try { if ( ($PSCmdlet.ParameterSetName -in @('RemoteByName', 'RemoteByPath') -and $ComputerName -eq $env:COMPUTERNAME) -or # in case local computername to avoid self remoting ($PSCmdlet.ParameterSetName -in @('ConfigPath', 'ConfigName') ) ) { if ($PSCmdlet.ParameterSetName -in @('RemoteByName', 'RemoteByPath')) { Write-Host "ComputerName '$ComputerName' matches local host. Falling back to local monitoring." -ForegroundColor Yellow Start-Sleep -Seconds 1 } $configParams['counterMap'] = $(Get-CounterMap) if ( $PSCmdlet.ParameterSetName -in @('ConfigPath', 'RemoteByPath') ) { if ( -not (Test-Path $ConfigPath) ) { Write-Warning "Configuration file not found: $ConfigPath" Return } $fileName = Split-Path $ConfigPath -Leaf if ( $fileName -notmatch '^tpc_.+\.json$' ) { throw "Invalid configuration file name. File must follow the pattern 'tpc_*.json'. Found: $fileName" } Write-Host "Loading configuration from '$ConfigPath'..." -ForegroundColor Yellow $configParams['ConfigPath'] = $ConfigPath } elseif ( $PSCmdlet.ParameterSetName -in @('ConfigName', 'RemoteByName') ) { Write-Host "Loading configuration '$ConfigName'..." -ForegroundColor Yellow $configParams['ConfigName'] = $ConfigName } } elseif ( $PSCmdlet.ParameterSetName -in @('RemoteByName', 'RemoteByPath') -and $ComputerName -ne $env:COMPUTERNAME ) { $monitorType = 'remoteSingle' $configParams['ComputerName'] = $ComputerName Write-Host "Starting remote monitoring for $ComputerName " -ForegroundColor Yellow -NoNewline if ( $Credential ) { Write-Host "using $($Credential.UserName)." -ForegroundColor Yellow $configParams['Credential'] = $Credential } else { Write-Host "using $env:USERDOMAIN\$env:USERNAME ." -ForegroundColor Yellow } # Reachability is owned solely by Get-CounterMap (WinRM, TCP 5985): it fails fast and # throws if the host is unreachable, which the surrounding try/catch reports. $configParams['counterMap'] = $(Get-CounterMap @configParams) switch ( $PSCmdlet.ParameterSetName ) { 'RemoteByName' { $configParams['ConfigName'] = $ConfigName } 'RemoteByPath' { $configParams['ConfigPath'] = $ConfigPath } } } # Start monitoring $MonitoringParams = @{ MonitorType = $monitorType Config = Get-CounterConfiguration @configParams UpdateInterval = $UpdateInterval Tui = $Tui ExportCsv = $ExportCsv CsvPath = $CsvPath ExportHtml = $ExportHtml HtmlPath = $HtmlPath HtmlGroupBy = $HtmlGroupBy } Start-MonitoringLoop @MonitoringParams } catch [System.Management.Automation.HaltCommandException] { Write-Host "`n=== Monitoring stopped by user ===" -ForegroundColor Green } catch { Write-Host "`n=== ERROR ===" -ForegroundColor Red Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Yellow throw } } |