Verwenden von PowerShell zum Synchronisieren zwischen einer SQL-Datenbank und einer lokalen SQL Server-DatenbankUse PowerShell to sync between a SQL Database and a SQL Server on-premises database

Dieses PowerShell-Beispiel konfiguriert Data Sync für die Synchronisierung zwischen einer Azure SQL-Datenbank-Instanz und einem lokalen SQL-Server.This PowerShell example configures Data Sync to sync between an Azure SQL Database and a SQL Server on-premises database.

Wenn Sie kein Azure-Abonnement besitzen, erstellen Sie ein kostenloses Konto, bevor Sie beginnen.If you don't have an Azure subscription, create a free account before you begin.

Hinweis

Dieser Artikel wurde aktualisiert und beinhaltet jetzt das neue Az-Modul von Azure PowerShell.This article has been updated to use the new Azure PowerShell Az module. Sie können das AzureRM-Modul weiterhin verwenden, das bis mindestens Dezember 2020 weiterhin Fehlerbehebungen erhält.You can still use the AzureRM module, which will continue to receive bug fixes until at least December 2020. Weitere Informationen zum neuen Az-Modul und zur Kompatibilität mit AzureRM finden Sie unter Introducing the new Azure PowerShell Az module (Einführung in das neue Az-Modul von Azure PowerShell).To learn more about the new Az module and AzureRM compatibility, see Introducing the new Azure PowerShell Az module. Anweisungen zur Installation des Az-Moduls finden Sie unter Install Azure PowerShell (Installieren von Azure PowerShell).For Az module installation instructions, see Install Azure PowerShell.

Verwenden von Azure Cloud ShellUse Azure Cloud Shell

Azure hostet Azure Cloud Shell, eine interaktive Shell-Umgebung, die Sie über Ihren Browser nutzen können.Azure hosts Azure Cloud Shell, an interactive shell environment that you can use through your browser. Cloud Shell ermöglicht die Verwendung von bash oder PowerShell, um mit Azure-Diensten zu arbeiten.Cloud Shell lets you use either bash or PowerShell to work with Azure services. Sie können die vorinstallierten Befehle von Cloud Shell verwenden, um den Code in diesem Artikel auszuführen, ohne etwas in Ihrer lokalen Umgebung installieren zu müssen.You can use the Cloud Shell pre-installed commands to run the code in this article without having to install anything on your local environment.

Starten von Azure Cloud Shell:To launch Azure Cloud Shell:

OptionOption Beispiel/LinkExample/Link
Klicken Sie in der rechten oberen Ecke eines Codeblocks auf Ausprobieren.Select Try It in the upper-right corner of a code block. Durch die Auswahl von Ausprobieren wird der Code nicht automatisch in Cloud Shell kopiert.Selecting Try It doesn't automatically copy the code to Cloud Shell. Beispiel für „Testen Sie es.“ für Azure Cloud Shell
Rufen Sie https://shell.azure.com auf, oder wählen Sie die Schaltfläche Cloud Shell starten, um Cloud Shell im Browser zu öffnen.Go to https://shell.azure.com or select the Launch Cloud Shell button to open Cloud Shell in your browser. Starten von Cloud Shell in einem neuen FensterLaunch Cloud Shell in a new window
Wählen Sie im Azure-Portal oben rechts in der Menüleiste die Schaltfläche Cloud Shell.Select the Cloud Shell button on the top-right menu bar in the Azure portal. Cloud Shell-Schaltfläche im Azure-Portal

Ausführen des Codes in diesem Artikel in Azure Cloud Shell:To run the code in this article in Azure Cloud Shell:

  1. Starten Sie Cloud Shell.Launch Cloud Shell.

  2. Wählen Sie die Schaltfläche Kopieren für einen Codeblock, um den Code zu kopieren.Select the Copy button on a code block to copy the code.

  3. Fügen Sie den Code mit STRG+UMSCHALT+V unter Windows und Linux oder Cmd+UMSCHALT+V unter macOS in die Cloud Shell-Sitzung ein.Paste the code into the Cloud Shell session with Ctrl+Shift+V on Windows and Linux, or Cmd+Shift+V on macOS.

  4. Drücken Sie die EINGABETASTE, um den Code auszuführen.Press Enter to run the code.

