Private/Culture.ps1
|
#Requires -Version 5.1 function Get-SMBeatUtcNow { [DateTime]::UtcNow } function ConvertTo-SMBeatUtcString { param( [Parameter(Mandatory = $true)] [datetime]$DateTime ) $utc = $DateTime if ($utc.Kind -eq [DateTimeKind]::Local) { $utc = $utc.ToUniversalTime() } elseif ($utc.Kind -eq [DateTimeKind]::Unspecified) { $utc = [datetime]::SpecifyKind($utc, [DateTimeKind]::Utc) } $utc.ToString('yyyy-MM-ddTHH:mm:ssZ', $script:SMBeatInvariant) } function ConvertFrom-SMBeatUtcString { param( [Parameter(Mandatory = $true)] [string]$Value ) [datetime]::Parse( $Value, $script:SMBeatInvariant, [System.Globalization.DateTimeStyles]::AdjustToUniversal -bor [System.Globalization.DateTimeStyles]::AssumeUniversal ) } function Get-SMBeatRecordUtc { param( $Record ) if ($null -eq $Record) { return [datetime]::MinValue } if ($Record.PSObject.Properties['TsUtc'] -and $null -ne $Record.TsUtc) { $utc = [datetime]$Record.TsUtc if ($utc.Kind -eq [DateTimeKind]::Utc) { return $utc } return [datetime]::SpecifyKind($utc, [DateTimeKind]::Utc) } if ($Record.PSObject.Properties['ts'] -and $Record.ts) { return ConvertFrom-SMBeatUtcString -Value ([string]$Record.ts) } [datetime]::MinValue } function ConvertTo-SMBeatJson { param( [Parameter(Mandatory = $true)] $InputObject ) ConvertTo-Json -InputObject $InputObject -Depth 8 -Compress:$false } function ConvertFrom-SMBeatJson { param( [Parameter(Mandatory = $true)] [string]$Json ) ConvertFrom-Json -InputObject $Json } function Test-SMBeatSharingViolation { param($Exception) $cur = $Exception $n = 0 while ($null -ne $cur -and $n -lt 6) { if ($cur -is [System.IO.IOException]) { $code = [int]($cur.HResult -band 0xFFFF) if ($code -eq 32 -or $code -eq 33) { return $true } } $cur = $cur.InnerException $n++ } $false } function Invoke-SMBeatIoRetry { param( [Parameter(Mandatory = $true)] [scriptblock]$Action, [int]$Tries = 8 ) $n = 0 while ($true) { try { return (& $Action) } catch { $n++ if ($n -ge $Tries -or -not (Test-SMBeatSharingViolation -Exception $_.Exception)) { throw } Start-Sleep -Milliseconds (50 * $n) } } } function Write-SMBeatTextFile { param( [Parameter(Mandatory = $true)] [string]$Path, [Parameter(Mandatory = $true)] [string]$Text ) $dir = Split-Path -Parent $Path if (-not (Test-Path -LiteralPath $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } Invoke-SMBeatIoRetry -Action { $fs = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite) try { $bytes = $script:SMBeatUtf8NoBom.GetBytes($Text) $fs.Write($bytes, 0, $bytes.Length) } finally { $fs.Dispose() } } } function Add-SMBeatTextFile { param( [Parameter(Mandatory = $true)] [string]$Path, [Parameter(Mandatory = $true)] [string]$Text ) $dir = Split-Path -Parent $Path if (-not (Test-Path -LiteralPath $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } Invoke-SMBeatIoRetry -Action { $fs = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Append, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite) try { $bytes = $script:SMBeatUtf8NoBom.GetBytes($Text) $fs.Write($bytes, 0, $bytes.Length) } finally { $fs.Dispose() } } } function Read-SMBeatTextFile { param( [Parameter(Mandatory = $true)] [string]$Path ) if (-not (Test-Path -LiteralPath $Path)) { return $null } Invoke-SMBeatIoRetry -Action { $fs = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite) try { $sr = New-Object System.IO.StreamReader($fs, $script:SMBeatUtf8NoBom, $true) try { $sr.ReadToEnd() } finally { $sr.Dispose() } } finally { } } } function New-SMBeatSharedStreamReader { param( [Parameter(Mandatory = $true)] [string]$Path ) Invoke-SMBeatIoRetry -Action { $fs = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite) New-Object System.IO.StreamReader($fs, $script:SMBeatUtf8NoBom, $true) } } function Get-SMBeatLanguage { param( [string]$Language ) if (-not [string]::IsNullOrWhiteSpace($Language)) { $normalized = $Language.Trim().ToLowerInvariant() if ($normalized -eq 'de' -or $normalized.StartsWith('de-')) { return 'de' } return 'en' } $ui = [string]$PSUICulture if ($ui.StartsWith('de', [System.StringComparison]::OrdinalIgnoreCase)) { return 'de' } return 'en' } function Resolve-SMBeatTimeZone { param( [object]$TimeZone ) if ($null -eq $TimeZone -or ($TimeZone -is [string] -and [string]::IsNullOrWhiteSpace([string]$TimeZone))) { return [TimeZoneInfo]::Local } if ($TimeZone -is [TimeZoneInfo]) { return $TimeZone } return [TimeZoneInfo]::FindSystemTimeZoneById([string]$TimeZone) } function Convert-SMBeatUtcToTimeZone { param( [Parameter(Mandatory = $true)] [datetime]$Utc, [Parameter(Mandatory = $true)] [TimeZoneInfo]$TimeZone ) $asUtc = $Utc if ($asUtc.Kind -eq [DateTimeKind]::Local) { $asUtc = $asUtc.ToUniversalTime() } else { $asUtc = [datetime]::SpecifyKind($asUtc, [DateTimeKind]::Utc) } [TimeZoneInfo]::ConvertTimeFromUtc($asUtc, $TimeZone) } function Convert-SMBeatTimeZoneToUtc { param( [Parameter(Mandatory = $true)] [datetime]$LocalTime, [Parameter(Mandatory = $true)] [TimeZoneInfo]$TimeZone ) if ($LocalTime.Kind -eq [DateTimeKind]::Utc) { return $LocalTime } $unspec = [datetime]::SpecifyKind($LocalTime, [DateTimeKind]::Unspecified) [TimeZoneInfo]::ConvertTimeToUtc($unspec, $TimeZone) } function Get-SMBeatByteDelta { param( [Parameter(Mandatory = $true)] [uint64]$Current, [uint64]$Previous ) if ($Current -ge $Previous) { return [int64]($Current - $Previous) } # Counter reset (reboot / instance recycle). Treat current raw as the new total for this interval. return [int64]$Current } function Get-SMBeatBucketStart { param( [Parameter(Mandatory = $true)] [datetime]$LocalTime, [Parameter(Mandatory = $true)] [ValidateSet('Hour', 'Day', 'Week')] [string]$Granularity ) $kind = $LocalTime.Kind switch ($Granularity) { 'Hour' { return New-Object datetime $LocalTime.Year, $LocalTime.Month, $LocalTime.Day, $LocalTime.Hour, 0, 0, $kind } 'Day' { return New-Object datetime $LocalTime.Year, $LocalTime.Month, $LocalTime.Day, 0, 0, 0, $kind } 'Week' { $date = New-Object datetime $LocalTime.Year, $LocalTime.Month, $LocalTime.Day, 0, 0, 0, $kind $offset = ([int]$date.DayOfWeek + 6) % 7 return $date.AddDays(-1 * $offset) } } } function Get-SMBeatBucketEnd { param( [Parameter(Mandatory = $true)] [datetime]$BucketStart, [Parameter(Mandatory = $true)] [ValidateSet('Hour', 'Day', 'Week')] [string]$Granularity ) switch ($Granularity) { 'Hour' { return $BucketStart.AddHours(1) } 'Day' { return $BucketStart.AddDays(1) } 'Week' { return $BucketStart.AddDays(7) } } } function ConvertTo-SMBeatGB { param( [int64]$Bytes ) [math]::Round(([double]$Bytes / 1000000000.0), 3) } function ConvertTo-SMBeatGiB { param( [int64]$Bytes ) ConvertTo-SMBeatGB -Bytes $Bytes } function Get-SMBeatInstanceLeafName { param( [string]$Name ) if ([string]::IsNullOrWhiteSpace($Name)) { return $Name } $idx = $Name.LastIndexOf('\') if ($idx -ge 0 -and $idx -lt ($Name.Length - 1)) { return $Name.Substring($idx + 1) } return $Name } function Test-SMBeatAdminShareName { param( [string]$Name ) if ([string]::IsNullOrWhiteSpace($Name)) { return $false } $leaf = Get-SMBeatInstanceLeafName -Name $Name if ($leaf -eq 'IPC$' -or $leaf -eq 'ADMIN$' -or $leaf -eq 'print$') { return $true } if ($leaf.Length -eq 2 -and $leaf.EndsWith('$') -and $leaf[0] -match '[A-Za-z]') { return $true } return $false } function Test-SMBeatSkipInstance { param( [string]$Name, [string]$Kind, [switch]$IncludeAdminShares ) if ([string]::IsNullOrWhiteSpace($Name)) { return $true } if ($Name -eq '_Total' -or $Name -like '*_Total*') { return $true } $leaf = Get-SMBeatInstanceLeafName -Name $Name if (($Kind -eq 'share' -or $Kind -eq 'smbperf') -and $leaf -eq 'IPC$') { return $true } if (($Kind -eq 'share' -or $Kind -eq 'smbperf') -and -not $IncludeAdminShares -and (Test-SMBeatAdminShareName -Name $Name)) { return $true } return $false } |