- Fix and optimize export script for ODBC DSNs, registry keys, and driver inventory. - Fix bug in the restore ODBC DSNs and registry keys scripts, ensuring compatibility with different Windows architectures.
274 lines
10 KiB
PowerShell
274 lines
10 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Export ODBC DSNs, registry keys, and driver inventory.
|
|
Generate migration package + report with vendor download links.
|
|
|
|
.DESCRIPTION
|
|
This script:
|
|
- Exports ODBC System/User DSNs
|
|
- Exports registry keys for ODBC.INI
|
|
- Lists all installed ODBC drivers and Add/Remove Program entries
|
|
- Matches known ODBC drivers to official vendor download URLs
|
|
- Searches for local EXE/MSI installers
|
|
- Generates CSV + Markdown reports
|
|
- Compresses all output into a single ZIP archive
|
|
|
|
Run as Administrator on the source PC.
|
|
#>
|
|
|
|
# ===========================
|
|
# CONFIGURATION
|
|
# ===========================
|
|
$BaseDir = "C:\ODBC_Migration"
|
|
$ExportDir = Join-Path $BaseDir "export"
|
|
$ZipFile = Join-Path $BaseDir "ODBC_Backup.zip"
|
|
$LogFile = Join-Path $BaseDir "export_log.txt"
|
|
|
|
# Optional: Add local folders to search for installers
|
|
$InstallerHuntPaths = @(
|
|
"$env:USERPROFILE\Downloads",
|
|
"C:\Installers",
|
|
"C:\Drivers",
|
|
"$env:PUBLIC\Downloads"
|
|
) | Where-Object { Test-Path $_ }
|
|
|
|
# ===========================
|
|
# PREP
|
|
# ===========================
|
|
New-Item -ItemType Directory -Path $ExportDir -Force | Out-Null
|
|
Start-Transcript -Path $LogFile -Append
|
|
Write-Host "Starting ODBC migration export..." -ForegroundColor Cyan
|
|
|
|
# ===========================
|
|
# STEP 1: EXPORT BASELINE DATA
|
|
# ===========================
|
|
Write-Host "Exporting ODBC driver list..."
|
|
$drivers = Get-OdbcDriver | Select-Object Name, Platform, Version, Attribute
|
|
$driversCsv = Join-Path $ExportDir "odbc_drivers.csv"
|
|
$drivers | Export-Csv -Path $driversCsv -NoTypeInformation -Encoding UTF8
|
|
|
|
Write-Host "Exporting DSNs..."
|
|
$dsnsXml = Join-Path $ExportDir "odbc_dsns.xml"
|
|
Get-OdbcDsn | Export-Clixml $dsnsXml
|
|
|
|
Write-Host "Exporting registry keys..."
|
|
reg export "HKLM\SOFTWARE\ODBC\ODBC.INI" (Join-Path $ExportDir "ODBC_System.reg") /y | Out-Null
|
|
reg export "HKCU\Software\ODBC\ODBC.INI" (Join-Path $ExportDir "ODBC_User.reg") /y | Out-Null
|
|
$WowKey = "HKLM\SOFTWARE\WOW6432Node\ODBC\ODBC.INI"
|
|
if (Test-Path "Registry::$WowKey") {
|
|
reg export $WowKey (Join-Path $ExportDir "ODBC_System32.reg") /y | Out-Null
|
|
Write-Host "Exported 32-bit ODBC keys."
|
|
}
|
|
|
|
# ===========================
|
|
# STEP 2: ENUMERATE INSTALLED PRODUCTS
|
|
# ===========================
|
|
Write-Host "Enumerating Add/Remove Programs entries..."
|
|
function Get-UninstallEntries {
|
|
$roots = @(
|
|
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
|
|
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
|
|
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
|
|
)
|
|
foreach ($r in $roots) {
|
|
if (Test-Path $r) {
|
|
Get-ChildItem $r | ForEach-Object { Get-ItemProperty $_.PsPath }
|
|
}
|
|
}
|
|
}
|
|
$uninst = Get-UninstallEntries | Select-Object `
|
|
DisplayName, DisplayVersion, Publisher, InstallLocation, UninstallString, ModifyPath, QuietUninstallString
|
|
|
|
# Tokenizer helper
|
|
function Normalize([string]$s) {
|
|
if (-not $s) { return "" }
|
|
return (($s -replace '[^a-zA-Z0-9]+', ' ') -as [string]).Trim().ToLowerInvariant()
|
|
}
|
|
|
|
# Map ODBC drivers -> installed programs
|
|
Write-Host "Mapping ODBC drivers to installed programs..."
|
|
$map = foreach ($d in $drivers) {
|
|
$nameNorm = Normalize $d.Name
|
|
$candidates = $uninst | Where-Object {
|
|
$_.DisplayName -and (Normalize $_.DisplayName) -match ($nameNorm -replace '\s+','.*')
|
|
}
|
|
|
|
if (-not $candidates -and $d.Name -match 'oracle|mysql|postgres|sql\s*server|mariadb|sqlite|snowflake|teradata|ibm|db2|progress|sybase|firebird|hana|vertica|redshift') {
|
|
$kw = ($matches[0])
|
|
$candidates = $uninst | Where-Object { $_.DisplayName -match $kw }
|
|
}
|
|
|
|
[PSCustomObject]@{
|
|
OdbcDriverName = $d.Name
|
|
Platform = $d.Platform
|
|
DriverVersion = $d.Version
|
|
ProductName = ($candidates | Select-Object -First 1 -ExpandProperty DisplayName)
|
|
ProductVersion = ($candidates | Select-Object -First 1 -ExpandProperty DisplayVersion)
|
|
Publisher = ($candidates | Select-Object -First 1 -ExpandProperty Publisher)
|
|
InstallLocation = ($candidates | Select-Object -First 1 -ExpandProperty InstallLocation)
|
|
UninstallString = ($candidates | Select-Object -First 1 -ExpandProperty UninstallString)
|
|
}
|
|
}
|
|
|
|
# ===========================
|
|
# STEP 3: ADD KNOWN VENDOR LINKS
|
|
# ===========================
|
|
Write-Host "Attaching known vendor download links..."
|
|
|
|
$vendorLinks = @{
|
|
# --- Microsoft ---
|
|
'odbc driver 18 for sql server' = 'https://learn.microsoft.com/sql/connect/odbc/download-odbc-driver-for-sql-server'
|
|
'odbc driver 17 for sql server' = 'https://learn.microsoft.com/sql/connect/odbc/download-odbc-driver-for-sql-server'
|
|
'sql server native client' = 'https://learn.microsoft.com/sql/relational-databases/native-client/applications/installing-sql-server-native-client'
|
|
'microsoft access driver' = 'https://www.microsoft.com/download/details.aspx?id=54920'
|
|
'microsoft excel driver' = 'https://www.microsoft.com/download/details.aspx?id=54920'
|
|
'microsoft text driver' = 'https://www.microsoft.com/download/details.aspx?id=54920'
|
|
'microsoft dbase driver' = 'https://www.microsoft.com/download/details.aspx?id=54920'
|
|
'microsoft odbc for oracle' = 'https://learn.microsoft.com/sql/odbc/microsoft/odbc-driver-for-oracle'
|
|
|
|
# --- Oracle ---
|
|
'oracle odbc driver' = 'https://www.oracle.com/database/technologies/releasenote-odbc-ic.html'
|
|
'oracle in oraclient' = 'https://www.oracle.com/database/technologies/releasenote-odbc-ic.html'
|
|
|
|
# --- MySQL / MariaDB ---
|
|
'mysql odbc' = 'https://dev.mysql.com/downloads/connector/odbc/'
|
|
'mariadb odbc' = 'https://mariadb.com/products/connectors/odbc/'
|
|
|
|
# --- PostgreSQL ---
|
|
'postgresql odbc' = 'https://odbc.postgresql.org/'
|
|
'psqlodbc' = 'https://odbc.postgresql.org/'
|
|
|
|
# --- SQLite ---
|
|
'sqlite odbc' = 'https://www.ch-werner.de/sqliteodbc/'
|
|
|
|
# --- IBM / Informix ---
|
|
'ibm db2 odbc' = 'https://www.ibm.com/support/pages/db2-clients'
|
|
'informix odbc' = 'https://www.ibm.com/support/pages/informix-odbc-driver'
|
|
|
|
# --- Snowflake ---
|
|
'snowflake odbc' = 'https://developers.snowflake.com/odbc/'
|
|
|
|
# --- Teradata ---
|
|
'teradata odbc' = 'https://downloads.teradata.com/connectivity/odbc-driver'
|
|
|
|
# --- Progress / OpenEdge ---
|
|
'progress openedge odbc' = 'https://www.progress.com/odbc/openedge'
|
|
'openedge odbc' = 'https://www.progress.com/odbc/openedge'
|
|
|
|
# --- SAP HANA ---
|
|
'sap hana odbc' = 'https://tools.hana.ondemand.com/#hanatools'
|
|
|
|
# --- Amazon Redshift ---
|
|
'redshift odbc' = 'https://docs.aws.amazon.com/redshift/latest/mgmt/configure-odbc-connection.html'
|
|
|
|
# --- Vertica ---
|
|
'vertica odbc' = 'https://www.vertica.com/download/vertica/client-drivers/'
|
|
|
|
# --- Firebird ---
|
|
'firebird odbc' = 'https://firebirdsql.org/en/odbc-driver/'
|
|
|
|
# --- Generic fallback ---
|
|
'generic odbc driver' = 'https://www.microsoft.com/en-us/sql/connect/odbc/'
|
|
}
|
|
|
|
foreach ($item in $map) {
|
|
$norm = Normalize $item.OdbcDriverName
|
|
$found = $false
|
|
foreach ($key in $vendorLinks.Keys) {
|
|
if ($norm -like "*$key*") {
|
|
$item | Add-Member -NotePropertyName "DownloadURL" -NotePropertyValue $vendorLinks[$key]
|
|
$found = $true
|
|
break
|
|
}
|
|
}
|
|
if (-not $found) {
|
|
$item | Add-Member -NotePropertyName "DownloadURL" -NotePropertyValue "Search manually"
|
|
}
|
|
}
|
|
|
|
# ===========================
|
|
# STEP 4: FIND LOCAL INSTALLER FILES
|
|
# ===========================
|
|
Write-Host "Scanning for local installers..."
|
|
$searchTerms = ($map.OdbcDriverName | Sort-Object -Unique)
|
|
$installerHits = @()
|
|
foreach ($p in $InstallerHuntPaths) {
|
|
Get-ChildItem -Path $p -Recurse -ErrorAction SilentlyContinue -Include *.msi,*.exe |
|
|
ForEach-Object {
|
|
$fileNorm = Normalize $_.Name
|
|
foreach ($term in $searchTerms) {
|
|
$t = Normalize $term
|
|
if ($fileNorm -match ($t -replace '\s+','.*')) {
|
|
$installerHits += [PSCustomObject]@{
|
|
Term = $term
|
|
FileName = $_.Name
|
|
FullPath = $_.FullName
|
|
SizeMB = [math]::Round($_.Length/1MB,2)
|
|
LastWrite = $_.LastWriteTime
|
|
SearchRoot = $p
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# ===========================
|
|
# STEP 5: REPORT OUTPUT
|
|
# ===========================
|
|
$mapCsv = Join-Path $ExportDir "odbc_driver_product_map.csv"
|
|
$map | Export-Csv -Path $mapCsv -NoTypeInformation -Encoding UTF8
|
|
$hitsCsv = Join-Path $ExportDir "odbc_installer_hits.csv"
|
|
$installerHits | Export-Csv -Path $hitsCsv -NoTypeInformation -Encoding UTF8
|
|
|
|
$reportMd = Join-Path $ExportDir "ODBC_Migration_Report.md"
|
|
@"
|
|
# ODBC Migration Report
|
|
|
|
**Generated:** $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
|
|
**Machine:** $env:COMPUTERNAME
|
|
|
|
## Summary
|
|
- Drivers detected: $($drivers.Count)
|
|
- DSNs exported: $((Get-OdbcDsn).Count)
|
|
- Installer hits: $($installerHits.Count)
|
|
|
|
## Drivers & Product Mapping
|
|
| ODBC Driver | Platform | Version | Product | Publisher | Download Link |
|
|
|---|---:|---|---|---|---|
|
|
$(
|
|
($map | ForEach-Object {
|
|
$dn = if ($_.OdbcDriverName) { $_.OdbcDriverName.Replace('|','-') } else { '' }
|
|
$pf = $_.Platform
|
|
$dv = $_.DriverVersion
|
|
$pn = ($_.ProductName -replace '\|','-')
|
|
$pu = ($_.Publisher -replace '\|','-')
|
|
$dl = if ($_.DownloadURL -match '^https?') { "[Download]($($_.DownloadURL))" } else { $_.DownloadURL }
|
|
"| $dn | $pf | $dv | $pn | $pu | $dl |"
|
|
}) -join "`r`n"
|
|
)
|
|
|
|
## Likely Local Installer Files
|
|
| Matches Term | File | Size (MB) | Modified | Path |
|
|
|---|---|---:|---|---|
|
|
$(
|
|
($installerHits | Sort-Object Term,FileName | ForEach-Object {
|
|
"| $($_.Term) | $($_.FileName) | $($_.SizeMB) | $($_.LastWrite.ToString('yyyy-MM-dd')) | $($_.FullPath) |"
|
|
}) -join "`r`n"
|
|
)
|
|
|
|
## Next Steps
|
|
1. On the **target PC**, install matching ODBC driver packages using the links above or your local installers.
|
|
2. Then run **Restore-ODBC.ps1** to import DSNs and registry settings.
|
|
3. Verify DSNs in *ODBC Data Source Administrator* (both 32-bit and 64-bit).
|
|
"@ | Out-File -FilePath $reportMd -Encoding UTF8
|
|
|
|
# ===========================
|
|
# STEP 6: ZIP PACKAGE
|
|
# ===========================
|
|
if (Test-Path $ZipFile) { Remove-Item $ZipFile -Force }
|
|
Compress-Archive -Path "$ExportDir\*" -DestinationPath $ZipFile -Force
|
|
|
|
Write-Host "Export complete. ZIP created at: $ZipFile" -ForegroundColor Green
|
|
Stop-Transcript
|