Wenn Sie PowerShell lokal installieren und nutzen möchten, müssen Sie für dieses Tutorial mindestens Version 1.4.0 von Azure PowerShell verwenden.If you choose to install and use the PowerShell locally, this tutorial requires AZ PowerShell 1.4.0 or later. Wenn Sie ein Upgrade ausführen müssen, finden Sie unter Installieren des Azure PowerShell-Moduls Informationen dazu.If you need to upgrade, see Install Azure PowerShell module. Wenn Sie PowerShell lokal ausführen, müssen Sie auch Connect-AzAccount ausführen, um eine Verbindung mit Azure herzustellen.If you are running PowerShell locally, you also need to run Connect-AzAccount to create a connection with Azure.

Eine Übersicht über die SQL-Datensynchronisierung finden Sie unter Synchronisieren von Daten über mehrere Cloud- und lokale Datenbanken mit SQL-Datensynchronisierung.For an overview of SQL Data Sync, see Sync data across multiple cloud and on-premises databases with Azure SQL Data Sync.

Wichtig

Die Azure SQL-Datensynchronisierung unterstützt derzeit keine verwalteten Azure SQL-Datenbank-Instanzen.Azure SQL Data Sync does not support Azure SQL Database Managed Instance at this time.

BeispielskriptSample script

# prerequisites: 
# 1. Create an Azure SQL Database from AdventureWorksLT sample database as hub database
# 2. Create an Azure SQL Database in the same region as sync database
# 3. Create an on premises SQL Server Database as member database
# 4. Update the parameters below before running the sample
#
using namespace Microsoft.Azure.Commands.Sql.DataSync.Model
using namespace System.Collections.Generic

# Hub database info
# Subscription id for hub database
$SubscriptionId = "subscription_guid"
# Resource group name for hub database
$ResourceGroupName = "ResourceGroupName"
# Server name for hub database
$ServerName = "ServerName"
# Database name for hub database
$DatabaseName = "TestHubDatabase"

# Sync database info
# Resource group name for sync database
$SyncDatabaseResourceGroupName = "ResourceGroupName"
# Server name for sync database
$SyncDatabaseServerName = "ServerName"
# Sync database name
$SyncDatabaseName = "SyncDatabaseName"

# Sync group info
# Sync group name
$SyncGroupName = "TestSyncGroup"
# Conflict resolution Policy. Value can be HubWin or MemberWin
$ConflictResolutionPolicy = "HubWin"
# Sync interval in seconds. Value must be no less than 300
$IntervalInSeconds = 300

# Member database info
# Member name
$SyncMemberName = "member"
# Member server name
$MemberServerName = "OnPremiseServer"
# Member database name
$MemberDatabaseName = "MemberDatabaseTest"
# Member database type. Value can be AzureSqlDatabase or SqlServerDatabase
$MemberDatabaseType = "SqlServerDatabase"
# Sync direction. Value can be Bidirectional, Onewaymembertohub, Onewayhubtomember
$SyncDirection = "Bidirectional"

#Sync Agent Info
$SyncAgentName = "TestSyncAgent"
$SyncAgentResourceGroupName = "ResourceGroupName"
$SyncAgentServerName = "ServerName"

# Other info
# Temp file to save the sync schema
$TempFile = $env:TEMP+"\syncSchema.json"

# List of included columns and tables in quoted name
$IncludedColumnsAndTables =  "[SalesLT].[Address].[AddressID]",
                             "[SalesLT].[Address].[AddressLine2]",
                             "[SalesLT].[Address].[rowguid]",
                             "[SalesLT].[Address].[PostalCode]",
                             "[SalesLT].[ProductDescription]"
$MetadataList = [System.Collections.ArrayList]::new($IncludedColumnsAndTables)


Connect-AzAccount 
select-Azsubscription -SubscriptionId $SubscriptionId

# Use this section if it is safe to show password in the script.
# Otherwise, use the PromptForCredential
# $User = "username"
# $PWord = ConvertTo-SecureString -String "password" -AsPlainText -Force
# $Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User, $PWord

