1+ using namespace Microsoft.Azure.Commands.Sql.DataSync.Model
2+ using namespace System.Collections.Generic
3+ param (
4+ [Parameter (Mandatory = $true )][string ]$SubscriptionId = " " ,
5+ [Parameter (Mandatory = $true )][string ]$ResourceGroupName = " " ,
6+ [Parameter (Mandatory = $true )][string ]$ServerName = " " ,
7+ [Parameter (Mandatory = $true )][string ]$DatabaseName = " " ,
8+ [Parameter (Mandatory = $true )][string ]$SyncGroupName = " " ,
9+ [string ]$MemberName = " " ,
10+ [int ]$TimeoutInSeconds = 900 ,
11+ [switch ]$RefreshDatabaseSchema = $false ,
12+ [switch ]$AddAllTables = $false ,
13+ [string ]$TablesAndColumnsToAdd = " " ,
14+ [string ]$TablesAndColumnsToRemove = " " )
15+
16+ $TablesAndColumnsToAddList = [System.Collections.ArrayList ]::new($TablesAndColumnsToAdd.Split (" ," ))
17+ $TablesAndColumnsToRemoveList = [System.Collections.ArrayList ]::new($TablesAndColumnsToRemove.Split (" ," ))
18+ $TempFile = $env: TEMP + " \syncSchema.json"
19+
20+ # #login to Azure account
21+ add-azurermaccount
22+
23+ # #select the subscription
24+ select-azurermsubscription - SubscriptionId $SubscriptionId
25+
26+ # #get sync group and check if sync group exists
27+ $SyncGroup = Get-AzureRmSqlSyncGroup - ResourceGroupName $ResourceGroupName `
28+ - ServerName $ServerName `
29+ - DatabaseName $DatabaseName `
30+ - Name $SyncGroupName
31+
32+ if ($SyncGroup -eq $null )
33+ {
34+ Write-Host " Sync group $SyncGroupName is not found."
35+ exit ;
36+ }
37+
38+ # #if member name specified, check if member exists
39+ if ($MemberName -ne " " )
40+ {
41+ $SyncMember = Get-AzureRmSqlSyncMember - ResourceGroupName $ResourceGroupName `
42+ - ServerName $ServerName `
43+ - DatabaseName $DatabaseName `
44+ - SyncGroupName $SyncGroupName `
45+ - Name $MemberName
46+ if ($SyncMember -eq $null )
47+ {
48+ Write-Error " Sync member $MemberName is not found."
49+ exit ;
50+ }
51+ }
52+
53+
54+ # # Refresh database schema if -RefreshDatabaseSchema is specified
55+ $DatabaseSchema = " "
56+ if ($RefreshDatabaseSchema )
57+ {
58+ $StartTime = Get-Date
59+ if ($MemberName -eq " " )
60+ {
61+ Write-Host " Refreshing database schema from hub database"
62+ Update-AzureRmSqlSyncSchema - ResourceGroupName $ResourceGroupName `
63+ - ServerName $ServerName `
64+ - DatabaseName $DatabaseName `
65+ - SyncGroupName $SyncGroupName
66+ }
67+ else
68+ {
69+ Write-Host " Refreshing database schema from member $MemberName "
70+ Update-AzureRmSqlSyncSchema - ResourceGroupName $ResourceGroupName `
71+ - ServerName $ServerName `
72+ - DatabaseName $DatabaseName `
73+ - SyncGroupName $SyncGroupName `
74+ - SyncMemberName $MemberName
75+ }
76+
77+ # # Wait until the database schema is refreshed
78+ $TimeoutTimeSpan = New-TimeSpan - Start $StartTime - End $StartTime
79+ $IsSucceeded = $false
80+ While ($TimeoutTimeSpan.TotalSeconds -le $TimeoutInSeconds )
81+ {
82+ Start-Sleep - s 10
83+
84+ if ($MemberName -eq " " )
85+ {
86+ $DatabaseSchema = Get-AzureRmSqlSyncSchema - SyncGroupName $SyncGroupName `
87+ - ServerName $ServerName `
88+ - DatabaseName $DatabaseName `
89+ - ResourceGroupName $ResourceGroupName
90+ }
91+ else
92+ {
93+ $DatabaseSchema = Get-AzureRmSqlSyncSchema - SyncGroupName $SyncGroupName `
94+ - ServerName $ServerName `
95+ - DatabaseName $DatabaseName `
96+ - ResourceGroupName $ResourceGroupName `
97+ - SyncMemberName $MemberName
98+ }
99+
100+ if ($DatabaseSchema.LastUpdateTime -gt $StartTime.ToUniversalTime ())
101+ {
102+ Write-Host " Database schema succeeded"
103+ $IsSucceeded = $true
104+ break ;
105+ }
106+ }
107+
108+ if (-not $IsSucceeded )
109+ {
110+ Write-Error " Refresh failed or timeout"
111+ exit ;
112+ }
113+ }
114+ else
115+ {
116+ if ($MemberName -eq " " )
117+ {
118+ $DatabaseSchema = Get-AzureRmSqlSyncSchema - SyncGroupName $SyncGroupName `
119+ - ServerName $ServerName `
120+ - DatabaseName $DatabaseName `
121+ - ResourceGroupName $ResourceGroupName
122+ }
123+ else
124+ {
125+ $DatabaseSchema = Get-AzureRmSqlSyncSchema - SyncGroupName $SyncGroupName `
126+ - ServerName $ServerName `
127+ - DatabaseName $DatabaseName `
128+ - ResourceGroupName $ResourceGroupName `
129+ - SyncMemberName $MemberName
130+ }
131+ }
132+
133+ if ($DatabaseSchema.LastUpdateTime -eq $null )
134+ {
135+ Write-Error " Database schema is not available. Refresh the database schema by specify -RefreshDatabaseSchema"
136+ Exit ;
137+ }
138+
139+ # # Remove specified tables and columns from sync schema
140+ # # Also remove tables and columns which is not defined in the database if database schema is refreshed
141+ $TablesToRemove = New-Object " System.Collections.Generic.List[AzureSqlSyncGroupSchemaTableModel]" ;
142+ foreach ($TableSchema in $SyncGroup.Schema.Tables )
143+ {
144+ $TableInDatabase = $DatabaseSchema.Tables | ? QuotedName -eq $TableSchema.QuotedName
145+
146+ if ($TablesAndColumnsToRemoveList.Contains ($TableSchema.QuotedName ) -or $TableInDatabase -eq $null )
147+ {
148+ $TablesToRemove.Add ($TableSchema );
149+ }
150+ else
151+ {
152+ $ColumnsToRemove = New-Object " System.Collections.Generic.List[AzureSqlSyncGroupSchemaColumnModel]" ;
153+ foreach ($ColumnSchema in $TableSchema.Columns )
154+ {
155+ $ColumnInTable = $TableInDatabase [0 ].Columns | ? QuotedName -eq $ColumnSchema.QuotedName
156+ $FullName = $TableSchema.QuotedName + " ." + $ColumnSchema.QuotedName
157+ if ($TablesAndColumnsToRemoveList.Contains ($FullName ) -or $ColumnInTable -eq $null )
158+ {
159+ $ColumnsToRemove.Add ($ColumnSchema );
160+ }
161+ }
162+
163+ if ($ColumnsToRemove.Count -gt 0 )
164+ {
165+ foreach ($ColumnToRemove in $ColumnsToRemove )
166+ {
167+ $FullName = $TableSchema.QuotedName + " ." + $ColumnToRemove.QuotedName
168+ Write-Host " $FullName is being removed from sync schema"
169+ $TableSchema.Columns.Remove ($ColumnToRemove );
170+ }
171+ }
172+ }
173+ }
174+
175+ if ($TablesToRemove.Count -gt 0 )
176+ {
177+ foreach ($TableToRemove in $TablesToRemove )
178+ {
179+ Write-Host $TableToRemove.QuotedName " is being removed from sync schema"
180+ $SyncGroup.Schema.Tables.Remove ($TableToRemove );
181+ }
182+ }
183+
184+ # # Add specified tables and columns to the sync schema
185+ foreach ($TableSchema in $DatabaseSchema.Tables )
186+ {
187+ # # Reuse if the table already exists in the schema; Otherwise, create a new one
188+ $newTableSchema = $SyncGroup.Schema.Tables | ? QuotedName -eq $TableSchema.QuotedName
189+ $AddNewTable = $false
190+ if ($newTableSchema -eq $null )
191+ {
192+ $AddNewTable = $true
193+ $newTableSchema = [AzureSqlSyncGroupSchemaTableModel ]::new()
194+ $newTableSchema.QuotedName = $TableSchema.QuotedName
195+ $newTableSchema.Columns = [List [AzureSqlSyncGroupSchemaColumnModel ]]::new();
196+ }
197+
198+ # # If the table name is specified, add all valid columns
199+ $addAllColumns = $false
200+ if ($AddAllTables -or $TablesAndColumnsToAddList.Contains ($TableSchema.QuotedName ))
201+ {
202+ # # If the table is not supported, move to next table
203+ if ($TableSchema.HasError )
204+ {
205+ $fullTableName = $TableSchema.QuotedName
206+ Write-Host " Can't add table $fullTableName to the sync schema" - foregroundcolor " Red"
207+ Write-Host $TableSchema.ErrorId - foregroundcolor " Red"
208+ continue ;
209+ }
210+ else
211+ {
212+ $addAllColumns = $true
213+ }
214+ }
215+
216+ # # Add columns
217+ foreach ($columnSchema in $TableSchema.Columns )
218+ {
219+ $fullColumnName = $TableSchema.QuotedName + " ." + $columnSchema.QuotedName
220+ if ($addAllColumns -or $TablesAndColumnsToAddList.Contains ($fullColumnName ))
221+ {
222+ # # If the column already exists in the sync schema or not supported, ignore
223+ $Column = $newTableSchema.Columns | ? QuotedName -eq $columnSchema.QuotedName
224+ if ($Column -ne $null )
225+ {
226+ Write-Host " Column $fullColumnName is already in the schema"
227+ }
228+ elseif ((-not $addAllColumns ) -and $TableSchema.HasError )
229+ {
230+ Write-Host " Can't add column $fullColumnName to the sync schema" - foregroundcolor " Red"
231+ Write-Host $tableSchema.ErrorId - foregroundcolor " Red"
232+ }
233+ elseif ((-not $addAllColumns ) -and $columnSchema.HasError )
234+ {
235+ Write-Host " Can't add column $fullColumnName to the sync schema" - foregroundcolor " Red"
236+ Write-Host $columnSchema.ErrorId - foregroundcolor " Red"
237+ }
238+ else
239+ {
240+ Write-Host " Adding $fullColumnName to the sync schema"
241+ $newColumnSchema = [AzureSqlSyncGroupSchemaColumnModel ]::new()
242+ $newColumnSchema.QuotedName = $columnSchema.QuotedName
243+ $newColumnSchema.DataSize = $columnSchema.DataSize
244+ $newColumnSchema.DataType = $columnSchema.DataType
245+ $newTableSchema.Columns.Add ($newColumnSchema )
246+ }
247+ }
248+ }
249+ if ($newTableSchema.Columns.Count -gt 0 -and $AddNewTable )
250+ {
251+ $SyncGroup.Schema.Tables.Add ($newTableSchema )
252+ }
253+ }
254+
255+ # # Update the master sync member name if database metadata is from the member
256+ if ($MemberName -ne " " )
257+ {
258+ $SyncGroup.Schema.MasterSyncMemberName = $MemberName
259+ }
260+ else
261+ {
262+ $SyncGroup.Schema.MasterSyncMemberName = $null
263+ }
264+
265+ $schemaString = $SyncGroup.Schema | ConvertTo-Json - depth 5 - Compress
266+
267+ # workaround a powershell bug if the PowerShell version is too early
268+ $schemaString = $schemaString.Replace (' "Tables"' , ' "tables"' ).Replace(' "Columns"' , ' "columns"' ).Replace(' "QuotedName"' , ' "quotedName"' ).Replace(' "MasterSyncMemberName"' , ' "masterSyncMemberName"' )
269+
270+ Write-Host " Write the schema to $TempFile "
271+ $schemaString | Out-File $TempFile
272+
273+ # Update the sync schema
274+ Update-AzureRmSqlSyncGroup - ResourceGroupName $ResourceGroupName `
275+ - ServerName $ServerName `
276+ - DatabaseName $DatabaseName `
277+ - Name $SyncGroupName `
278+ - SchemaFile $TempFile
0 commit comments