Public/Invoke-SMBeatSample.ps1

#Requires -Version 5.1

function Invoke-SMBeatSample {
    <#
    .SYNOPSIS
        Captures one SMB/NIC counter sample and appends byte deltas to JSONL.
    .DESCRIPTION
        Reads locale-independent CIM raw counters, computes deltas against the last sample,
        and writes invariant JSONL. The first sample per counter instance is a baseline (no traffic row).
        Use -ComputerName/-Session to run on the target. Use -CimSession to read counters remotely
        and store samples locally (ad-hoc).
    #>

    [CmdletBinding(DefaultParameterSetName = 'Local')]
    param(
        [Parameter(ParameterSetName = 'ComputerName', ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('CN')]
        [string[]]$ComputerName,

        [Parameter(ParameterSetName = 'CimSession')]
        [Microsoft.Management.Infrastructure.CimSession[]]$CimSession,

        [Parameter(ParameterSetName = 'Session')]
        [System.Management.Automation.Runspaces.PSSession[]]$Session,

        [pscredential]$Credential,
        [System.Management.Automation.Runspaces.AuthenticationMechanism]$Authentication,
        [switch]$UseSSL,
        [int]$Port,
        [System.Management.Automation.Remoting.PSSessionOption]$SessionOption,
        [int]$ThrottleLimit = 32,

        [string]$Path,
        [int]$IntervalSec = 60,
        [int]$RetentionDays = 90,
        [bool]$IncludeSessions = $true,
        [bool]$IncludeAdminShares = $false,
        [bool]$IncludeNics = $true
    )

    begin {
        Assert-SMBeatRemotingExclusive -ComputerName $ComputerName -CimSession $CimSession -Session $Session
        $localSplat = @{
            IntervalSec        = $IntervalSec
            RetentionDays      = $RetentionDays
            IncludeSessions    = $IncludeSessions
            IncludeAdminShares = $IncludeAdminShares
            IncludeNics        = $IncludeNics
        }
        if ($Path) { $localSplat['Path'] = $Path }
    }

    process {
        if ($PSCmdlet.ParameterSetName -eq 'CimSession') {
            foreach ($cs in $CimSession) {
                try {
                    Invoke-SMBeatSampleInternal @localSplat -CimSession $cs -AdHocLayout
                }
                catch {
                    $record = New-SMBeatErrorRecord -Message $_.Exception.Message -ComputerName $cs.ComputerName -Exception $_.Exception
                    $PSCmdlet.WriteError($record)
                }
            }
            return
        }

        if ($PSCmdlet.ParameterSetName -eq 'ComputerName' -or $PSCmdlet.ParameterSetName -eq 'Session') {
            $sb = {
                param($Splat)
                Import-Module SMBeat -ErrorAction Stop
                Invoke-SMBeatSample @Splat
            }
            $invoke = @{
                ScriptBlock  = $sb
                ArgumentList = @($localSplat)
                ThrottleLimit = $ThrottleLimit
            }
            if ($PSCmdlet.ParameterSetName -eq 'Session') {
                $invoke['Session'] = $Session
            }
            else {
                $invoke['ComputerName'] = $ComputerName
                if ($Credential) { $invoke['Credential'] = $Credential }
                if ($PSBoundParameters.ContainsKey('Authentication')) { $invoke['Authentication'] = $Authentication }
                if ($UseSSL) { $invoke['UseSSL'] = $true }
                if ($Port) { $invoke['Port'] = $Port }
                if ($SessionOption) { $invoke['SessionOption'] = $SessionOption }
            }
            Invoke-SMBeatRemoteCommand @invoke
            return
        }

        Invoke-SMBeatSampleInternal @localSplat
    }
}