Add Sage Spain export artifacts

This commit is contained in:
2026-05-07 14:09:32 +02:00
parent 6717843f18
commit 8477894758
42 changed files with 167193 additions and 0 deletions
@@ -0,0 +1,334 @@
param(
[string[]]$SqlInstance = @(),
[string]$OutputDirectory = (Join-Path $env:USERPROFILE "Desktop"),
[switch]$ScanProgramFiles
)
$ErrorActionPreference = "Continue"
function Add-Section {
param([string]$Title)
$script:reportLines += ""
$script:reportLines += "============================================================"
$script:reportLines += $Title
$script:reportLines += "============================================================"
}
function Add-Line {
param([string]$Text = "")
$script:reportLines += $Text
}
function Read-RegistryValues {
param([string]$Path)
try {
if (Test-Path $Path) {
return Get-ItemProperty -Path $Path -ErrorAction Stop
}
}
catch {
Add-Line "Registry read failed: $Path :: $($_.Exception.Message)"
}
return $null
}
function Get-SageUninstallEntries {
$paths = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
)
foreach ($path in $paths) {
Get-ItemProperty -Path $path -ErrorAction SilentlyContinue |
Where-Object {
$_.DisplayName -and (
$_.DisplayName -match "Sage" -or
$_.Publisher -match "Sage"
)
} |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate, InstallLocation, UninstallString, PSPath
}
}
function Get-SageFileVersions {
$roots = @(
$env:ProgramFiles,
${env:ProgramFiles(x86)},
$env:ProgramData
) | Where-Object { $_ -and (Test-Path $_) }
foreach ($root in $roots) {
Get-ChildItem -LiteralPath $root -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match "Sage" } |
ForEach-Object {
Get-ChildItem -LiteralPath $_.FullName -Recurse -File -Include *.exe,*.dll -ErrorAction SilentlyContinue |
Where-Object { $_.VersionInfo.ProductName -match "Sage" -or $_.VersionInfo.CompanyName -match "Sage" -or $_.Name -match "Sage" } |
Select-Object FullName,
@{Name="FileVersion"; Expression={$_.VersionInfo.FileVersion}},
@{Name="ProductVersion"; Expression={$_.VersionInfo.ProductVersion}},
@{Name="ProductName"; Expression={$_.VersionInfo.ProductName}},
@{Name="CompanyName"; Expression={$_.VersionInfo.CompanyName}}
}
}
}
function Get-SqlInstancesFromRegistry {
$instanceRoots = @(
"HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Microsoft SQL Server\Instance Names\SQL"
)
$instances = New-Object System.Collections.Generic.List[object]
foreach ($root in $instanceRoots) {
$values = Read-RegistryValues $root
if (-not $values) {
continue
}
$values.PSObject.Properties |
Where-Object { $_.Name -notlike "PS*" } |
ForEach-Object {
$instanceName = $_.Name
$instanceId = [string]$_.Value
$setupPaths = @(
"HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$instanceId\Setup",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Microsoft SQL Server\$instanceId\Setup"
)
foreach ($setupPath in $setupPaths) {
$setup = Read-RegistryValues $setupPath
if ($setup) {
$instances.Add([pscustomobject]@{
InstanceName = $instanceName
InstanceId = $instanceId
Edition = $setup.Edition
Version = $setup.Version
PatchLevel = $setup.PatchLevel
ProductCode = $setup.ProductCode
SQLPath = $setup.SQLPath
SetupPath = $setupPath
})
}
}
}
}
return $instances
}
function Get-SqlServices {
Get-CimInstance Win32_Service -ErrorAction SilentlyContinue |
Where-Object { $_.Name -like "MSSQL*" -or $_.Name -like "SQLAgent*" -or $_.DisplayName -like "*SQL Server*" } |
Select-Object Name, DisplayName, State, StartMode, PathName
}
function Resolve-Sqlcmd {
$cmd = Get-Command sqlcmd.exe -ErrorAction SilentlyContinue
if ($cmd) {
return $cmd.Source
}
$candidates = @(
"$env:ProgramFiles\Microsoft SQL Server\Client SDK\ODBC\*\Tools\Binn\sqlcmd.exe",
"${env:ProgramFiles(x86)}\Microsoft SQL Server\Client SDK\ODBC\*\Tools\Binn\sqlcmd.exe",
"$env:ProgramFiles\Microsoft SQL Server\*\Tools\Binn\sqlcmd.exe",
"${env:ProgramFiles(x86)}\Microsoft SQL Server\*\Tools\Binn\sqlcmd.exe"
)
foreach ($candidate in $candidates) {
$match = Get-ChildItem -Path $candidate -ErrorAction SilentlyContinue | Select-Object -First 1
if ($match) {
return $match.FullName
}
}
return $null
}
function Invoke-SqlVersionQuery {
param(
[string]$SqlcmdPath,
[string]$Instance
)
$query = @"
SET NOCOUNT ON;
SELECT
@@VERSION AS FullVersion,
SERVERPROPERTY('ProductVersion') AS ProductVersion,
SERVERPROPERTY('ProductLevel') AS ProductLevel,
SERVERPROPERTY('Edition') AS Edition,
SERVERPROPERTY('EngineEdition') AS EngineEdition,
SERVERPROPERTY('MachineName') AS MachineName,
SERVERPROPERTY('ServerName') AS ServerName,
SERVERPROPERTY('InstanceName') AS InstanceName,
SERVERPROPERTY('Collation') AS Collation;
"@
$tempQuery = Join-Path $env:TEMP ("sql_version_query_{0}.sql" -f ([guid]::NewGuid().ToString("N")))
Set-Content -LiteralPath $tempQuery -Value $query -Encoding UTF8
try {
$output = & $SqlcmdPath -S $Instance -E -i $tempQuery -W -s "|" -b 2>&1
[pscustomobject]@{
Instance = $Instance
Success = $LASTEXITCODE -eq 0
Output = ($output -join [Environment]::NewLine)
}
}
catch {
[pscustomobject]@{
Instance = $Instance
Success = $false
Output = $_.Exception.Message
}
}
finally {
Remove-Item -LiteralPath $tempQuery -Force -ErrorAction SilentlyContinue
}
}
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null
$reportPath = Join-Path $OutputDirectory "Sage_SQL_Environment_$timestamp.txt"
$jsonPath = Join-Path $OutputDirectory "Sage_SQL_Environment_$timestamp.json"
$reportLines = New-Object System.Collections.Generic.List[string]
$computer = Get-CimInstance Win32_ComputerSystem -ErrorAction SilentlyContinue
$os = Get-CimInstance Win32_OperatingSystem -ErrorAction SilentlyContinue
$sageEntries = @(Get-SageUninstallEntries)
$sqlRegistryInstances = @(Get-SqlInstancesFromRegistry)
$sqlServices = @(Get-SqlServices)
$sageFileVersions = @()
if ($ScanProgramFiles) {
$sageFileVersions = @(Get-SageFileVersions)
}
$sqlcmdPath = Resolve-Sqlcmd
$queryInstances = New-Object System.Collections.Generic.List[string]
foreach ($instance in $SqlInstance) {
if (-not [string]::IsNullOrWhiteSpace($instance)) {
$queryInstances.Add($instance)
}
}
if ($queryInstances.Count -eq 0) {
$machineName = $env:COMPUTERNAME
foreach ($instance in $sqlRegistryInstances) {
if ($instance.InstanceName -eq "MSSQLSERVER") {
$queryInstances.Add("localhost")
}
else {
$queryInstances.Add("localhost\$($instance.InstanceName)")
}
}
}
$queryInstances = @($queryInstances | Select-Object -Unique)
$sqlQueryResults = @()
if ($sqlcmdPath -and $queryInstances.Count -gt 0) {
foreach ($instance in $queryInstances) {
$sqlQueryResults += Invoke-SqlVersionQuery -SqlcmdPath $sqlcmdPath -Instance $instance
}
}
Add-Section "Capture metadata"
Add-Line "Timestamp: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")"
Add-Line "Computer: $env:COMPUTERNAME"
Add-Line "User: $env:USERDOMAIN\$env:USERNAME"
Add-Line "Output text: $reportPath"
Add-Line "Output json: $jsonPath"
Add-Section "Windows / machine"
Add-Line "Manufacturer: $($computer.Manufacturer)"
Add-Line "Model: $($computer.Model)"
Add-Line "OS: $($os.Caption)"
Add-Line "OS Version: $($os.Version)"
Add-Line "OS Build: $($os.BuildNumber)"
Add-Line "Install date: $($os.InstallDate)"
Add-Section "Sage entries from installed programs"
if ($sageEntries.Count -eq 0) {
Add-Line "No Sage uninstall entries found."
}
else {
$sageEntries | Format-List | Out-String | ForEach-Object { Add-Line $_.TrimEnd() }
}
Add-Section "Sage file versions"
if (-not $ScanProgramFiles) {
Add-Line "Skipped. Re-run with -ScanProgramFiles for file version scan."
}
elseif ($sageFileVersions.Count -eq 0) {
Add-Line "No Sage file versions found under Program Files / ProgramData."
}
else {
$sageFileVersions | Sort-Object ProductName, ProductVersion, FullName | Format-Table -AutoSize | Out-String | ForEach-Object { Add-Line $_.TrimEnd() }
}
Add-Section "SQL Server instances from registry"
if ($sqlRegistryInstances.Count -eq 0) {
Add-Line "No SQL Server registry instances found."
}
else {
$sqlRegistryInstances | Format-List | Out-String | ForEach-Object { Add-Line $_.TrimEnd() }
}
Add-Section "SQL Server services"
if ($sqlServices.Count -eq 0) {
Add-Line "No SQL Server services found."
}
else {
$sqlServices | Format-Table -AutoSize | Out-String | ForEach-Object { Add-Line $_.TrimEnd() }
}
Add-Section "SQL Server live query"
Add-Line "sqlcmd path: $(if ($sqlcmdPath) { $sqlcmdPath } else { "not found" })"
if (-not $sqlcmdPath) {
Add-Line "Cannot query SQL Server live because sqlcmd.exe was not found."
}
elseif ($queryInstances.Count -eq 0) {
Add-Line "No SQL instances to query. Pass -SqlInstance server\instance if needed."
}
else {
foreach ($result in $sqlQueryResults) {
Add-Line ""
Add-Line "Instance: $($result.Instance)"
Add-Line "Success: $($result.Success)"
Add-Line $result.Output
}
}
$data = [pscustomobject]@{
CapturedAt = (Get-Date).ToString("o")
ComputerName = $env:COMPUTERNAME
UserName = "$env:USERDOMAIN\$env:USERNAME"
Windows = [pscustomobject]@{
Caption = $os.Caption
Version = $os.Version
BuildNumber = $os.BuildNumber
InstallDate = $os.InstallDate
}
SageUninstallEntries = $sageEntries
SageFileVersions = $sageFileVersions
SqlRegistryInstances = $sqlRegistryInstances
SqlServices = $sqlServices
SqlcmdPath = $sqlcmdPath
SqlQueryResults = $sqlQueryResults
}
$reportLines | Set-Content -LiteralPath $reportPath -Encoding UTF8
$data | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $jsonPath -Encoding UTF8
Write-Host "Created:"
Write-Host " $reportPath"
Write-Host " $jsonPath"