# encoding: ascii
# api: powershell
# title: Compare-DatabaseColumns
# description: This script compares the column structure between two databases with tables of the same name. Table names to compare can be passed in as an array or piped in either as string values, or as a property of Name or TableName.
# version: 0.1
# type: function
# author: Steven Murawski
# license: CC0
# function: Run-Query
# x-poshcode-id: 974
# x-archived: 2014-10-10T07:40:54
# x-published: 2009-03-26T06:56:00
#
#
param( [String[]]$Table = $null,
$SqlServerOne = 'YourDatabaseServer',
$FirstDatabase = 'FirstDatabaseToCompare',
$SqlUsernameOne = 'SQL Login',
$SqlPasswordOne = 'SQL Password',
$SqlServerTwo = 'YourDatabaseServer',
$SecondDatabase = 'SecondDatabaseToCompare',
$SqlUsernameTwo = 'SQL Login',
$SqlPasswordTwo = 'SQL Password',
$FilePrefix = 'Log',
[switch]$Log,
[switch]$Column)
if ($Input)
{
foreach ($item in $Input)
{
if ($item -is [string])
{
$Table += $item
}
else
{
foreach ($property in $item.psobject.properties)
{
if ('name', 'TableName' -contains $property.name)
{
$Table += $Property.value
break
}
}
}
}
}
if ($Table.count -eq 0)
{
throw 'A table to compare is required.'
}
$File = $FilePrefix + '{0}-{1}.csv'
$OFS = "', '"
$ColumnQuery = @"
SELECT sysobjects.name AS TableName, syscolumns.name AS ColumnName, systypes.name AS type,
syscolumns.length
FROM systypes
INNER JOIN syscolumns ON systypes.xusertype = syscolumns.xusertype --get data type info
INNER JOIN sysobjects ON syscolumns.id = sysobjects.id
WHERE
sysobjects.name IN ('$Table')
"@
function Run-Query()
{
param (
$SqlQuery,
$SqlServer,
$SqlCatalog,
$SqlUser,
$SqlPass
)
$SqlConnString = "Server = $SqlServer; Database = $SqlCatalog; user = $SqlUser; password = $SqlPass"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = $SqlConnString
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$a = $SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
$DataSet.Tables | Select-Object -ExpandProperty Rows
}
[String[]]$Properties = 'TableName', 'ColumnName', 'Type', 'Length'
Write-Debug "Checking Tables: '$Table'"
$ColumnsDBOne = Run-Query -SqlQuery $ColumnQuery -SqlServer $SqlServerOne -SqlCatalog $FirstDatabase -SqlUser $SqlUsernameOne -SqlPass $SqlPasswordOne | Select-Object -Property $Properties
$ColumnsDBTwo = Run-Query -SqlQuery $ColumnQuery -SqlServer $SqlServerTwo -SqlCatalog $SecondDatabase -SqlUser $SqlUsernameTwo -SqlPass $SqlPasswordTwo | Select-Object -Property $Properties
Write-Host 'Differences in Columns: '
$Database = @{Name='Database';Expression={if ($_.SideIndicator -eq '<='){'{0} / {1}' -f $FirstDatabase, $SqlServerOne} else {'{0} / {1}' -f $SecondDatabase, $SqlServerTwo}}}
$ColumnDifference = Compare-Object $ColumnsDBOne $ColumnsDBTwo -SyncWindow (($TablesDBOne.count + $TablesDBTwo.count)/2) -Property $Properties | select 'TableName', 'ColumnName', 'Type', 'Length', $Database
if ($log)
{
$ColumnDifference | Export-Csv -Path ($file -f $FirstDatabase, $SecondDatabase) -NoTypeInformation
}
$OFS = ', '
$ColumnDifference | Sort-Object -Property 'TableName', 'ColumnName', 'Type', 'Length', 'Database'