66 lines
3.2 KiB
PowerShell
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)
|