Scripts/compare-blg-report.ps1
|
#Requires -Version 5.1 # Run on FILESERVER (powershell.exe 5.1). Stop the Perfmon set first. # Evaluates the .blg only. Paste the output here to compare with the HTML report. # # powershell.exe -NoProfile -File .\compare-blg-report.ps1 # powershell.exe -NoProfile -File .\compare-blg-report.ps1 -Start '2026-08-30 13:49' -End '2026-08-30 14:49' [CmdletBinding()] param( [string]$BlgPath = 'C:\PerfLogs\Admin\SMB_MBF\FILESERVER_20260830-000001\DataCollector01.blg', [datetime]$Start, [datetime]$End ) $ErrorActionPreference = 'Stop' function ConvertTo-SMBeatCompareGB { param([double]$Bytes) [math]::Round(($Bytes / 1000000000.0), 3) } function ConvertFrom-SMBeatCompareNumber { param([string]$Text) if ([string]::IsNullOrWhiteSpace($Text)) { return $null } $s = $Text.Trim().Trim('"') if ($s.Length -eq 0 -or $s -eq '-' -or $s -eq ' ') { return $null } $n = 0.0 if ([double]::TryParse($s, [System.Globalization.NumberStyles]::Float, [cultureinfo]::GetCultureInfo('de-DE'), [ref]$n)) { return $n } if ([double]::TryParse($s, [System.Globalization.NumberStyles]::Float, [cultureinfo]::InvariantCulture, [ref]$n)) { return $n } return $null } function ConvertFrom-SMBeatCompareWhen { param([string]$Text) $s = $Text.Trim().Trim('"') $styles = [System.Globalization.DateTimeStyles]::AllowWhiteSpaces $dto = [datetime]::MinValue foreach ($cult in @([cultureinfo]::GetCultureInfo('de-DE'), [cultureinfo]::InvariantCulture, [cultureinfo]::GetCultureInfo('en-US'))) { if ([datetime]::TryParse($s, $cult, $styles, [ref]$dto)) { return $dto } } return $null } function Test-SMBeatCompareHeader { param( [string]$Header, [string]$Kind ) $h = $Header.ToLowerInvariant() $isShare = ($h -like '*freigabe*' -or $h -like '*share*') $isSmb = ($h -like '*smb-server*' -or $h -like '*smb server*' -or $h -like '*smbserver*') $isNic = ($h -like '*netzwerkschnittstelle*' -or $h -like '*network interface*') $isSent = ($h -like '*gesendete*' -or $h -like '*bytes sent*' -or $h -like '*bytes gesendet*' -or $h -like '*sent bytes*') $isRecv = ($h -like '*empfangene*' -or $h -like '*bytes received*' -or $h -like '*bytes empfangen*' -or $h -like '*received bytes*') $isPrivat = ($h -like '*privat*') $isAdmin = ($h -like '*admin$*' -or $h -like '*ipc$*') if ($Kind -eq 'smbServerSent') { return ($isSmb -and -not $isShare -and $isSent) } if ($Kind -eq 'smbServerRecv') { return ($isSmb -and -not $isShare -and $isRecv) } if ($Kind -eq 'sharePrivatSent') { return ($isShare -and $isPrivat -and $isSent -and -not $isAdmin) } if ($Kind -eq 'sharePrivatRecv') { return ($isShare -and $isPrivat -and $isRecv -and -not $isAdmin) } if ($Kind -eq 'nicSent') { return ($isNic -and $isSent) } if ($Kind -eq 'nicRecv') { return ($isNic -and $isRecv) } return $false } if ($env:OS -ne 'Windows_NT') { throw 'Needs Windows relog.exe. Run on FILESERVER.' } $blg = $BlgPath if (Test-Path -LiteralPath $BlgPath -PathType Container) { $found = @(Get-ChildItem -LiteralPath $BlgPath -Filter '*.blg' | Sort-Object LastWriteTime -Descending) if ($found.Count -eq 0) { throw ('No .blg in {0}' -f $BlgPath) } $blg = $found[0].FullName } if (-not (Test-Path -LiteralPath $blg)) { throw ('BLG not found: {0}' -f $blg) } $relog = Join-Path $env:SystemRoot 'System32\relog.exe' if (-not (Test-Path -LiteralPath $relog)) { throw 'relog.exe not found.' } $csv = Join-Path $env:TEMP ('smbeat-blg-{0}.csv' -f [guid]::NewGuid().ToString('N')) Write-Host ('BLG : {0}' -f $blg) & $relog $blg -f csv -o $csv | Out-Host if (-not (Test-Path -LiteralPath $csv)) { throw 'relog did not write CSV. Stop the data collector set and retry.' } $lines = @(Get-Content -LiteralPath $csv -Encoding Default | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) if ($lines.Count -lt 2) { throw 'CSV has no samples.' } $headerLine = $lines[0] $sep = ',' if ($headerLine.IndexOf(';') -ge 0 -and ($headerLine.Split(';').Count -gt $headerLine.Split(',').Count)) { $sep = ';' } $headers = @($headerLine.Split($sep)) $idxSmbSent = @() $idxSmbRecv = @() $idxPrivSent = @() $idxPrivRecv = @() $idxNicSent = @() $idxNicRecv = @() for ($i = 1; $i -lt $headers.Count; $i++) { $name = $headers[$i] if (Test-SMBeatCompareHeader -Header $name -Kind 'smbServerSent') { $idxSmbSent += $i } if (Test-SMBeatCompareHeader -Header $name -Kind 'smbServerRecv') { $idxSmbRecv += $i } if (Test-SMBeatCompareHeader -Header $name -Kind 'sharePrivatSent') { $idxPrivSent += $i } if (Test-SMBeatCompareHeader -Header $name -Kind 'sharePrivatRecv') { $idxPrivRecv += $i } if (Test-SMBeatCompareHeader -Header $name -Kind 'nicSent') { $idxNicSent += $i } if (Test-SMBeatCompareHeader -Header $name -Kind 'nicRecv') { $idxNicRecv += $i } } function Show-SMBeatCompareCols { param([string]$Label, [int[]]$Indexes) $text = '(none)' if ($Indexes.Count -gt 0) { $text = ($Indexes | ForEach-Object { $headers[$_] }) -join ' | ' } Write-Host ('{0}: {1}' -f $Label, $text) } Write-Host '' Write-Host '=== columns ===' Show-SMBeatCompareCols -Label 'SMB-Server Out' -Indexes $idxSmbSent Show-SMBeatCompareCols -Label 'SMB-Server In ' -Indexes $idxSmbRecv Show-SMBeatCompareCols -Label 'Privat Out ' -Indexes $idxPrivSent Show-SMBeatCompareCols -Label 'Privat In ' -Indexes $idxPrivRecv Show-SMBeatCompareCols -Label 'NIC Out ' -Indexes $idxNicSent Show-SMBeatCompareCols -Label 'NIC In ' -Indexes $idxNicRecv $sum = @{ smbSent = 0.0 smbRecv = 0.0 privSent = 0.0 privRecv = 0.0 nicSent = 0.0 nicRecv = 0.0 } $used = 0 $first = $null $last = $null $prevWhen = $null function Add-SMBeatCompareRate { param( [hashtable]$Map, [int[]]$Indexes, [string[]]$Cells, [double]$Seconds, [string]$Key ) $rate = 0.0 $any = $false foreach ($i in $Indexes) { if ($i -ge $Cells.Count) { continue } $n = ConvertFrom-SMBeatCompareNumber -Text $Cells[$i] if ($null -ne $n) { $rate += [double]$n $any = $true } } if ($any) { $Map[$Key] = $Map[$Key] + ($rate * $Seconds) } } foreach ($line in ($lines | Select-Object -Skip 1)) { $cells = @($line.Split($sep)) if ($cells.Count -lt 2) { continue } $when = ConvertFrom-SMBeatCompareWhen -Text $cells[0] if ($null -eq $when) { continue } if ($PSBoundParameters.ContainsKey('Start') -and $when -lt $Start) { continue } if ($PSBoundParameters.ContainsKey('End') -and $when -gt $End) { continue } $dt = 60.0 if ($null -ne $prevWhen) { $gap = ($when - $prevWhen).TotalSeconds if ($gap -gt 0 -and $gap -le 3600) { $dt = $gap } } $prevWhen = $when if ($null -eq $first) { $first = $when } $last = $when $used++ Add-SMBeatCompareRate -Map $sum -Indexes $idxSmbSent -Cells $cells -Seconds $dt -Key 'smbSent' Add-SMBeatCompareRate -Map $sum -Indexes $idxSmbRecv -Cells $cells -Seconds $dt -Key 'smbRecv' Add-SMBeatCompareRate -Map $sum -Indexes $idxPrivSent -Cells $cells -Seconds $dt -Key 'privSent' Add-SMBeatCompareRate -Map $sum -Indexes $idxPrivRecv -Cells $cells -Seconds $dt -Key 'privRecv' Add-SMBeatCompareRate -Map $sum -Indexes $idxNicSent -Cells $cells -Seconds $dt -Key 'nicSent' Add-SMBeatCompareRate -Map $sum -Indexes $idxNicRecv -Cells $cells -Seconds $dt -Key 'nicRecv' } Write-Host '' Write-Host '=== window ===' if ($null -eq $first) { Write-Host 'No samples in the selected window.' Remove-Item -LiteralPath $csv -Force -ErrorAction SilentlyContinue return } Write-Host ('From : {0}' -f $first) Write-Host ('To : {0}' -f $last) Write-Host ('Samples : {0}' -f $used) Write-Host ('Seconds : {0:N0}' -f (($last - $first).TotalSeconds)) Write-Host '' Write-Host '=== volume (rate * interval) ===' @( [PSCustomObject]@{ Source = 'SMB-Server Out'; Bytes = [int64]$sum.smbSent; GB = (ConvertTo-SMBeatCompareGB -Bytes $sum.smbSent) } [PSCustomObject]@{ Source = 'SMB-Server In'; Bytes = [int64]$sum.smbRecv; GB = (ConvertTo-SMBeatCompareGB -Bytes $sum.smbRecv) } [PSCustomObject]@{ Source = 'Privat Out'; Bytes = [int64]$sum.privSent; GB = (ConvertTo-SMBeatCompareGB -Bytes $sum.privSent) } [PSCustomObject]@{ Source = 'Privat In'; Bytes = [int64]$sum.privRecv; GB = (ConvertTo-SMBeatCompareGB -Bytes $sum.privRecv) } [PSCustomObject]@{ Source = 'NIC Out'; Bytes = [int64]$sum.nicSent; GB = (ConvertTo-SMBeatCompareGB -Bytes $sum.nicSent) } [PSCustomObject]@{ Source = 'NIC In'; Bytes = [int64]$sum.nicRecv; GB = (ConvertTo-SMBeatCompareGB -Bytes $sum.nicRecv) } ) | Format-Table -AutoSize Write-Host 'Paste this output. HTML is compared in chat, not in this script.' Remove-Item -LiteralPath $csv -Force -ErrorAction SilentlyContinue |