Public/Start-tpcMonitor.ps1

function Start-tpcMonitor {
    <#
    .SYNOPSIS
        Starts real-time performance counter monitoring for local or remote systems using predefined configuration templates with language-independent counter IDs.
 
    .DESCRIPTION
        This function launches the main monitoring interface of the psTerminalPerfCounter module. It loads performance
        counter configurations from JSON templates, validates counter availability, and starts continuous real-time
        monitoring with configurable update intervals and data retention.
 
        The function uses the module's language-independent ID system to ensure configurations work across different
        system locales. It automatically filters unavailable counters and provides detailed feedback about monitoring status.
        Supports interactive monitoring with graphical displays, tables, and statistics based on configuration settings.
 
        Monitoring can be performed on the local system or on remote computers by specifying ComputerName parameter.
        Remote monitoring requires appropriate permissions and network connectivity to the target system.
 
    .PARAMETER ConfigName
        Name of the configuration template to load (without 'tpc_' prefix and '.json' extension).
        Must correspond to a JSON file in the config directories (e.g., 'CPU' loads 'tpc_CPU.json').
        Default: 'CPU'
        Cannot be used together with ConfigPath parameter.
        Required when using remote monitoring with ComputerName parameter.
 
    .PARAMETER ConfigPath
        Absolute path to a specific JSON configuration file.
        The file must follow the naming convention 'tpc_*.json' and exist at the specified location.
        Cannot be used together with ConfigName parameter.
        Only available for local monitoring.
 
    .PARAMETER ComputerName
        DNS name of the remote computer to monitor.
        Requires ConfigName parameter to be specified.
        The remote system must be reachable and allow remote performance counter access.
 
    .PARAMETER Credential
        PSCredential object for authenticating to the remote computer.
        If not specified, uses the current user's credentials.
        Only applicable when ComputerName is specified.
 
    .PARAMETER UpdateInterval
        Interval in seconds between performance counter updates and display refreshes.
        Lower values provide more responsive monitoring but increase system load.
        Graph time span = Samples (from JSON config) × UpdateInterval seconds.
        Default: 1 second
 
    .PARAMETER MaxHistoryPoints
        Maximum number of historical data points to retain in memory for each counter.
        This is the complete historical data used for statistics and future export.
        Independent of graph display width. Time span covered by graph display = Samples × UpdateInterval seconds.
        Default: 100 historical data points
 
    .EXAMPLE
        Start-tpcMonitor
 
        Starts monitoring using the default CPU configuration with 1-second updates and 100 historical data points.
        Graph displays 70 samples covering 70 seconds (70 samples × 1 second interval).
 
    .EXAMPLE
        Start-tpcMonitor -ConfigPath "C:\MyConfigs\tpc_CustomCPU.json"
 
        Starts monitoring using a custom configuration file from an absolute path.
 
    .EXAMPLE
        Start-tpcMonitor -ConfigName "Memory" -UpdateInterval 2
 
        Starts memory monitoring with 2-second update intervals using the 'tpc_Memory.json' configuration.
 
    .EXAMPLE
        Start-tpcMonitor -ConfigName "Disk" -UpdateInterval 1 -MaxHistoryPoints 200
 
        Starts disk monitoring with 1-second updates and extended data retention of 200 points.
 
    .EXAMPLE
        Start-tpcMonitor -ConfigName "CPU" -ComputerName "Server01"
 
        Monitors CPU performance on remote server 'Server01' using current user credentials.
 
    .EXAMPLE
        Start-tpcMonitor -ConfigName "Memory" -ComputerName "SQLServer01" -Credential $cred
 
        Monitors memory performance on remote server 'SQLServer01' using specified credentials.
 
    .OUTPUTS
        Interactive real-time monitoring display with configurable output formats:
        - Graphical plots (line, bar, scatter based on configuration)
        - Statistical summaries (min, max, average, current values)
        - Tabular data with formatted values and units
        - Session summary upon completion
 
    .NOTES
        Main entry point for the psTerminalPerfCounter monitoring system.
        Requires JSON configuration files in the module's config directory or custom directories.
        Press Ctrl+C to stop monitoring and display session summary.
 
        Remote monitoring requires:
        - Network connectivity to target system
        - Appropriate permissions for remote performance counter access
        - Windows Remote Management (WinRM) enabled on target system
    #>


    [CmdletBinding()]
    param(
        [Parameter(ParameterSetName = 'ConfigName',         Mandatory)]
        [Parameter(ParameterSetName = 'SingleRemoteServer', Mandatory)]
        [string]        $ConfigName,

        [Parameter(ParameterSetName = 'ConfigPath',         Mandatory)]
        [string]        $ConfigPath,

<# for later releases
        [Parameter(ParameterSetName = 'RemoteServerConfig', Mandatory)]
        [string] $RemoteServerConfig,
        [Parameter(ParameterSetName = 'RemoteServerConfig' )]
        [switch] $showConsoleTable,
#>

        [Parameter(ParameterSetName = 'SingleRemoteServer', Mandatory)]
        [string]        $ComputerName,
        [Parameter(ParameterSetName = 'SingleRemoteServer')]
        [pscredential]  $Credential = $null,

        [int]           $UpdateInterval     = 1,
        [int]           $MaxHistoryPoints   = 100
# [switch] $visHTML,
# [switch] $exportJson
    )

    BEGIN {

        $config         = @()
        $monitorType    = 'local'

    }

    PROCESS {

        try {


            if ( $PSCmdlet.ParameterSetName -eq 'ConfigPath' ) {

                $monitorType = 'local'

                if ( -not (Test-Path $ConfigPath) ) {
                    Write-Warning "Configuration file not found: $ConfigPath"
                    Return
                }

                $fileName = Split-Path $ConfigPath -Leaf
                if ( $fileName -notmatch '^tpc_.+\.json$' ) {
                    Write-Warning "Invalid configuration file name. File must follow the pattern 'tpc_*.json'. Found: $fileName"
                    Return
                }

                Write-Host "Loading configuration from '$ConfigPath'..." -ForegroundColor Yellow
                $Config = Get-CounterConfiguration -ConfigPath $ConfigPath

                foreach ( $counter in $Config.Counters ) {
                    $counter.TestAvailability()
                }

            } elseif ( $PSCmdlet.ParameterSetName -eq 'ConfigName' ) {

                $monitorType = 'local'

                Write-Host "Loading configuration '$ConfigName'..." -ForegroundColor Yellow
                $Config = Get-CounterConfiguration -ConfigName $ConfigName

                foreach ( $counter in $Config.Counters ) {
                    $counter.TestAvailability()
                }

            <# } elseif ( $PSCmdlet.ParameterSetName -eq 'RemoteServerConfig' ) {
 
                $monitorType = 'remoteMulti'
 
                Write-Host "Loading remote server configuration from '$RemoteServerConfig'..." -ForegroundColor Yellow
 
                if ( -not (Test-Path $RemoteServerConfig) ) {
                    Write-Warning "Server Configuration file not found: $RemoteServerConfig"
                    Return
                }
 
                $Config = Get-ServerConfiguration -pathServerConfiguration $RemoteServerConfig
 
                if ( $Config.Servers.Count -eq 0 ) {
                    Write-Warning "No valid servers found in remote server configuration '$RemoteServerConfig'"
                    Return
                } #>


            } elseif ( $PSCmdlet.ParameterSetName -eq 'SingleRemoteServer' ) {

                $monitorType = 'remoteSingle'

                Write-Host "Starting remote monitoring for $computername " -ForegroundColor Yellow -NoNewline

                if ( $credential ) {
                    Write-Host "using $($credential.UserName)." -ForegroundColor Yellow -NoNewline
                } else {
                    Write-Host "using $(whoami)." -ForegroundColor Yellow
                }

                if ( Test-Connection -ComputerName $ComputerName -Count 1 -Quiet ) {

                    $Config = Get-CounterConfiguration -ConfigName $ConfigName -isRemote -computername $ComputerName -credential $credential

                    $config.name = "$($Config.Name) @ REMOTE $($ComputerName)"


                } else {
                    Write-Warning "Remote computer $computername not reachable. Aborting"
                    Return
                }

            } else {
                throw "Invalid parameter set. Use ConfigName, ConfigPath, or RemoteServerConfig."
            }

            # Validate remote server, server count, only one is allowed to be visualized with graph in console. use -showTable or -visHTML

<# for later releases
            if ( $PSCmdlet.ParameterSetName -eq 'RemoteServerConfig' ) {
 
                if ( -not $showConsoleTable.IsPresent ) {
 
                    if ( $Config.Servers.Count -gt 1 ) {
 
                        Write-Host "Multiple remote servers found. Please select which server to visualize in console (or use switch -showConsoleTable):" -ForegroundColor Yellow
                        Write-Host ""
 
                        # Display server selection menu
                        Write-Host "[0] Abort monitoring" -ForegroundColor Red
                        for ( $i = 0; $i -lt $Config.Servers.Count; $i++ ) {
                            $server = $Config.Servers[$i]
                            Write-Host "[$($i + 1)] $($server.serverName) - $($server.serverComment)" -ForegroundColor Cyan
                        }
                        Write-Host ""
 
                        # Get user selection
                        do {
                            $selection = Read-Host "Enter your choice (0 to abort, 1-$($Config.Servers.Count) to select server)"
                            $selectedIndex = $null
 
                            if ( [int]::TryParse($selection, [ref]$selectedIndex) ) {
 
                                if ( $selectedIndex -eq 0 ) {
                                    Write-Host "Monitoring aborted by user." -ForegroundColor Red
                                    return
                                }
 
                                $selectedIndex = $selectedIndex - 1 # Convert to 0-based index
                                if ( $selectedIndex -ge 0 -and $selectedIndex -lt $Config.Servers.Count ) {
                                    break
                                }
 
                            }
 
                            Write-Host "Invalid selection. Please enter 0 to abort or a number between 1 and $($Config.Servers.Count)." -ForegroundColor Red
 
                        } while ($true)
 
                        # Clean up config
                        $selectedServer = $Config.Servers[$selectedIndex]
                        $Config.Servers = @($selectedServer)
 
                        Write-Host "Selected server: $($selectedServer.serverName)" -ForegroundColor Green
                        Write-Host ""
 
                    }
 
                    # rebuild config for directly use local monitoring loop
                    if ( $Config.Servers.Count -eq 1) {
 
                        $monitorType = 'remoteSingle'
 
                        $config = @{
                            Name = "$($Config.Servers[0].PerformanceCounters[0].Name) - REMOTE $($Config.Servers[0].serverName)" # currently only one key ( counter configuration ) is supported
                            Description = "Remote monitoring of $($Config.Servers[0].serverName)"
                            ConfigPath = "REMOTE CONFIG"
                            Counters = $Config.Servers[0].PerformanceCounters[0].Counters
                        }
 
                    }
 
                } elseif ( $showConsoleTable.IsPresent ) {
 
                    # set all counter formats to table
                    foreach ( $server in $Config.servers ) {
                        foreach ( $counter in $server.PerformanceCounters ) {
                            $counter.format = "Table"
                        }
                    }
 
                }
 
                if ( $exportJson.IsPresent ) {
 
                    # write to json
 
                }
 
                if ( $visHTML.IsPresent ) {
 
                    # write to json
 
                    # load HTML
 
                }
 
 
 
            }
#>


            # Start monitoring
            $MonitoringParams = @{
                MonitorType     = $monitorType
                Config          = $Config
                UpdateInterval  = $UpdateInterval
                MaxDataPoints   = $MaxHistoryPoints
            }

            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

        } finally {

            if ( $PSCmdlet.ParameterSetName -in @('ConfigName', 'ConfigPath') ) {

                if ( $availabilityResult.Success -eq $true ) {
                    Show-SessionSummary -Counters $config.Counters
                }

            }

        }

    }

    END {

    }

}