Files
autodesk/migration/tools/plugin-usage-matrix.ps1

66 lines
3.2 KiB
PowerShell

param(
[string]$Source = 'C:\dev\TEMP\Reports',
[string]$Output = 'C:\dev\autodesk\migration\audits\plugin-usage-matrix-20260731'
)
$ErrorActionPreference = 'Stop'
$utf8 = New-Object System.Text.UTF8Encoding($false)
$outputEvidence = Join-Path $Output 'evidence'
New-Item -ItemType Directory -Force -Path $outputEvidence | Out-Null
# The source is read only. Only the three fields captured below are emitted.
$pattern = '^.*?\s+(?<plugin>\S+)\s+(?<internal_code>\S+)\s+(?<time>\d{2}:\d{2}:\d{2})\s+(?<date>\d{2}\.\d{2}\.\d{2,4})\s+(?<computer>\S+)\s*$'
$records = [System.Collections.Generic.List[object]]::new()
$fileCount = 0
$lineCount = 0
$blankCount = 0
$unmatchedCount = 0
foreach ($file in (Get-ChildItem -LiteralPath $Source -Recurse -File | Sort-Object FullName)) {
$fileCount++
foreach ($line in Get-Content -LiteralPath $file.FullName -Encoding UTF8) {
$text = $line.Trim()
if ([string]::IsNullOrWhiteSpace($text)) { $blankCount++; continue }
$lineCount++
if ($text -notmatch $pattern) { $unmatchedCount++; continue }
$dateText = $matches.date
$format = if ($dateText.Length -eq 8) { 'dd.MM.yy' } else { 'dd.MM.yyyy' }
$date = [DateTime]::ParseExact(($dateText + ' ' + $matches.time), ($format + ' HH:mm:ss'), [Globalization.CultureInfo]::InvariantCulture, [Globalization.DateTimeStyles]::None)
$records.Add([pscustomobject]@{
plugin_name = $matches.plugin
launch_timestamp = $date.ToString('yyyy-MM-ddTHH:mm:ss', [Globalization.CultureInfo]::InvariantCulture)
computer_name = $matches.computer
})
}
}
$unique = $records | Sort-Object plugin_name,launch_timestamp,computer_name -Unique
$unique | Export-Csv (Join-Path $Output 'plugin-usage-matrix.csv') -NoTypeInformation -Encoding UTF8
$summary = $unique | Group-Object plugin_name | Sort-Object Name | ForEach-Object {
$items = $_.Group | Sort-Object launch_timestamp,computer_name
[pscustomobject]@{
plugin_name = $_.Name
unique_launches = $items.Count
unique_computers = ($items.computer_name | Sort-Object -Unique).Count
first_launch_timestamp = $items[0].launch_timestamp
last_launch_timestamp = $items[-1].launch_timestamp
}
}
$summary | Export-Csv (Join-Path $Output 'plugin-usage-summary.csv') -NoTypeInformation -Encoding UTF8
$diagnostics = @(
'Input format: one record per non-empty line; only plugin, timestamp and computer fields are retained.',
('Input files: ' + $fileCount),
('Non-empty input records: ' + $lineCount),
('Blank input lines ignored: ' + $blankCount),
('Unmatched non-empty records: ' + $unmatchedCount),
('Parsed records: ' + $records.Count),
('Unique three-attribute records: ' + $unique.Count),
('Unique plugins: ' + (($unique.plugin_name | Sort-Object -Unique).Count)),
('Date normalization: dd.MM.yy and dd.MM.yyyy to yyyy-MM-ddTHH:mm:ss'),
'Sort order: plugin_name, launch_timestamp, computer_name.',
'Project numbers, project names, project paths and source log filenames are intentionally excluded.'
)
[IO.File]::WriteAllLines((Join-Path $outputEvidence 'parse-diagnostics.txt'), $diagnostics, $utf8)