Public/Reset-SMBeat.ps1

#Requires -Version 5.1

function Reset-SMBeat {
    <#
    .SYNOPSIS
        Updates the module, wipes collector data, and starts a fresh measurement.
    .DESCRIPTION
        Stops the task, deletes the data root (samples, heartbeat, logs), updates
        the installed module (Gallery Update-Module when possible, then a copy of
        the currently loaded module into Program Files), and registers the
        collector again. Remote calls push this session's module first.
        Does not touch a manual Perfmon set.
    .PARAMETER Force
        Do not prompt before deleting data.
    .PARAMETER Wait
        Wait until the first heartbeat is fresh. Default is true.
    #>

    [CmdletBinding(DefaultParameterSetName = 'Local', SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param(
        [Parameter(ParameterSetName = 'ComputerName', ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [string[]]$ComputerName,

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

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

        [string]$Path,
        [int]$IntervalSec = 60,
        [int]$RetentionDays = 90,
        [bool]$IncludeNics = $true,
        [bool]$IncludeSmbPerf = $true,
        [bool]$Wait = $true,
        [int]$WaitTimeoutSec = 90,
        [switch]$Force
    )

    begin {
        Assert-SMBeatRemotingExclusive -ComputerName $ComputerName -CimSession $null -Session $Session
        $payload = @{
            Path               = $Path
            IntervalSec        = $IntervalSec
            RetentionDays      = $RetentionDays
            IncludeNics        = $IncludeNics
            IncludeSmbPerf     = $IncludeSmbPerf
            IncludeEtwShares   = $true
            IncludeAdminShares = $false
            Wait               = [bool]$Wait
            WaitTimeoutSec     = $WaitTimeoutSec
            PassThru           = $true
        }
    }

    process {
        if ($PSCmdlet.ParameterSetName -eq 'Local') {
            $roots = @(Get-SMBeatDataRootsToRemove -Path $Path)
            $label = $roots -join ', '
            if ([string]::IsNullOrWhiteSpace($label)) {
                $label = Get-SMBeatDefaultDataRoot
            }
            if (-not $Force -and -not $PSCmdlet.ShouldProcess($label, 'Update SMBeat module, delete samples, and start a fresh collector')) {
                return
            }
            Reset-SMBeatLocal -Payload $payload
            return
        }

        $targetLabel = ''
        if ($PSCmdlet.ParameterSetName -eq 'Session') {
            $names = New-Object System.Collections.Generic.List[string]
            foreach ($s in $Session) {
                $names.Add([string]$s.ComputerName) | Out-Null
            }
            $targetLabel = $names -join ', '
        }
        else {
            $targetLabel = $ComputerName -join ', '
        }
        if (-not $Force -and -not $PSCmdlet.ShouldProcess($targetLabel, 'Update SMBeat module, delete samples, and start a fresh collector')) {
            return
        }

        $installParams = @{
            ThrottleLimit = $ThrottleLimit
        }
        if ($PSCmdlet.ParameterSetName -eq 'Session') {
            $installParams['Session'] = $Session
        }
        else {
            $installParams['ComputerName'] = $ComputerName
            if ($Credential) { $installParams['Credential'] = $Credential }
            if ($PSBoundParameters.ContainsKey('Authentication')) { $installParams['Authentication'] = $Authentication }
            if ($UseSSL) { $installParams['UseSSL'] = $true }
            if ($Port) { $installParams['Port'] = $Port }
            if ($SessionOption) { $installParams['SessionOption'] = $SessionOption }
        }
        Install-SMBeat @installParams | Out-Null

        $remotePayload = @{
            Path           = $Path
            IntervalSec    = $IntervalSec
            RetentionDays  = $RetentionDays
            IncludeNics    = $IncludeNics
            IncludeSmbPerf = $IncludeSmbPerf
            Wait           = [bool]$Wait
            WaitTimeoutSec = $WaitTimeoutSec
        }
        $sb = {
            param($P)
            Import-Module SMBeat -Force -ErrorAction Stop
            $splat = @{
                Force          = $true
                IntervalSec    = $P.IntervalSec
                RetentionDays  = $P.RetentionDays
                IncludeNics    = $P.IncludeNics
                IncludeSmbPerf = $P.IncludeSmbPerf
                Wait           = [bool]$P.Wait
                WaitTimeoutSec = $P.WaitTimeoutSec
            }
            if ($P.Path) { $splat['Path'] = $P.Path }
            Reset-SMBeat @splat
        }
        $invoke = @{
            ScriptBlock   = $sb
            ArgumentList  = @($remotePayload)
            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
    }
}