mirror of
https://github.com/Microsoft/sql-server-samples.git
synced 2025-12-08 14:58:54 +00:00
278 lines
11 KiB
PowerShell
278 lines
11 KiB
PowerShell
using namespace Microsoft.Azure.Commands.Sql.DataSync.Model
|
|
using namespace System.Collections.Generic
|
|
param (
|
|
[Parameter(Mandatory=$true)][string]$SubscriptionId = "",
|
|
[Parameter(Mandatory=$true)][string]$ResourceGroupName = "",
|
|
[Parameter(Mandatory=$true)][string]$ServerName = "",
|
|
[Parameter(Mandatory=$true)][string]$DatabaseName = "",
|
|
[Parameter(Mandatory=$true)][string]$SyncGroupName = "",
|
|
[string]$MemberName = "",
|
|
[int]$TimeoutInSeconds = 900,
|
|
[switch]$RefreshDatabaseSchema = $false,
|
|
[switch]$AddAllTables = $false,
|
|
[string]$TablesAndColumnsToAdd = "",
|
|
[string]$TablesAndColumnsToRemove = "")
|
|
|
|
$TablesAndColumnsToAddList = [System.Collections.ArrayList]::new($TablesAndColumnsToAdd.Split(","))
|
|
$TablesAndColumnsToRemoveList = [System.Collections.ArrayList]::new($TablesAndColumnsToRemove.Split(","))
|
|
$TempFile = $env:TEMP+"\syncSchema.json"
|
|
|
|
##login to Azure account
|
|
add-azurermaccount
|
|
|
|
##select the subscription
|
|
select-azurermsubscription -SubscriptionId $SubscriptionId
|
|
|
|
##get sync group and check if sync group exists
|
|
$SyncGroup = Get-AzureRmSqlSyncGroup -ResourceGroupName $ResourceGroupName `
|
|
-ServerName $ServerName `
|
|
-DatabaseName $DatabaseName `
|
|
-Name $SyncGroupName
|
|
|
|
if ($SyncGroup -eq $null)
|
|
{
|
|
Write-Host "Sync group $SyncGroupName is not found."
|
|
exit;
|
|
}
|
|
|
|
##if member name specified, check if member exists
|
|
if ($MemberName -ne "")
|
|
{
|
|
$SyncMember = Get-AzureRmSqlSyncMember -ResourceGroupName $ResourceGroupName `
|
|
-ServerName $ServerName `
|
|
-DatabaseName $DatabaseName `
|
|
-SyncGroupName $SyncGroupName `
|
|
-Name $MemberName
|
|
if ($SyncMember -eq $null)
|
|
{
|
|
Write-Error "Sync member $MemberName is not found."
|
|
exit;
|
|
}
|
|
}
|
|
|
|
|
|
## Refresh database schema if -RefreshDatabaseSchema is specified
|
|
$DatabaseSchema = ""
|
|
if ($RefreshDatabaseSchema)
|
|
{
|
|
$StartTime = Get-Date
|
|
if ($MemberName -eq "")
|
|
{
|
|
Write-Host "Refreshing database schema from hub database"
|
|
Update-AzureRmSqlSyncSchema -ResourceGroupName $ResourceGroupName `
|
|
-ServerName $ServerName `
|
|
-DatabaseName $DatabaseName `
|
|
-SyncGroupName $SyncGroupName
|
|
}
|
|
else
|
|
{
|
|
Write-Host "Refreshing database schema from member $MemberName"
|
|
Update-AzureRmSqlSyncSchema -ResourceGroupName $ResourceGroupName `
|
|
-ServerName $ServerName `
|
|
-DatabaseName $DatabaseName `
|
|
-SyncGroupName $SyncGroupName `
|
|
-SyncMemberName $MemberName
|
|
}
|
|
|
|
## Wait until the database schema is refreshed
|
|
$TimeoutTimeSpan = New-TimeSpan -Start $StartTime -End $StartTime
|
|
$IsSucceeded = $false
|
|
While ($TimeoutTimeSpan.TotalSeconds -le $TimeoutInSeconds)
|
|
{
|
|
Start-Sleep -s 10
|
|
|
|
if ($MemberName -eq "")
|
|
{
|
|
$DatabaseSchema = Get-AzureRmSqlSyncSchema -SyncGroupName $SyncGroupName `
|
|
-ServerName $ServerName `
|
|
-DatabaseName $DatabaseName `
|
|
-ResourceGroupName $ResourceGroupName
|
|
}
|
|
else
|
|
{
|
|
$DatabaseSchema = Get-AzureRmSqlSyncSchema -SyncGroupName $SyncGroupName `
|
|
-ServerName $ServerName `
|
|
-DatabaseName $DatabaseName `
|
|
-ResourceGroupName $ResourceGroupName `
|
|
-SyncMemberName $MemberName
|
|
}
|
|
|
|
if ($DatabaseSchema.LastUpdateTime -gt $StartTime.ToUniversalTime())
|
|
{
|
|
Write-Host "Database schema succeeded"
|
|
$IsSucceeded = $true
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (-not $IsSucceeded)
|
|
{
|
|
Write-Error "Refresh failed or timeout"
|
|
exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ($MemberName -eq "")
|
|
{
|
|
$DatabaseSchema = Get-AzureRmSqlSyncSchema -SyncGroupName $SyncGroupName `
|
|
-ServerName $ServerName `
|
|
-DatabaseName $DatabaseName `
|
|
-ResourceGroupName $ResourceGroupName
|
|
}
|
|
else
|
|
{
|
|
$DatabaseSchema = Get-AzureRmSqlSyncSchema -SyncGroupName $SyncGroupName `
|
|
-ServerName $ServerName `
|
|
-DatabaseName $DatabaseName `
|
|
-ResourceGroupName $ResourceGroupName `
|
|
-SyncMemberName $MemberName
|
|
}
|
|
}
|
|
|
|
if ($DatabaseSchema.LastUpdateTime -eq $null)
|
|
{
|
|
Write-Error "Database schema is not available. Refresh the database schema by specify -RefreshDatabaseSchema"
|
|
Exit;
|
|
}
|
|
|
|
## Remove specified tables and columns from sync schema
|
|
## Also remove tables and columns which is not defined in the database if database schema is refreshed
|
|
$TablesToRemove = New-Object "System.Collections.Generic.List[AzureSqlSyncGroupSchemaTableModel]";
|
|
foreach ($TableSchema in $SyncGroup.Schema.Tables)
|
|
{
|
|
$TableInDatabase = $DatabaseSchema.Tables | ? QuotedName -eq $TableSchema.QuotedName
|
|
|
|
if ($TablesAndColumnsToRemoveList.Contains($TableSchema.QuotedName) -or $TableInDatabase -eq $null)
|
|
{
|
|
$TablesToRemove.Add($TableSchema);
|
|
}
|
|
else
|
|
{
|
|
$ColumnsToRemove = New-Object "System.Collections.Generic.List[AzureSqlSyncGroupSchemaColumnModel]";
|
|
foreach($ColumnSchema in $TableSchema.Columns)
|
|
{
|
|
$ColumnInTable = $TableInDatabase[0].Columns | ? QuotedName -eq $ColumnSchema.QuotedName
|
|
$FullName = $TableSchema.QuotedName+"."+$ColumnSchema.QuotedName
|
|
if ($TablesAndColumnsToRemoveList.Contains($FullName) -or $ColumnInTable -eq $null)
|
|
{
|
|
$ColumnsToRemove.Add($ColumnSchema);
|
|
}
|
|
}
|
|
|
|
if ($ColumnsToRemove.Count -gt 0)
|
|
{
|
|
foreach ($ColumnToRemove in $ColumnsToRemove)
|
|
{
|
|
$FullName = $TableSchema.QuotedName+"."+$ColumnToRemove.QuotedName
|
|
Write-Host "$FullName is being removed from sync schema"
|
|
$TableSchema.Columns.Remove($ColumnToRemove);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($TablesToRemove.Count -gt 0)
|
|
{
|
|
foreach ($TableToRemove in $TablesToRemove)
|
|
{
|
|
Write-Host $TableToRemove.QuotedName" is being removed from sync schema"
|
|
$SyncGroup.Schema.Tables.Remove($TableToRemove);
|
|
}
|
|
}
|
|
|
|
## Add specified tables and columns to the sync schema
|
|
foreach ($TableSchema in $DatabaseSchema.Tables)
|
|
{
|
|
## Reuse if the table already exists in the schema; Otherwise, create a new one
|
|
$newTableSchema = $SyncGroup.Schema.Tables | ? QuotedName -eq $TableSchema.QuotedName
|
|
$AddNewTable = $false
|
|
if ($newTableSchema -eq $null)
|
|
{
|
|
$AddNewTable = $true
|
|
$newTableSchema = [AzureSqlSyncGroupSchemaTableModel]::new()
|
|
$newTableSchema.QuotedName = $TableSchema.QuotedName
|
|
$newTableSchema.Columns = [List[AzureSqlSyncGroupSchemaColumnModel]]::new();
|
|
}
|
|
|
|
## If the table name is specified, add all valid columns
|
|
$addAllColumns = $false
|
|
if ($AddAllTables -or $TablesAndColumnsToAddList.Contains($TableSchema.QuotedName))
|
|
{
|
|
## If the table is not supported, move to next table
|
|
if ($TableSchema.HasError)
|
|
{
|
|
$fullTableName = $TableSchema.QuotedName
|
|
Write-Host "Can't add table $fullTableName to the sync schema" -foregroundcolor "Red"
|
|
Write-Host $TableSchema.ErrorId -foregroundcolor "Red"
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
$addAllColumns = $true
|
|
}
|
|
}
|
|
|
|
## Add columns
|
|
foreach($columnSchema in $TableSchema.Columns)
|
|
{
|
|
$fullColumnName = $TableSchema.QuotedName + "." + $columnSchema.QuotedName
|
|
if ($addAllColumns -or $TablesAndColumnsToAddList.Contains($fullColumnName))
|
|
{
|
|
## If the column already exists in the sync schema or not supported, ignore
|
|
$Column = $newTableSchema.Columns | ? QuotedName -eq $columnSchema.QuotedName
|
|
if ($Column -ne $null)
|
|
{
|
|
Write-Host "Column $fullColumnName is already in the schema"
|
|
}
|
|
elseif ((-not $addAllColumns) -and $TableSchema.HasError)
|
|
{
|
|
Write-Host "Can't add column $fullColumnName to the sync schema" -foregroundcolor "Red"
|
|
Write-Host $tableSchema.ErrorId -foregroundcolor "Red"
|
|
}
|
|
elseif ((-not $addAllColumns) -and $columnSchema.HasError)
|
|
{
|
|
Write-Host "Can't add column $fullColumnName to the sync schema" -foregroundcolor "Red"
|
|
Write-Host $columnSchema.ErrorId -foregroundcolor "Red"
|
|
}
|
|
else
|
|
{
|
|
Write-Host "Adding $fullColumnName to the sync schema"
|
|
$newColumnSchema = [AzureSqlSyncGroupSchemaColumnModel]::new()
|
|
$newColumnSchema.QuotedName = $columnSchema.QuotedName
|
|
$newColumnSchema.DataSize = $columnSchema.DataSize
|
|
$newColumnSchema.DataType = $columnSchema.DataType
|
|
$newTableSchema.Columns.Add($newColumnSchema)
|
|
}
|
|
}
|
|
}
|
|
if ($newTableSchema.Columns.Count -gt 0 -and $AddNewTable)
|
|
{
|
|
$SyncGroup.Schema.Tables.Add($newTableSchema)
|
|
}
|
|
}
|
|
|
|
## Update the master sync member name if database metadata is from the member
|
|
if ($MemberName -ne "")
|
|
{
|
|
$SyncGroup.Schema.MasterSyncMemberName = $MemberName
|
|
}
|
|
else
|
|
{
|
|
$SyncGroup.Schema.MasterSyncMemberName = $null
|
|
}
|
|
|
|
$schemaString = $SyncGroup.Schema | ConvertTo-Json -depth 5 -Compress
|
|
|
|
# workaround a powershell bug if the PowerShell version is too early
|
|
$schemaString = $schemaString.Replace('"Tables"', '"tables"').Replace('"Columns"', '"columns"').Replace('"QuotedName"', '"quotedName"').Replace('"MasterSyncMemberName"','"masterSyncMemberName"')
|
|
|
|
Write-Host "Write the schema to $TempFile"
|
|
$schemaString | Out-File $TempFile
|
|
|
|
# Update the sync schema
|
|
Update-AzureRmSqlSyncGroup -ResourceGroupName $ResourceGroupName `
|
|
-ServerName $ServerName `
|
|
-DatabaseName $DatabaseName `
|
|
-Name $SyncGroupName `
|
|
-SchemaFile $TempFile |