$Credential = $Host.ui.PromptForCredential("Need credential", 
              "Please enter your user name and password for server "+$ServerName+".database.windows.net", 
              "", 
              "")

 #Create a new Sync Agent
 Write-Host "Creating new Sync Agent "
 New-AzSqlSyncAgent -ResourceGroupName $ResourceGroupName  `
                               -ServerName  $ServerName  `
                               -SyncDatabaseName $SyncDatabaseName `
                              -SyncAgentName $SyncAgentName


#Generate Agent Key
Write-Host "Generating Agent Key"
$AgentKey = New-AzSqlSyncAgentKey -ResourceGroupName $ResourceGroupName   `
                              -ServerName  $ServerName  `
                              -SyncAgentName $SyncAgentName
 Write-Host "Use your agent key to configure the sync agent. Do this before proceeding"
$agentkey
                  
#DO THE FOLLOWING BEFORE THE NEXT STEP
#Install the on-premises sync agent on your machine and register the sync agent using the agent key generated above to bring the sync agent online.
#Add the SQL server database information including server name, database name, user name, password on the configuration tool within the sync agent.  


# Create a new sync group
Write-Host "Creating Sync Group"$SyncGroupName
New-AzSqlSyncGroup   -ResourceGroupName $ResourceGroupName `
                            -ServerName $ServerName `
                            -DatabaseName $DatabaseName `
                            -Name $SyncGroupName `
                            -SyncDatabaseName $SyncDatabaseName `
                            -SyncDatabaseServerName $SyncDatabaseServerName `
                            -SyncDatabaseResourceGroupName $SyncDatabaseResourceGroupName `
                            -ConflictResolutionPolicy $ConflictResolutionPolicy `
                            -DatabaseCredential $Credential

# Use this section if it is safe to show password in the script.
#$User = "username"
#$Password = ConvertTo-SecureString -String "password" -AsPlainText -Force
#$Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User, $Password

$Credential = $Host.ui.PromptForCredential("Need credential", 
              "Please enter your user name and password for server "+$MemberServerName, 
              "", 
              "")

#Get Information from sync Agent 
#Confirm that your SQL Server was configured
#Note the Database ID, you will use this as SqlServerDatabaseID for the next step.
$SyncAgentInfo = Get-AzSqlSyncAgentLinkedDatabase -ResourceGroupName $ResourceGroupName   `
                              -ServerName  $ServerName  `
                              -SyncAgentName $SyncAgentName

# Add a new sync member
Write-Host "Adding member"$SyncMemberName" to the sync group"



New-AzSqlSyncMember -ResourceGroupName $ResourceGroupName -ServerName $ServerName -DatabaseName $DatabaseName -SyncGroupName $SyncGroupName -Name $SyncMemberName -MemberDatabaseType $MemberDatabaseType -SyncAgentResourceGroupName SyncAgentResourceGroupName -SyncAgentServerName $SyncAgentServerName -SyncAgentName $SyncAgentName  -SyncDirection $SyncDirection -SqlServerDatabaseID  $SyncAgentInfo.DatabaseId

# Refresh database schema from hub database
# Specify the -SyncMemberName parameter if you want to refresh schema from the member database
Write-Host "Refreshing database schema from hub database"
$StartTime= Get-Date
Update-AzSqlSyncSchema   -ResourceGroupName $ResourceGroupName `
                              -ServerName $ServerName `
                              -DatabaseName $DatabaseName `
                              -SyncGroupName $SyncGroupName


#Waiting for successful refresh

$StartTime=$StartTime.ToUniversalTime()
$timer=0
$timeout=90
# Check the log and see if refresh has gone through
Write-Host "Check for successful refresh"
$IsSucceeded = $false
While ($IsSucceeded -eq $false)
{
    Start-Sleep -s 10
    $timer=$timer+10
    $Details = Get-AzSqlSyncSchema -SyncGroupName $SyncGroupName -ServerName $ServerName -DatabaseName $DatabaseName -ResourceGroupName $ResourceGroupName
    if ($Details.LastUpdateTime -gt $StartTime)
      {
        Write-Host "Refresh was successful"
        $IsSucceeded = $true
      }
    if ($timer -eq $timeout) 
      {
              Write-Host "Refresh timed out"
        break;
      }
}


