1
0
Files
odbc-migration-kit/export-ODBC.ps1
Eugene Amos 912d24e0c6 ODBC scripts
- 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.
2025-10-10 09:59:13 -07:00

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