Private/Paths.ps1
|
#Requires -Version 5.1 function Get-SMBeatDefaultDataRoot { $pd = $env:ProgramData if ([string]::IsNullOrWhiteSpace($pd)) { if (-not [string]::IsNullOrWhiteSpace($env:HOME)) { return (Join-Path $env:HOME '.smbeat') } return (Join-Path ([System.IO.Path]::GetTempPath()) 'SMBeat') } Join-Path $pd 'SMBeat' } function Get-SMBeatDefaultReportRoot { $pd = $env:ProgramData if ([string]::IsNullOrWhiteSpace($pd)) { if (-not [string]::IsNullOrWhiteSpace($env:HOME)) { return (Join-Path $env:HOME '.smbeat-reports') } return (Join-Path ([System.IO.Path]::GetTempPath()) 'SMBeat-Reports') } Join-Path $pd 'SMBeat-Reports' } function Get-SMBeatDataRoot { param( [string]$Path, [string]$ComputerName ) $root = $Path if ([string]::IsNullOrWhiteSpace($root)) { $root = Get-SMBeatDefaultDataRoot } if (-not [string]::IsNullOrWhiteSpace($ComputerName)) { $root = Join-Path $root $ComputerName } return $root } function Get-SMBeatSampleDirectory { param( [Parameter(Mandatory = $true)] [string]$DataRoot ) Join-Path $DataRoot 'samples' } function Get-SMBeatSampleFilePath { param( [Parameter(Mandatory = $true)] [string]$DataRoot, [Parameter(Mandatory = $true)] [datetime]$Utc ) $day = $Utc.ToString('yyyy-MM-dd', $script:SMBeatInvariant) Join-Path (Get-SMBeatSampleDirectory -DataRoot $DataRoot) ($day + '.jsonl') } function Get-SMBeatStatePath { param( [Parameter(Mandatory = $true)] [string]$DataRoot ) Join-Path $DataRoot 'state.json' } function Get-SMBeatHeartbeatPath { param( [Parameter(Mandatory = $true)] [string]$DataRoot ) Join-Path $DataRoot 'heartbeat.json' } function Get-SMBeatConfigPath { param( [Parameter(Mandatory = $true)] [string]$DataRoot ) Join-Path $DataRoot 'config.json' } function Get-SMBeatLogPath { param( [Parameter(Mandatory = $true)] [string]$DataRoot ) Join-Path $DataRoot 'collector.log' } function Get-SMBeatStopRequestPath { param( [Parameter(Mandatory = $true)] [string]$DataRoot ) Join-Path $DataRoot 'stop.request' } function Get-SMBeatFlushRequestPath { param( [Parameter(Mandatory = $true)] [string]$DataRoot ) Join-Path $DataRoot 'flush.request' } function Get-SMBeatCollectorScriptPath { Join-Path $script:SMBeatModuleRoot 'Scripts\Invoke-SMBeatCollector.ps1' } function Get-SMBeatPowerShellExePath { Join-Path $env:SystemRoot 'System32\WindowsPowerShell\v1.0\powershell.exe' } function Get-SMBeatModuleVersion { $mod = Get-Module -Name SMBeat -ErrorAction SilentlyContinue if ($mod -and $mod.Version) { return $mod.Version.ToString() } $psd1 = Join-Path $script:SMBeatModuleRoot 'SMBeat.psd1' if (Test-Path -LiteralPath $psd1) { $data = Import-PowerShellDataFile -Path $psd1 -ErrorAction SilentlyContinue if ($data -and $data.ModuleVersion) { return [string]$data.ModuleVersion } } return 'unknown' } function Get-SMBeatInstallDestination { $pf = $env:ProgramFiles if ([string]::IsNullOrWhiteSpace($pf)) { return '' } Join-Path $pf 'WindowsPowerShell\Modules\SMBeat' } function Get-SMBeatModuleCopyNames { @('SMBeat.psd1', 'SMBeat.psm1', 'Public', 'Private', 'Scripts', 'en-US', 'LICENSE') } function Copy-SMBeatModuleToDestination { param( [Parameter(Mandatory = $true)] [string]$Destination, [string]$SourceRoot ) if ([string]::IsNullOrWhiteSpace($SourceRoot)) { $SourceRoot = $script:SMBeatModuleRoot } if ([string]::IsNullOrWhiteSpace($Destination)) { throw 'SMBeat install destination is empty.' } if (-not (Test-Path -LiteralPath $Destination)) { New-Item -ItemType Directory -Path $Destination -Force | Out-Null } foreach ($name in Get-SMBeatModuleCopyNames) { $from = Join-Path $SourceRoot $name if (Test-Path -LiteralPath $from) { Copy-Item -LiteralPath $from -Destination $Destination -Recurse -Force } } return $Destination } function Get-SMBeatLatestInstalledVersion { $list = @(Get-Module -Name SMBeat -ListAvailable -ErrorAction SilentlyContinue | Sort-Object Version) if ($list.Count -gt 0) { return $list[$list.Count - 1].Version.ToString() } return (Get-SMBeatModuleVersion) } function Update-SMBeatInstalledModule { $methods = New-Object System.Collections.Generic.List[string] $dest = Get-SMBeatInstallDestination if (Get-Command Update-Module -ErrorAction SilentlyContinue) { try { Update-Module -Name SMBeat -Force -ErrorAction Stop $methods.Add('gallery') | Out-Null } catch { } } if (-not [string]::IsNullOrWhiteSpace($dest)) { try { Copy-SMBeatModuleToDestination -Destination $dest | Out-Null $methods.Add('copy') | Out-Null } catch { } } $path = $dest if ([string]::IsNullOrWhiteSpace($path)) { $path = $script:SMBeatModuleRoot } [PSCustomObject]@{ Methods = $methods.ToArray() ModulePath = $path Version = Get-SMBeatLatestInstalledVersion } } function ConvertTo-SMBeatHashtable { param( $Object ) $hash = @{} if ($null -eq $Object) { return $hash } if ($Object -is [hashtable]) { return $Object } foreach ($prop in $Object.PSObject.Properties) { $hash[$prop.Name] = $prop.Value } return $hash } function Get-SMBeatPropertyValue { param( $Object, [Parameter(Mandatory = $true)] [string]$Name, $Default ) if ($null -eq $Object) { return $Default } if ($Object -is [hashtable]) { if ($Object.ContainsKey($Name)) { return $Object[$Name] } return $Default } $prop = $Object.PSObject.Properties[$Name] if ($null -eq $prop) { return $Default } return $prop.Value } function Get-SMBeatDefaultConfig { [PSCustomObject]@{ IntervalSec = $script:SMBeatDefaultIntervalSec RetentionDays = $script:SMBeatDefaultRetentionDays Path = Get-SMBeatDefaultDataRoot IncludeNics = $true IncludeEtwShares = $true IncludeSmbPerf = $true IncludeAdminShares = $false Mode = 'tcp445+etw' } } function Read-SMBeatConfig { param( [string]$DataRoot ) if ([string]::IsNullOrWhiteSpace($DataRoot)) { $DataRoot = Get-SMBeatDefaultDataRoot } $path = Get-SMBeatConfigPath -DataRoot $DataRoot $json = Read-SMBeatTextFile -Path $path $defaults = Get-SMBeatDefaultConfig if ($null -eq $json) { return $defaults } $parsed = ConvertFrom-SMBeatJson -Json $json $result = ConvertTo-SMBeatHashtable -Object $defaults foreach ($prop in $parsed.PSObject.Properties) { $result[$prop.Name] = $prop.Value } [PSCustomObject]$result } function Save-SMBeatConfig { param( [Parameter(Mandatory = $true)] [string]$DataRoot, [Parameter(Mandatory = $true)] $Config ) $path = Get-SMBeatConfigPath -DataRoot $DataRoot Write-SMBeatTextFile -Path $path -Text (ConvertTo-SMBeatJson -InputObject $Config) } function Write-SMBeatLog { param( [Parameter(Mandatory = $true)] [string]$DataRoot, [Parameter(Mandatory = $true)] [string]$Message ) $line = '{0} {1}{2}' -f (ConvertTo-SMBeatUtcString -DateTime (Get-SMBeatUtcNow)), $Message, [Environment]::NewLine Add-SMBeatTextFile -Path (Get-SMBeatLogPath -DataRoot $DataRoot) -Text $line } |