# Get the database schema 
Write-Host "Adding tables and columns to the sync schema"
$databaseSchema = Get-AzSqlSyncSchema   -ResourceGroupName $ResourceGroupName `
                                             -ServerName $ServerName `
                                             -DatabaseName $DatabaseName `
                                             -SyncGroupName $SyncGroupName `

$databaseSchema | ConvertTo-Json -depth 5 -Compress | Out-File "C:\Users\OnPremiseServer\AppData\Local\Temp\syncSchema.json"     
$newSchema = [AzureSqlSyncGroupSchemaModel]::new()
$newSchema.Tables = [List[AzureSqlSyncGroupSchemaTableModel]]::new();

# Add columns and tables to the sync schema
foreach ($tableSchema in $databaseSchema.Tables)
{
    $newTableSchema = [AzureSqlSyncGroupSchemaTableModel]::new()
    $newTableSchema.QuotedName = $tableSchema.QuotedName
    $newTableSchema.Columns = [List[AzureSqlSyncGroupSchemaColumnModel]]::new();
    $addAllColumns = $false
    if ($MetadataList.Contains($tableSchema.QuotedName))
    {
        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
        }
    }
    foreach($columnSchema in $tableSchema.Columns)
    {
        $fullColumnName = $tableSchema.QuotedName + "." + $columnSchema.QuotedName
        if ($addAllColumns -or $MetadataList.Contains($fullColumnName))
        {
            if ((-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)
    {
        $newSchema.Tables.Add($newTableSchema)
    }
}

# Convert sync schema to Json format
$schemaString = $newSchema | ConvertTo-Json -depth 5 -Compress

# workaround a powershell bug
$schemaString = $schemaString.Replace('"Tables"', '"tables"').Replace('"Columns"', '"columns"').Replace('"QuotedName"', '"quotedName"').Replace('"MasterSyncMemberName"','"masterSyncMemberName"')

# Save the sync schema to a temp file
$schemaString | Out-File $TempFile

# Update sync schema
Write-Host "Updating the sync schema"
Update-AzSqlSyncGroup  -ResourceGroupName $ResourceGroupName `
                            -ServerName $ServerName `
                            -DatabaseName $DatabaseName `
                            -Name $SyncGroupName `
                            -Schema $TempFile

$SyncLogStartTime = Get-Date

# Trigger sync manually
Write-Host "Trigger sync manually"
Start-AzSqlSyncGroupSync  -ResourceGroupName $ResourceGroupName `
                               -ServerName $ServerName `
                               -DatabaseName $DatabaseName `
                               -SyncGroupName $SyncGroupName

# Check the sync log and wait until the first sync succeeded
Write-Host "Check the sync log"
$IsSucceeded = $false
For ($i = 0; ($i -lt 300) -and (-not $IsSucceeded); $i = $i + 10)
{
    Start-Sleep -s 10
    $SyncLogEndTime = Get-Date
    $SyncLogList = Get-AzSqlSyncGroupLog  -ResourceGroupName $ResourceGroupName `
                                           -ServerName $ServerName `
                                           -DatabaseName $DatabaseName `
                                           -SyncGroupName $SyncGroupName `
                                           -StartTime $SyncLogStartTime.ToUniversalTime() `
                                           -EndTime $SyncLogEndTime.ToUniversalTime()
    if ($SynclogList.Length -gt 0)
    {
        foreach ($SyncLog in $SyncLogList)
        {
            if ($SyncLog.Details.Contains("Sync completed successfully"))
            {
                Write-Host $SyncLog.TimeStamp : $SyncLog.Details
                $IsSucceeded = $true
            }
        }
    }
}

if ($IsSucceeded)
{
    # Enable scheduled sync
    Write-Host "Enable the scheduled sync with 300 seconds interval"
    Update-AzSqlSyncGroup  -ResourceGroupName $ResourceGroupName `
                                -ServerName $ServerName `
                                -DatabaseName $DatabaseName `
                                -Name $SyncGroupName `
                                -IntervalInSeconds $IntervalInSeconds
}
else
{
    # Output all log if sync doesn't succeed in 300 seconds
    $SyncLogEndTime = Get-Date
    $SyncLogList = Get-AzSqlSyncGroupLog  -ResourceGroupName $ResourceGroupName `
                                           -ServerName $ServerName `
                                           -DatabaseName $DatabaseName `
                                           -SyncGroupName $SyncGroupName `
                                           -StartTime $SyncLogStartTime.ToUniversalTime() `
                                           -EndTime $SyncLogEndTime.ToUniversalTime()
    if ($SynclogList.Length -gt 0)
    {
        foreach ($SyncLog in $SyncLogList)
        {
            Write-Host $SyncLog.TimeStamp : $SyncLog.Details
        }
    }
}
# Clean up deployment 
# Remove-AzResourceGroup -ResourceGroupName $resourcegroupname
# Remove-AzResourceGroup -ResourceGroupName $SyncDatabaseResourceGroupName

Bereinigen der BereitstellungClean up deployment

Nach der Ausführung des Beispielskripts können Sie den folgenden Befehl ausführen, um die Ressourcengruppe und alle damit verbundenen Ressourcen zu entfernen.After you run the sample script, you can run the following command to remove the resource group and all resources associated with it.

Remove-AzResourceGroup -ResourceGroupName $ResourceGroupName
Remove-AzResourceGroup -ResourceGroupName $SyncDatabaseResourceGroupName

Erläuterung des SkriptsScript explanation

Das Skript verwendet die folgenden Befehle.This script uses the following commands. Jeder Befehl in der Tabelle ist mit der zugehörigen Dokumentation verknüpft.Each command in the table links to command-specific documentation.

Get-HelpCommand NotizenNotes
New-AzSqlSyncAgentNew-AzSqlSyncAgent Erstellt einen neuen Synchronisierungs-AgentCreates a new Sync Agent
New-AzSqlSyncAgentKeyNew-AzSqlSyncAgentKey Generiert den Agent-Schlüssel, der dem Synchronisierungs-Agent zugeordnet istGenerates the agent key associated with the Sync agent
Get-AzSqlSyncAgentLinkedDatabaseGet-AzSqlSyncAgentLinkedDatabase Ruft alle Informationen für den Synchronisierungs-Agent abGet all the information for the Sync Agent
New-AzSqlSyncMemberNew-AzSqlSyncMember Fügt der Synchronisierungsgruppe ein neues Mitglied hinzuAdd a new member to the Sync Group
Update-AzSqlSyncSchemaUpdate-AzSqlSyncSchema Aktualisiert die Schemainformationen der DatenbankRefreshes the database schema information
Get-AzSqlSyncSchemaGet-AzSqlSyncSchema Ruft die Schemainformationen der Datenbank abGet the database schema information
Update-AzSqlSyncGroupUpdate-AzSqlSyncGroup Aktualisiert die SynchronisierungsgruppeUpdates the Sync Group
Start-AzSqlSyncGroupSyncStart-AzSqlSyncGroupSync Löst eine Synchronisierung ausTriggers a Sync
Get-AzSqlSyncGroupLogGet-AzSqlSyncGroupLog Überprüft das SynchronisierungsprotokollChecks the Sync Log

Nächste SchritteNext steps

Weitere Informationen zu Azure PowerShell finden Sie in der Azure PowerShell-Dokumentation.For more information about Azure PowerShell, see Azure PowerShell documentation.

Zusätzliche PowerShell-Skriptbeispiele für SQL-Datenbank finden Sie unter Azure PowerShell-Beispiele für Azure SQL-Datenbank.Additional SQL Database PowerShell script samples can be found in Azure SQL Database PowerShell scripts.

Weitere Informationen zur SQL-Datensynchronisierung finden Sie unter:For more info about SQL Data Sync, see:

Weitere Informationen zu SQL-Datenbank finden Sie unter:For more info about SQL Database, see: