diff --git a/azure-sql/database/copy-database-to-new-server/copy-database-to-new-server-az-ps.ps1 b/azure-sql/database/copy-database-to-new-server/copy-database-to-new-server-az-ps.ps1 new file mode 100644 index 0000000..3d694dc --- /dev/null +++ b/azure-sql/database/copy-database-to-new-server/copy-database-to-new-server-az-ps.ps1 @@ -0,0 +1,94 @@ +# +# Connect-AzAccount +# The SubscriptionId in which to create these objects +$subscriptionId = "" +# Set the resource group name and location for your source server +$sourceResourceGroupName = "mySourceResourceGroup-$(Get-Random)" +$sourceResourceGroupLocation = "westus2" +# Set the resource group name and location for your target server +$targetResourceGroupName = "myTargetResourceGroup-$(Get-Random)" +$targetResourceGroupLocation = "eastus" +# Set an admin login and password for your server +$adminSqlLogin = "" +$password = "" +# The logical server names have to be unique in the system +$sourceServerName = "source-server-$(Get-Random)" +$targetServerName = "target-server-$(Get-Random)" +# The sample database name +$sourceDatabaseName = "mySampleDatabase" +$targetDatabaseName = "CopyOfMySampleDatabase" +# The IP address range that you want to allow to access your servers +$sourceStartIp = "0.0.0.0" +$sourceEndIp = "0.0.0.0" +$targetStartIp = "0.0.0.0" +$targetEndIp = "0.0.0.0" + +# Set subscription +Set-AzContext -SubscriptionId $subscriptionId + +# Create two new resource groups +$sourceResourceGroup = New-AzResourceGroup -Name $sourceResourceGroupName -Location $sourceResourceGroupLocation +$targetResourceGroup = New-AzResourceGroup -Name $targetResourceGroupName -Location $targetResourceGroupLocation + +# Build the SQL administrator credential reused for both servers +$adminCredential = New-Object -TypeName System.Management.Automation.PSCredential ` + -ArgumentList $adminSqlLogin, (ConvertTo-SecureString -String $password -AsPlainText -Force) + +# Create a server with a system-wide unique server name +$sourceServerParams = @{ + ResourceGroupName = $sourceResourceGroupName + ServerName = $sourceServerName + Location = $sourceResourceGroupLocation + SqlAdministratorCredentials = $adminCredential +} +$sourceResourceGroup = New-AzSqlServer @sourceServerParams +$targetServerParams = @{ + ResourceGroupName = $targetResourceGroupName + ServerName = $targetServerName + Location = $targetResourceGroupLocation + SqlAdministratorCredentials = $adminCredential +} +$targetResourceGroup = New-AzSqlServer @targetServerParams + +# Create a server firewall rule that allows access from the specified IP range +$sourceFirewallParams = @{ + ResourceGroupName = $sourceResourceGroupName + ServerName = $sourceServerName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $sourceStartIp + EndIpAddress = $sourceEndIp +} +$sourceServerFirewallRule = New-AzSqlServerFirewallRule @sourceFirewallParams +$targetFirewallParams = @{ + ResourceGroupName = $targetResourceGroupName + ServerName = $targetServerName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $targetStartIp + EndIpAddress = $targetEndIp +} +$targetServerFirewallRule = New-AzSqlServerFirewallRule @targetFirewallParams + +# Create a blank database in the source-server with an S0 performance level +$sourceDatabaseParams = @{ + ResourceGroupName = $sourceResourceGroupName + ServerName = $sourceServerName + DatabaseName = $sourceDatabaseName + RequestedServiceObjectiveName = "S0" +} +$sourceDatabase = New-AzSqlDatabase @sourceDatabaseParams + +# Copy source database to the target server +$databaseCopyParams = @{ + ResourceGroupName = $sourceResourceGroupName + ServerName = $sourceServerName + DatabaseName = $sourceDatabaseName + CopyResourceGroupName = $targetResourceGroupName + CopyServerName = $targetServerName + CopyDatabaseName = $targetDatabaseName +} +$databaseCopy = New-AzSqlDatabaseCopy @databaseCopyParams + +# Clean up deployment +# Remove-AzResourceGroup -ResourceGroupName $sourceResourceGroupName +# Remove-AzResourceGroup -ResourceGroupName $targetResourceGroupName +# diff --git a/azure-sql/database/create-and-configure-database/create-and-configure-database-az-ps.ps1 b/azure-sql/database/create-and-configure-database/create-and-configure-database-az-ps.ps1 new file mode 100644 index 0000000..f7d9af2 --- /dev/null +++ b/azure-sql/database/create-and-configure-database/create-and-configure-database-az-ps.ps1 @@ -0,0 +1,59 @@ +# +# Connect-AzAccount +# The SubscriptionId in which to create these objects +$subscriptionId = "" +# Set the resource group name and location for your server +$resourceGroupName = "myResourceGroup-$(Get-Random)" +$location = "westus2" +# Set an admin login and password for your server +$adminSqlLogin = "" +$password = "" +# Set server name - the logical server name has to be unique in the system +$serverName = "server-$(Get-Random)" +# The sample database name +$databaseName = "mySampleDatabase" +# The IP address range that you want to allow to access your server +$startIp = "0.0.0.0" +$endIp = "0.0.0.0" + +# Set subscription +Set-AzContext -SubscriptionId $subscriptionId + +# Create a resource group +$resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location + +# Create a credential for the server admin +$adminCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminSqlLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force) + +# Create a server with a system-wide unique server name +$serverParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + Location = $location + SqlAdministratorCredentials = $adminCredential +} +$server = New-AzSqlServer @serverParams + +# Create a server firewall rule that allows access from the specified IP range +$firewallParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $startIp + EndIpAddress = $endIp +} +$serverFirewallRule = New-AzSqlServerFirewallRule @firewallParams + +# Create a blank database with an S0 performance level +$databaseParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $databaseName + RequestedServiceObjectiveName = "S0" + SampleName = "AdventureWorksLT" +} +$database = New-AzSqlDatabase @databaseParams + +# Clean up deployment +# Remove-AzResourceGroup -ResourceGroupName $resourceGroupName +# diff --git a/azure-sql/database/failover-groups/add-elastic-pool-to-failover-group-az-ps.ps1 b/azure-sql/database/failover-groups/add-elastic-pool-to-failover-group-az-ps.ps1 index 1dbad80..54d186b 100644 --- a/azure-sql/database/failover-groups/add-elastic-pool-to-failover-group-az-ps.ps1 +++ b/azure-sql/database/failover-groups/add-elastic-pool-to-failover-group-az-ps.ps1 @@ -1,16 +1,11 @@ - # -# Add an elastic pool in Azure SQL Database to a failover group - -# - # Set variables for your server and database $subscriptionId = '' $randomIdentifier = $(Get-Random) $resourceGroupName = "myResourceGroup-$randomIdentifier" $location = "East US" -$adminLogin = "azureuser" -$password = "PWD27!"+(New-Guid).Guid +$adminLogin = "" +$password = "" $serverName = "mysqlserver-$randomIdentifier" $poolName = "myElasticPool" $databaseName = "mySampleDatabase" @@ -18,190 +13,199 @@ $drLocation = "West US" $drServerName = "mysqlsecondary-$randomIdentifier" $failoverGroupName = "failovergrouptutorial-$randomIdentifier" - -# The ip address range that you want to allow to access your server -# Leaving at 0.0.0.0 will prevent outside-of-azure connections +# The IP address range that you want to allow to access your server +# Leaving at 0.0.0.0 will prevent outside-of-Azure connections $startIp = "0.0.0.0" $endIp = "0.0.0.0" # Show randomized variables -Write-host "Resource group name is" $resourceGroupName -Write-host "Password is" $password -Write-host "Server name is" $serverName -Write-host "DR Server name is" $drServerName -Write-host "Failover group name is" $failoverGroupName - -# - -# +Write-Host "Resource group name is" $resourceGroupName +Write-Host "Password is" $password +Write-Host "Server name is" $serverName +Write-Host "DR Server name is" $drServerName +Write-Host "Failover group name is" $failoverGroupName # Set subscription ID -Set-AzContext -SubscriptionId $subscriptionId +Set-AzContext -SubscriptionId $subscriptionId # Create a resource group -Write-host "Creating resource group..." -$resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location -Tag @{Owner="SQLDB-Samples"} +Write-Host "Creating resource group..." +$resourceGroupParams = @{ + Name = $resourceGroupName + Location = $location + Tag = @{Owner = "SQLDB-Samples" } +} +$resourceGroup = New-AzResourceGroup @resourceGroupParams $resourceGroup -# - -# +# Build the SQL administrator credential reused for both servers +$adminCredential = New-Object -TypeName System.Management.Automation.PSCredential ` + -ArgumentList $adminLogin, (ConvertTo-SecureString -String $password -AsPlainText -Force) # Create a server with a system-wide unique server name -Write-host "Creating primary logical server..." -New-AzSqlServer -ResourceGroupName $resourceGroupName ` - -ServerName $serverName ` - -Location $location ` - -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential ` - -ArgumentList $adminLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force)) -Write-host "Primary logical server = " $serverName +Write-Host "Creating primary logical server..." +$primaryServerParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + Location = $location + SqlAdministratorCredentials = $adminCredential +} +New-AzSqlServer @primaryServerParams +Write-Host "Primary logical server = " $serverName # Create a server firewall rule that allows access from the specified IP range -Write-host "Configuring firewall for primary logical server..." -New-AzSqlServerFirewallRule -ResourceGroupName $resourceGroupName ` - -ServerName $serverName ` - -FirewallRuleName "AllowedIPs" -StartIpAddress $startIp -EndIpAddress $endIp -Write-host "Firewall configured" +Write-Host "Configuring firewall for primary logical server..." +$primaryFirewallParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $startIp + EndIpAddress = $endIp +} +New-AzSqlServerFirewallRule @primaryFirewallParams +Write-Host "Firewall configured" # Create General Purpose Gen5 database with 2 vCore -Write-host "Creating a gen5 2 vCore database..." -$database = New-AzSqlDatabase -ResourceGroupName $resourceGroupName ` - -ServerName $serverName ` - -DatabaseName $databaseName ` - -Edition "GeneralPurpose" ` - -VCore 2 ` - -ComputeGeneration Gen5 ` - -MinimumCapacity 1 ` - -SampleName "AdventureWorksLT" +Write-Host "Creating a gen5 2 vCore database..." +$databaseParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $databaseName + Edition = "GeneralPurpose" + VCore = 2 + ComputeGeneration = "Gen5" + MinimumCapacity = 1 + SampleName = "AdventureWorksLT" +} +$database = New-AzSqlDatabase @databaseParams $database # Create primary Gen5 elastic 2 vCore pool -Write-host "Creating elastic pool..." -$elasticPool = New-AzSqlElasticPool -ResourceGroupName $resourceGroupName ` - -ServerName $serverName ` - -ElasticPoolName $poolName ` - -Edition "GeneralPurpose" ` - -vCore 2 ` - -ComputeGeneration Gen5 +Write-Host "Creating elastic pool..." +$primaryPoolParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + ElasticPoolName = $poolName + Edition = "GeneralPurpose" + VCore = 2 + ComputeGeneration = "Gen5" +} +$elasticPool = New-AzSqlElasticPool @primaryPoolParams $elasticPool -# Add single db into elastic pool -Write-host "Creating elastic pool..." -$addDatabase = Set-AzSqlDatabase -ResourceGroupName $resourceGroupName ` - -ServerName $serverName ` - -DatabaseName $databaseName ` - -ElasticPoolName $poolName +# Add single database into elastic pool +Write-Host "Creating elastic pool..." +$addDatabaseParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $databaseName + ElasticPoolName = $poolName +} +$addDatabase = Set-AzSqlDatabase @addDatabaseParams $addDatabase -# - -# - # Create a secondary server in the failover region -Write-host "Creating a secondary logical server in the failover region..." -New-AzSqlServer -ResourceGroupName $resourceGroupName ` - -ServerName $drServerName ` - -Location $drLocation ` - -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential ` - -ArgumentList $adminlogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force)) -Write-host "Secondary logical server =" $drServerName +Write-Host "Creating a secondary logical server in the failover region..." +$secondaryServerParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $drServerName + Location = $drLocation + SqlAdministratorCredentials = $adminCredential +} +New-AzSqlServer @secondaryServerParams +Write-Host "Secondary logical server =" $drServerName # Create a server firewall rule that allows access from the specified IP range -Write-host "Configuring firewall for secondary logical server..." -New-AzSqlServerFirewallRule -ResourceGroupName $resourceGroupName ` - -ServerName $drServerName ` - -FirewallRuleName "AllowedIPs" -StartIpAddress $startIp -EndIpAddress $endIp -Write-host "Firewall configured" +Write-Host "Configuring firewall for secondary logical server..." +$secondaryFirewallParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $drServerName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $startIp + EndIpAddress = $endIp +} +New-AzSqlServerFirewallRule @secondaryFirewallParams +Write-Host "Firewall configured" # Create secondary Gen5 elastic 2 vCore pool -Write-host "Creating secondary elastic pool..." -$elasticPool = New-AzSqlElasticPool -ResourceGroupName $resourceGroupName ` - -ServerName $drServerName ` - -ElasticPoolName $poolName ` - -Edition "GeneralPurpose" ` - -vCore 2 ` - -ComputeGeneration Gen5 +Write-Host "Creating secondary elastic pool..." +$secondaryPoolParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $drServerName + ElasticPoolName = $poolName + Edition = "GeneralPurpose" + VCore = 2 + ComputeGeneration = "Gen5" +} +$elasticPool = New-AzSqlElasticPool @secondaryPoolParams $elasticPool -# - -# - # Create a failover group between the servers -Write-host "Creating failover group..." -New-AzSqlDatabaseFailoverGroup ` - –ResourceGroupName $resourceGroupName ` - -ServerName $serverName ` - -PartnerServerName $drServerName ` - –FailoverGroupName $failoverGroupName ` - –FailoverPolicy Manual -Write-host "Failover group created successfully." - -# - -# +Write-Host "Creating failover group..." +$failoverGroupParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + PartnerServerName = $drServerName + FailoverGroupName = $failoverGroupName + FailoverPolicy = "Automatic" + GracePeriodWithDataLossHours = 2 +} +New-AzSqlDatabaseFailoverGroup @failoverGroupParams +Write-Host "Failover group created successfully." # Add elastic pool to the failover group -Write-host "Enumerating databases in elastic pool...." -$FailoverGroup = Get-AzSqlDatabaseFailoverGroup ` - -ResourceGroupName $resourceGroupName ` - -ServerName $serverName ` - -FailoverGroupName $failoverGroupName -$databases = Get-AzSqlElasticPoolDatabase ` - -ResourceGroupName $resourceGroupName ` - -ServerName $serverName ` - -ElasticPoolName $poolName -Write-host "Adding databases to failover group..." -$failoverGroup = $failoverGroup | Add-AzSqlDatabaseToFailoverGroup ` - -Database $databases +Write-Host "Enumerating databases in elastic pool...." +$getFailoverGroupParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + FailoverGroupName = $failoverGroupName +} +$failoverGroup = Get-AzSqlDatabaseFailoverGroup @getFailoverGroupParams +$poolDatabaseParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + ElasticPoolName = $poolName +} +$databases = Get-AzSqlElasticPoolDatabase @poolDatabaseParams +Write-Host "Adding databases to failover group..." +$failoverGroup = $failoverGroup | Add-AzSqlDatabaseToFailoverGroup -Database $databases $failoverGroup -# - -# - # Check role of secondary replica -Write-host "Confirming the secondary server is secondary...." -(Get-AzSqlDatabaseFailoverGroup ` - -FailoverGroupName $failoverGroupName ` - -ResourceGroupName $resourceGroupName ` - -ServerName $drServerName).ReplicationRole - -# +Write-Host "Confirming the secondary server is secondary...." +$secondaryRoleParams = @{ + FailoverGroupName = $failoverGroupName + ResourceGroupName = $resourceGroupName + ServerName = $drServerName +} +(Get-AzSqlDatabaseFailoverGroup @secondaryRoleParams).ReplicationRole -# # Failover to secondary server -Write-host "Failing over failover group to the secondary..." -Switch-AzSqlDatabaseFailoverGroup ` - -ResourceGroupName $resourceGroupName ` - -ServerName $drServerName ` - -FailoverGroupName $failoverGroupName -Write-host "Failover group failed over to" $drServerName +Write-Host "Failing over failover group to the secondary..." +$switchToSecondaryParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $drServerName + FailoverGroupName = $failoverGroupName +} +Switch-AzSqlDatabaseFailoverGroup @switchToSecondaryParams +Write-Host "Failover group failed over to" $drServerName # Check role of secondary replica -Write-host "Confirming the secondary server is now primary" -(Get-AzSqlDatabaseFailoverGroup ` - -FailoverGroupName $failoverGroupName ` - -ResourceGroupName $resourceGroupName ` - -ServerName $drServerName).ReplicationRole - -# - -# +Write-Host "Confirming the secondary server is now primary" +(Get-AzSqlDatabaseFailoverGroup @secondaryRoleParams).ReplicationRole # Revert failover to primary server -Write-host "Failing over failover group to the primary...." -Switch-AzSqlDatabaseFailoverGroup ` - -ResourceGroupName $resourceGroupName ` - -ServerName $serverName ` - -FailoverGroupName $failoverGroupName -Write-host "Failover group failed over to" $serverName - -# +Write-Host "Failing over failover group to the primary...." +$switchToPrimaryParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + FailoverGroupName = $failoverGroupName +} +Switch-AzSqlDatabaseFailoverGroup @switchToPrimaryParams +Write-Host "Failover group failed over to" $serverName # Clean up resources by removing the resource group -# Write-host "Removing resource group..." +# Write-Host "Removing resource group..." # Remove-AzResourceGroup -ResourceGroupName $resourceGroupName -# Write-host "Resource group removed =" $resourceGroupName - -# \ No newline at end of file +# Write-Host "Resource group removed =" $resourceGroupName +# diff --git a/azure-sql/database/import-from-bacpac/import-from-bacpac-az-ps.ps1 b/azure-sql/database/import-from-bacpac/import-from-bacpac-az-ps.ps1 new file mode 100644 index 0000000..9a8e995 --- /dev/null +++ b/azure-sql/database/import-from-bacpac/import-from-bacpac-az-ps.ps1 @@ -0,0 +1,119 @@ +# +# Connect-AzAccount +# The SubscriptionId in which to create these objects +$subscriptionId = "" +# Set the resource group name and location for your server +$resourceGroupName = "myResourceGroup-$(Get-Random)" +$location = "westeurope" +# Set an admin login and password for your server +$adminSqlLogin = "" +$password = "" +# Set server name - the logical server name has to be unique in the system +$serverName = "server-$(Get-Random)" +# The sample database name +$databaseName = "myImportedDatabase" +# The storage account name and storage container name +$storageAccountName = "sqlimport$(Get-Random)" +$storageContainerName = "importcontainer$(Get-Random)" +# BACPAC file name +$bacpacFilename = "sample.bacpac" +# The IP address range that you want to allow to access your server +$startIp = "0.0.0.0" +$endIp = "0.0.0.0" + +# Set subscription +Set-AzContext -SubscriptionId $subscriptionId + +# Create a resource group +$resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location + +# Create a storage account +$storageAccountParams = @{ + ResourceGroupName = $resourceGroupName + Name = $storageAccountName + Location = $location + SkuName = "Standard_LRS" +} +$storageAccount = New-AzStorageAccount @storageAccountParams + +# Create a storage context for the storage account +$storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageAccountName).Value[0] +$storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey + +# Create a storage container +$storageContainer = New-AzStorageContainer -Name $storageContainerName -Context $storageContext + +# Download sample database from GitHub +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 #required by GitHub +Invoke-WebRequest -Uri "https://github.com/Microsoft/sql-server-samples/releases/download/wide-world-importers-v1.0/WideWorldImporters-Standard.bacpac" -OutFile $bacpacFilename + +# Upload sample database into storage container +$blobContentParams = @{ + Container = $storageContainerName + File = $bacpacFilename + Context = $storageContext +} +Set-AzStorageBlobContent @blobContentParams + +# Create a credential for the server admin +$adminCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminSqlLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force) + +# Create a new server with a system-wide unique server name +$serverParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + Location = $location + SqlAdministratorCredentials = $adminCredential +} +$server = New-AzSqlServer @serverParams + +# Create a server firewall rule that allows access from the specified IP range +$firewallParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $startIp + EndIpAddress = $endIp +} +$serverFirewallRule = New-AzSqlServerFirewallRule @firewallParams + +# Import BACPAC to database with an S3 performance level +$importParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $databaseName + DatabaseMaxSizeBytes = 100GB + StorageKeyType = "StorageAccessKey" + StorageKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -StorageAccountName $storageAccountName).Value[0] + StorageUri = "https://$storageAccountName.blob.core.windows.net/$storageContainerName/$bacpacFilename" + Edition = "Standard" + ServiceObjectiveName = "S3" + AdministratorLogin = "$adminSqlLogin" + AdministratorLoginPassword = $(ConvertTo-SecureString -String $password -AsPlainText -Force) +} +$importRequest = New-AzSqlDatabaseImport @importParams + +# Check import status and wait for the import to complete +$importStatus = Get-AzSqlDatabaseImportExportStatus -OperationStatusLink $importRequest.OperationStatusLink +[Console]::Write("Importing") +while ($importStatus.Status -eq "InProgress") { + $importStatus = Get-AzSqlDatabaseImportExportStatus -OperationStatusLink $importRequest.OperationStatusLink + [Console]::Write(".") + Start-Sleep -s 10 +} +[Console]::WriteLine("") +$importStatus + +# Scale down to S0 after import is complete +$scaleDownParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $databaseName + Edition = "Standard" + RequestedServiceObjectiveName = "S0" +} +Set-AzSqlDatabase @scaleDownParams + +# Clean up deployment +# Remove-AzResourceGroup -ResourceGroupName $resourceGroupName +# diff --git a/azure-sql/database/monitor-and-scale-database/monitor-and-scale-database-az-ps.ps1 b/azure-sql/database/monitor-and-scale-database/monitor-and-scale-database-az-ps.ps1 new file mode 100644 index 0000000..488bba1 --- /dev/null +++ b/azure-sql/database/monitor-and-scale-database/monitor-and-scale-database-az-ps.ps1 @@ -0,0 +1,145 @@ +# +# This script requires the following +# - Az.Resources +# - Az.Accounts +# - Az.Monitor +# - Az.Sql + +# First, run Connect-AzAccount + +# Set the subscription in which to create these objects. This is displayed on objects in the Azure portal. +$subscriptionId = "" +# Set the resource group name and location for your server +$resourceGroupName = "myResourceGroup-$(Get-Random)" +$location = "westus2" +# Set an admin login and password for your server +$adminSqlLogin = "" +$password = "" +# Set server name - the logical server name has to be unique in the system +$serverName = "server-$(Get-Random)" +# The sample database name +$databaseName = "mySampleDatabase" +# The IP address range that you want to allow to access your server via the firewall rule +$startIp = "0.0.0.0" +$endIp = "0.0.0.0" + +# Set subscription +Set-AzContext -SubscriptionId $subscriptionId + +# Create a new resource group +$resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location + +# Create a credential for the server admin +$adminCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminSqlLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force) + +# Create a new server with a system-wide unique server name +$serverParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + Location = $location + SqlAdministratorCredentials = $adminCredential +} +$server = New-AzSqlServer @serverParams + +# Create a server firewall rule that allows access from the specified IP range +$firewallParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $startIp + EndIpAddress = $endIp +} +$serverFirewallRule = New-AzSqlServerFirewallRule @firewallParams + +# Create a blank database with an S0 performance level +$databaseParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $databaseName + RequestedServiceObjectiveName = "S0" + SampleName = "AdventureWorksLT" +} +$database = New-AzSqlDatabase @databaseParams + +# Monitor the DTU consumption on the database in 5-minute intervals +$monitorParameters = @{ + ResourceId = "/subscriptions/$($(Get-AzContext).Subscription.Id)/resourceGroups/$resourceGroupName/providers/Microsoft.Sql/servers/$serverName/databases/$databaseName" + TimeGrain = [TimeSpan]::Parse("00:05:00") + MetricNames = "dtu_consumption_percent" +} +$metric = Get-AzMetric @monitorParameters +$metric.Data + +# Scale the database performance to Standard S1 +$scaleParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $databaseName + Edition = "Standard" + RequestedServiceObjectiveName = "S1" +} +$database = Set-AzSqlDatabase @scaleParams + +# Set up an Alert rule using Azure Monitor for the database +# Add an Alert that fires when the pool utilization reaches 90% +# Objects needed: An Action Group Receiver (in this case, an email group), an Action Group, Alert Criteria, and finally an Alert Rule. + +# Creates a new action group receiver object with a target email address. +$receiver = New-AzActionGroupReceiver -Name "my Sample Azure Admins" -EmailAddress "azure-admins-group@contoso.com" + +# Creates a new or updates an existing action group. +$actionGroupParams = @{ + Name = "mysample-email-the-azure-admins" + ShortName = "AzAdminsGrp" + ResourceGroupName = $resourceGroupName + Receiver = $receiver +} +$actionGroup = Set-AzActionGroup @actionGroupParams + +# Fetch the created AzActionGroup into an object of type Microsoft.Azure.Management.Monitor.Models.ActivityLogAlertActionGroup +$actionGroupObject = New-AzActionGroup -ActionGroupId $actionGroup.Id + +# Create a criteria for the Alert to monitor. +$criteriaParams = @{ + MetricName = "dtu_consumption_percent" + TimeAggregation = "Average" + Operator = "GreaterThan" + Threshold = 90 +} +$criteria = New-AzMetricAlertRuleV2Criteria @criteriaParams + +# Create the Alert rule. +# Add-AzMetricAlertRuleV2 adds or updates a V2 (non-classic) metric-based alert rule. +$alertRuleParams = @{ + Name = "mySample_Alert_DTU_consumption_pct" + ResourceGroupName = $resourceGroupName + WindowSize = (New-TimeSpan -Minutes 1) + Frequency = (New-TimeSpan -Minutes 1) + TargetResourceId = "/subscriptions/$($(Get-AzContext).Subscription.Id)/resourceGroups/$resourceGroupName/providers/Microsoft.Sql/servers/$serverName/databases/$databaseName" + Condition = $criteria + ActionGroup = $actionGroupObject + Severity = 3 #Informational +} +Add-AzMetricAlertRuleV2 @alertRuleParams + +<# +# Set up an alert rule using Azure Monitor for the database +# Note that Add-AzMetricAlertRule is deprecated. Use Add-AzMetricAlertRuleV2 instead. +$deprecatedAlertParams = @{ + ResourceGroup = $resourceGroupName + Name = "MySampleAlertRule" + Location = $location + TargetResourceId = "/subscriptions/$($(Get-AzContext).Subscription.Id)/resourceGroups/$resourceGroupName/providers/Microsoft.Sql/servers/$serverName/databases/$databaseName" + MetricName = "dtu_consumption_percent" + Operator = "GreaterThan" + Threshold = 90 + WindowSize = $([TimeSpan]::Parse("00:05:00")) + TimeAggregationOperator = "Average" + Action = $(New-AzAlertRuleEmail -SendToServiceOwner) +} +Add-AzMetricAlertRule @deprecatedAlertParams +#> + +# Clean up deployment +# Remove-AzResourceGroup -ResourceGroupName $resourceGroupName +# diff --git a/azure-sql/database/monitor-and-scale-pool/monitor-and-scale-pool-az-ps.ps1 b/azure-sql/database/monitor-and-scale-pool/monitor-and-scale-pool-az-ps.ps1 new file mode 100644 index 0000000..18482d7 --- /dev/null +++ b/azure-sql/database/monitor-and-scale-pool/monitor-and-scale-pool-az-ps.ps1 @@ -0,0 +1,168 @@ +# +# This script requires the following +# - Az.Resources +# - Az.Accounts +# - Az.Monitor +# - Az.Sql + +# First, run Connect-AzAccount + +# Set the subscription in which to create these objects. This is displayed on objects in the Azure portal. +$subscriptionId = "" +# Set the resource group name and location for your server +$resourceGroupName = "myResourceGroup-$(Get-Random)" +$location = "westus2" +# Set elastic pool name +$poolName = "MySamplePool" +# Set an admin login and password for your database +$adminSqlLogin = "" +$password = "" +# Set server name - the logical server name has to be unique in the system +$serverName = "server-$(Get-Random)" +# The sample database names +$firstDatabaseName = "myFirstSampleDatabase" +$secondDatabaseName = "mySecondSampleDatabase" +# The IP address range that you want to allow to access your server via the firewall rule +$startIp = "0.0.0.0" +$endIp = "0.0.0.0" + +# Set subscription +Set-AzContext -SubscriptionId $subscriptionId + +# Create a new resource group +$resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location + +$adminCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminSqlLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force) + +# Create a new server with a system-wide unique server name +$serverParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + Location = $location + SqlAdministratorCredentials = $adminCredential +} +$server = New-AzSqlServer @serverParams + +# Create elastic database pool +$elasticPoolParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + ElasticPoolName = $poolName + Edition = "Standard" + Dtu = 50 + DatabaseDtuMin = 10 + DatabaseDtuMax = 50 +} +$elasticPool = New-AzSqlElasticPool @elasticPoolParams + +# Create a server firewall rule that allows access from the specified IP range +$firewallParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $startIp + EndIpAddress = $endIp +} +$serverFirewallRule = New-AzSqlServerFirewallRule @firewallParams + +# Create two blank databases in the pool +$firstDatabaseParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $firstDatabaseName + ElasticPoolName = $poolName +} +$firstDatabase = New-AzSqlDatabase @firstDatabaseParams +$secondDatabaseParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $secondDatabaseName + ElasticPoolName = $poolName +} +$secondDatabase = New-AzSqlDatabase @secondDatabaseParams + +# Monitor the DTU consumption of the pool in 5-minute intervals +$monitorParameters = @{ + ResourceId = "/subscriptions/$($(Get-AzContext).Subscription.Id)/resourceGroups/$resourceGroupName/providers/Microsoft.Sql/servers/$serverName/elasticPools/$poolName" + TimeGrain = [TimeSpan]::Parse("00:05:00") + MetricNames = "dtu_consumption_percent" +} +$metric = Get-AzMetric @monitorParameters +$metric.Data + +# Scale the pool +$scaleParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + ElasticPoolName = $poolName + Edition = "Standard" + Dtu = 100 + DatabaseDtuMin = 20 + DatabaseDtuMax = 100 +} +$elasticPool = Set-AzSqlElasticPool @scaleParams + +# Set up an Alert rule using Azure Monitor for the database +# Add an Alert that fires when the pool utilization reaches 90% +# Objects needed: an Action Group Receiver, an Action Group, Alert Criteria, and finally an Alert Rule. + +# Creates a new action group receiver object with a target email address. +$receiver = New-AzActionGroupReceiver -Name "my Sample Azure Admins" -EmailAddress "azure-admins-group@contoso.com" + +# Creates a new or updates an existing action group. +$actionGroupParams = @{ + Name = "mysample-email-the-azure-admins" + ShortName = "AzAdminsGrp" + ResourceGroupName = $resourceGroupName + Receiver = $receiver +} +$actionGroup = Set-AzActionGroup @actionGroupParams + +# Fetch the created AzActionGroup into an object of type Microsoft.Azure.Management.Monitor.Models.ActivityLogAlertActionGroup +$actionGroupObject = New-AzActionGroup -ActionGroupId $actionGroup.Id + +# Create a criteria for the Alert to monitor. +$criteriaParams = @{ + MetricName = "dtu_consumption_percent" + TimeAggregation = "Average" + Operator = "GreaterThan" + Threshold = 90 +} +$criteria = New-AzMetricAlertRuleV2Criteria @criteriaParams + +# Create the Alert rule. +# Add-AzMetricAlertRuleV2 adds or updates a V2 (non-classic) metric-based alert rule. +$alertRuleParams = @{ + Name = "mySample_Alert_DTU_consumption_pct" + ResourceGroupName = $resourceGroupName + WindowSize = (New-TimeSpan -Minutes 1) + Frequency = (New-TimeSpan -Minutes 1) + TargetResourceId = "/subscriptions/$($(Get-AzContext).Subscription.Id)/resourceGroups/$resourceGroupName/providers/Microsoft.Sql/servers/$serverName/elasticPools/$poolName" + Condition = $criteria + ActionGroup = $actionGroupObject + Severity = 3 #Informational +} +Add-AzMetricAlertRuleV2 @alertRuleParams + +<# +# Set up an alert rule using Azure Monitor for the database +# Add a classic alert that fires when the pool utilization reaches 90% +# Note that Add-AzMetricAlertRule is deprecated. Use Add-AzMetricAlertRuleV2 instead. +$deprecatedAlertParams = @{ + ResourceGroup = $resourceGroupName + Name = "mySampleAlertRule" + Location = $location + TargetResourceId = "/subscriptions/$($(Get-AzContext).Subscription.Id)/resourceGroups/$resourceGroupName/providers/Microsoft.Sql/servers/$serverName/elasticPools/$poolName" + MetricName = "dtu_consumption_percent" + Operator = "GreaterThan" + Threshold = 90 + WindowSize = $([TimeSpan]::Parse("00:05:00")) + TimeAggregationOperator = "Average" + Action = $(New-AzAlertRuleEmail -SendToServiceOwner) +} +Add-AzMetricAlertRule @deprecatedAlertParams +#> + +# Clean up deployment +# Remove-AzResourceGroup -ResourceGroupName $resourceGroupName +# diff --git a/azure-sql/database/move-database-between-pools-and-standalone/move-database-between-pools-and-standalone-az-ps.ps1 b/azure-sql/database/move-database-between-pools-and-standalone/move-database-between-pools-and-standalone-az-ps.ps1 new file mode 100644 index 0000000..238746c --- /dev/null +++ b/azure-sql/database/move-database-between-pools-and-standalone/move-database-between-pools-and-standalone-az-ps.ps1 @@ -0,0 +1,107 @@ +# +# Connect-AzAccount +$subscriptionId = "" +# Set the resource group name and location for your server +$resourceGroupName = "myResourceGroup-$(Get-Random)" +$location = "westus2" +# Set elastic pool names +$firstPoolName = "MyFirstPool" +$secondPoolName = "MySecondPool" +# Set an admin login and password for your server +$adminSqlLogin = "" +$password = "" +# The logical server name has to be unique in the system +$serverName = "server-$(Get-Random)" +# The sample database names +$firstDatabaseName = "myFirstSampleDatabase" +$secondDatabaseName = "mySecondSampleDatabase" +# The IP address range that you want to allow to access your server +$startIp = "0.0.0.0" +$endIp = "0.0.0.0" + +# Set subscription +Set-AzContext -SubscriptionId $subscriptionId + +# Create a new resource group +$resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location + +$adminCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminSqlLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force) + +# Create a new server with a system-wide unique server name +$serverParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + Location = $location + SqlAdministratorCredentials = $adminCredential +} +$server = New-AzSqlServer @serverParams + +# Create a server firewall rule that allows access from the specified IP range +$firewallParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $startIp + EndIpAddress = $endIp +} +$serverFirewallRule = New-AzSqlServerFirewallRule @firewallParams + +# Create two elastic database pools +$firstPoolParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + ElasticPoolName = $firstPoolName + Edition = "Standard" + Dtu = 50 + DatabaseDtuMin = 10 + DatabaseDtuMax = 20 +} +$firstPool = New-AzSqlElasticPool @firstPoolParams +$secondPoolParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + ElasticPoolName = $secondPoolName + Edition = "Standard" + Dtu = 50 + DatabaseDtuMin = 10 + DatabaseDtuMax = 50 +} +$secondPool = New-AzSqlElasticPool @secondPoolParams + +# Create two blank databases in the first pool +$firstDatabaseParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $firstDatabaseName + ElasticPoolName = $firstPoolName +} +$firstDatabase = New-AzSqlDatabase @firstDatabaseParams +$secondDatabaseParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $secondDatabaseName + ElasticPoolName = $secondPoolName +} +$secondDatabase = New-AzSqlDatabase @secondDatabaseParams + +# Move the database to the second pool +$moveToPoolParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $firstDatabaseName + ElasticPoolName = $secondPoolName +} +$firstDatabase = Set-AzSqlDatabase @moveToPoolParams + +# Move the database into a standalone performance level +$moveToStandaloneParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $firstDatabaseName + RequestedServiceObjectiveName = "S0" +} +$firstDatabase = Set-AzSqlDatabase @moveToStandaloneParams + +# Clean up deployment +# Remove-AzResourceGroup -ResourceGroupName $resourceGroupName +# diff --git a/azure-sql/database/restore-database/restore-database-az-ps.ps1 b/azure-sql/database/restore-database/restore-database-az-ps.ps1 new file mode 100644 index 0000000..0dc6543 --- /dev/null +++ b/azure-sql/database/restore-database/restore-database-az-ps.ps1 @@ -0,0 +1,77 @@ +# +# Connect-AzAccount +$subscriptionId = "" +# Set the resource group name and location for your server +$resourceGroupName = "myResourceGroup-$(Get-Random)" +$location = "westus2" +# Set an admin login and password for your server +$adminSqlLogin = "" +$password = "" +# Set server name - the logical server name has to be unique in the system +$serverName = "server-$(Get-Random)" +# The sample database name +$databaseName = "mySampleDatabase" +# The restored database names +$pointInTimeRestoreDatabaseName = "MySampleDatabase_10MinutesAgo" +# The IP address range that you want to allow to access your server +$startIp = "0.0.0.0" +$endIp = "0.0.0.0" + +# Set subscription +Set-AzContext -SubscriptionId $subscriptionId + +# Create a resource group +$resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location + +$adminCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminSqlLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force) + +# Create a server with a system-wide unique server name +$serverParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + Location = $location + SqlAdministratorCredentials = $adminCredential +} +$server = New-AzSqlServer @serverParams + +# Create a server firewall rule that allows access from the specified IP range +$firewallParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $startIp + EndIpAddress = $endIp +} +$firewallRule = New-AzSqlServerFirewallRule @firewallParams + +# Create a blank database with an S0 performance level +$databaseParams = @{ + ResourceGroupName = $resourceGroupName + ServerName = $serverName + DatabaseName = $databaseName + RequestedServiceObjectiveName = "S0" +} +$database = New-AzSqlDatabase @databaseParams + +Start-Sleep -second 600 + +# Restore database to its state 7 minutes ago +# Note: Point-in-time restore requires database to be at least 5 minutes old +$restoreParams = @{ + FromPointInTimeBackup = $true + PointInTime = (Get-Date).AddMinutes(-7) + ResourceGroupName = $resourceGroupName + ServerName = $serverName + TargetDatabaseName = $pointInTimeRestoreDatabaseName + ResourceId = $database.ResourceID + Edition = "Standard" + ServiceObjectiveName = "S0" +} +Restore-AzSqlDatabase @restoreParams + +# Note: For performing geo-restore for a managed instance database, use -FromGeoBackup parameter with restore. +# Sample script: Restore-AzSqlDatabase -FromGeoBackup -ResourceGroupName "TargetResourceGroup" -ServerName "TargetServer" -TargetDatabaseName "RestoredDatabase" -ResourceId $geoBackup.ResourceID -Edition "Standard" -RequestedServiceObjectiveName "S2" + +# Clean up deployment +# Remove-AzResourceGroup -ResourceGroupName $resourceGroupName +# diff --git a/azure-sql/database/setup-geodr-and-failover/setup-geodr-and-failover-elastic-pool-az-ps.ps1 b/azure-sql/database/setup-geodr-and-failover/setup-geodr-and-failover-elastic-pool-az-ps.ps1 new file mode 100644 index 0000000..acf44a3 --- /dev/null +++ b/azure-sql/database/setup-geodr-and-failover/setup-geodr-and-failover-elastic-pool-az-ps.ps1 @@ -0,0 +1,139 @@ +# +# Connect-AzAccount +$subscriptionId = "" +# Set the resource group name and location for your server +$primaryResourceGroupName = "myPrimaryResourceGroup-$(Get-Random)" +$secondaryResourceGroupName = "mySecondaryResourceGroup-$(Get-Random)" +$primaryLocation = "westus2" +$secondaryLocation = "eastus" +# The logical server names have to be unique in the system +$primaryServerName = "primary-server-$(Get-Random)" +$secondaryServerName = "secondary-server-$(Get-Random)" +# Set an admin login and password for your servers +$adminSqlLogin = "" +$password = "" +# The sample database name +$databaseName = "mySampleDatabase" +# The IP address ranges that you want to allow to access your servers +$primaryStartIp = "0.0.0.0" +$primaryEndIp = "0.0.0.0" +$secondaryStartIp = "0.0.0.0" +$secondaryEndIp = "0.0.0.0" +# The elastic pool names +$primaryPoolName = "PrimaryPool" +$secondaryPoolName = "SecondaryPool" + +# Set subscription +Set-AzContext -SubscriptionId $subscriptionId + +# Create two new resource groups +$primaryResourceGroup = New-AzResourceGroup -Name $primaryResourceGroupName -Location $primaryLocation +$secondaryResourceGroup = New-AzResourceGroup -Name $secondaryResourceGroupName -Location $secondaryLocation + +# Create two new logical servers with a system-wide unique server name + +$adminCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminSqlLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force) + +$primaryServerParams = @{ + ResourceGroupName = $primaryResourceGroupName + ServerName = $primaryServerName + Location = $primaryLocation + SqlAdministratorCredentials = $adminCredential +} +$primaryServer = New-AzSqlServer @primaryServerParams + +$secondaryServerParams = @{ + ResourceGroupName = $secondaryResourceGroupName + ServerName = $secondaryServerName + Location = $secondaryLocation + SqlAdministratorCredentials = $adminCredential +} +$secondaryServer = New-AzSqlServer @secondaryServerParams + +# Create a server firewall rule for each server that allows access from the specified IP range +$primaryFirewallParams = @{ + ResourceGroupName = $primaryResourceGroupName + ServerName = $primaryServerName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $primaryStartIp + EndIpAddress = $primaryEndIp +} +$primaryServerFirewallRule = New-AzSqlServerFirewallRule @primaryFirewallParams + +$secondaryFirewallParams = @{ + ResourceGroupName = $secondaryResourceGroupName + ServerName = $secondaryServerName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $secondaryStartIp + EndIpAddress = $secondaryEndIp +} +$secondaryServerFirewallRule = New-AzSqlServerFirewallRule @secondaryFirewallParams + +# Create a pool in each of the servers +$primaryPoolParams = @{ + ResourceGroupName = $primaryResourceGroupName + ServerName = $primaryServerName + ElasticPoolName = $primaryPoolName + Edition = "Standard" + Dtu = 50 + DatabaseDtuMin = 10 + DatabaseDtuMax = 50 +} +$primaryPool = New-AzSqlElasticPool @primaryPoolParams + +$secondaryPoolParams = @{ + ResourceGroupName = $secondaryResourceGroupName + ServerName = $secondaryServerName + ElasticPoolName = $secondaryPoolName + Edition = "Standard" + Dtu = 50 + DatabaseDtuMin = 10 + DatabaseDtuMax = 50 +} +$secondaryPool = New-AzSqlElasticPool @secondaryPoolParams + +# Create a blank database in the pool on the primary server +$databaseParams = @{ + ResourceGroupName = $primaryResourceGroupName + ServerName = $primaryServerName + DatabaseName = $databaseName + ElasticPoolName = $primaryPoolName +} +$database = New-AzSqlDatabase @databaseParams + +# Establish Active Geo-Replication +$primaryDatabaseParams = @{ + ResourceGroupName = $primaryResourceGroupName + ServerName = $primaryServerName + DatabaseName = $databaseName +} +$database = Get-AzSqlDatabase @primaryDatabaseParams +$secondaryParams = @{ + PartnerResourceGroupName = $secondaryResourceGroupName + PartnerServerName = $secondaryServerName + SecondaryElasticPoolName = $secondaryPoolName + AllowConnections = "All" +} +$database | New-AzSqlDatabaseSecondary @secondaryParams + +# Initiate a planned failover +$secondaryDatabaseParams = @{ + ResourceGroupName = $secondaryResourceGroupName + ServerName = $secondaryServerName + DatabaseName = $databaseName +} +$database = Get-AzSqlDatabase @secondaryDatabaseParams +$database | Set-AzSqlDatabaseSecondary -PartnerResourceGroupName $primaryResourceGroupName -Failover + +# Monitor Geo-Replication config and health after failover +$database = Get-AzSqlDatabase @secondaryDatabaseParams +$replicationLinkParams = @{ + PartnerResourceGroupName = $primaryResourceGroupName + PartnerServerName = $primaryServerName +} +$database | Get-AzSqlDatabaseReplicationLink @replicationLinkParams + +# Clean up deployment +# Remove-AzResourceGroup -ResourceGroupName $primaryResourceGroupName +# Remove-AzResourceGroup -ResourceGroupName $secondaryResourceGroupName +# diff --git a/azure-sql/database/setup-geodr-and-failover/setup-geodr-and-failover-single-database-az-ps.ps1 b/azure-sql/database/setup-geodr-and-failover/setup-geodr-and-failover-single-database-az-ps.ps1 new file mode 100644 index 0000000..37f797e --- /dev/null +++ b/azure-sql/database/setup-geodr-and-failover/setup-geodr-and-failover-single-database-az-ps.ps1 @@ -0,0 +1,98 @@ +# +# Connect-AzAccount +$subscriptionId = "" +# Set the resource group name and location for your primary server +$primaryResourceGroupName = "myPrimaryResourceGroup-$(Get-Random)" +$primaryLocation = "westus2" +# Set the resource group name and location for your secondary server +$secondaryResourceGroupName = "mySecondaryResourceGroup-$(Get-Random)" +$secondaryLocation = "eastus" +# Set an admin login and password for your servers +$adminSqlLogin = "" +$password = "" +# Set server names - the logical server names have to be unique in the system +$primaryServerName = "primary-server-$(Get-Random)" +$secondaryServerName = "secondary-server-$(Get-Random)" +# The sample database name +$databaseName = "mySampleDatabase" +# The IP address range that you want to allow to access your servers +$primaryStartIp = "0.0.0.0" +$primaryEndIp = "0.0.0.0" +$secondaryStartIp = "0.0.0.0" +$secondaryEndIp = "0.0.0.0" + +# Set subscription +Set-AzContext -SubscriptionId $subscriptionId + +# Create two new resource groups +$primaryResourceGroup = New-AzResourceGroup -Name $primaryResourceGroupName -Location $primaryLocation +$secondaryResourceGroup = New-AzResourceGroup -Name $secondaryResourceGroupName -Location $secondaryLocation + +# Create two new logical servers with a system-wide unique server name +$adminCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminSqlLogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force) + +$primaryServerParams = @{ + ResourceGroupName = $primaryResourceGroupName + ServerName = $primaryServerName + Location = $primaryLocation + SqlAdministratorCredentials = $adminCredential +} +$primaryServer = New-AzSqlServer @primaryServerParams + +$secondaryServerParams = @{ + ResourceGroupName = $secondaryResourceGroupName + ServerName = $secondaryServerName + Location = $secondaryLocation + SqlAdministratorCredentials = $adminCredential +} +$secondaryServer = New-AzSqlServer @secondaryServerParams + +# Create a server firewall rule for each server that allows access from the specified IP range +$primaryFirewallParams = @{ + ResourceGroupName = $primaryResourceGroupName + ServerName = $primaryServerName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $primaryStartIp + EndIpAddress = $primaryEndIp +} +$primaryServerFirewallRule = New-AzSqlServerFirewallRule @primaryFirewallParams + +$secondaryFirewallParams = @{ + ResourceGroupName = $secondaryResourceGroupName + ServerName = $secondaryServerName + FirewallRuleName = "AllowedIPs" + StartIpAddress = $secondaryStartIp + EndIpAddress = $secondaryEndIp +} +$secondaryServerFirewallRule = New-AzSqlServerFirewallRule @secondaryFirewallParams + +# Create a blank database with S0 performance level on the primary server +$databaseParams = @{ + ResourceGroupName = $primaryResourceGroupName + ServerName = $primaryServerName + DatabaseName = $databaseName + RequestedServiceObjectiveName = "S0" +} +$database = New-AzSqlDatabase @databaseParams + +# Establish Active Geo-Replication +$database = Get-AzSqlDatabase -DatabaseName $databaseName -ResourceGroupName $primaryResourceGroupName -ServerName $primaryServerName +$database | New-AzSqlDatabaseSecondary -PartnerResourceGroupName $secondaryResourceGroupName -PartnerServerName $secondaryServerName -AllowConnections "All" + +# Initiate a planned failover +$database = Get-AzSqlDatabase -DatabaseName $databaseName -ResourceGroupName $secondaryResourceGroupName -ServerName $secondaryServerName +$database | Set-AzSqlDatabaseSecondary -PartnerResourceGroupName $primaryResourceGroupName -Failover + +# Monitor Geo-Replication config and health after failover +$database = Get-AzSqlDatabase -DatabaseName $databaseName -ResourceGroupName $secondaryResourceGroupName -ServerName $secondaryServerName +$database | Get-AzSqlDatabaseReplicationLink -PartnerResourceGroupName $primaryResourceGroupName -PartnerServerName $primaryServerName + +# Remove the replication link after the failover +$database = Get-AzSqlDatabase -DatabaseName $databaseName -ResourceGroupName $secondaryResourceGroupName -ServerName $secondaryServerName +$secondaryLink = $database | Get-AzSqlDatabaseReplicationLink -PartnerResourceGroupName $primaryResourceGroupName -PartnerServerName $primaryServerName +$secondaryLink | Remove-AzSqlDatabaseSecondary + +# Clean up deployment +#Remove-AzResourceGroup -ResourceGroupName $primaryResourceGroupName +#Remove-AzResourceGroup -ResourceGroupName $secondaryResourceGroupName +# diff --git a/azure-sql/managed-instance/transparent-data-encryption/setup-tde-byok-sqlmi-az-ps.ps1 b/azure-sql/managed-instance/transparent-data-encryption/setup-tde-byok-sqlmi-az-ps.ps1 new file mode 100644 index 0000000..62c7520 --- /dev/null +++ b/azure-sql/managed-instance/transparent-data-encryption/setup-tde-byok-sqlmi-az-ps.ps1 @@ -0,0 +1,90 @@ +# +# You will need an existing Managed Instance as a prerequisite for completing this script. +# See https://docs.microsoft.com/en-us/azure/sql-database/scripts/sql-database-create-configure-managed-instance-powershell + +# Log in to your Azure account: +Connect-AzAccount + +# If there are multiple subscriptions, choose the one where AKV is created: +Set-AzContext -SubscriptionId "" + +# Install the Az.Sql PowerShell package if you are running this PowerShell locally (uncomment below): +# Install-Module -Name Az.Sql + +# 1. Create resource and set up Azure Key Vault (skip if already done) + +# Create resource group (name the resource and specify the location) +$location = "westus2" # specify the location +$resourcegroup = "MyRG" # specify a new RG name +New-AzResourceGroup -Name $resourcegroup -Location $location + +# Create new Azure Key Vault with a globally unique VaultName and soft-delete option turned on: +$vaultname = "MyKeyVault" # specify a globally unique VaultName +New-AzKeyVault -VaultName $vaultname -ResourceGroupName $resourcegroup -Location $location + +# Authorize Managed Instance to use the AKV (wrap/unwrap key and get public part of key, if public part exists): +$assignIdentityParams = @{ + ResourceGroupName = $resourcegroup + Name = "MyManagedInstance" + AssignIdentity = $true +} +$objectid = (Set-AzSqlInstance @assignIdentityParams).Identity.PrincipalId +$accessPolicyParams = @{ + BypassObjectIdValidation = $true + VaultName = $vaultname + ObjectId = $objectid + PermissionsToKeys = "get", "wrapKey", "unwrapKey" +} +Set-AzKeyVaultAccessPolicy @accessPolicyParams + +# Allow access from trusted Azure services: +Update-AzKeyVaultNetworkRuleSet -VaultName $vaultname -Bypass AzureServices + +# Allow access from your client IP address(es) to be able to complete remaining steps: +Update-AzKeyVaultNetworkRuleSet -VaultName $vaultname -IpAddressRange "" + +# Turn the network rules ON by setting the default action to Deny: +Update-AzKeyVaultNetworkRuleSet -VaultName $vaultname -DefaultAction Deny + +# 2. Provide TDE Protector key (skip if already done) + +# First, give yourself necessary permissions on the AKV, (specify your account instead of contoso.com): +$selfAccessPolicyParams = @{ + VaultName = $vaultname + UserPrincipalName = "myaccount@contoso.com" + PermissionsToKeys = "create", "import", "get", "list" +} +Set-AzKeyVaultAccessPolicy @selfAccessPolicyParams + +# The recommended way is to import an existing key from a .pfx file. Replace "" with the actual password below: +$keypath = "c:\some_path\mytdekey.pfx" # Supply your .pfx path and name +$securepfxpwd = ConvertTo-SecureString -String "" -AsPlainText -Force +$addKeyParams = @{ + VaultName = $vaultname + Name = "MyTDEKey" + KeyFilePath = $keypath + KeyFilePassword = $securepfxpwd +} +$key = Add-AzKeyVaultKey @addKeyParams + +# ...or get an existing key from the vault: +# $key = Get-AzKeyVaultKey -VaultName $vaultname -Name "MyTDEKey" + +# Alternatively, generate a new key directly in Azure Key Vault (recommended for test purposes only - uncomment below): +# $key = Add-AzureKeyVaultKey -VaultName $vaultname -Name MyTDEKey -Destination Software -Size 2048 + +# 3. Set up BYOK TDE on Managed Instance: + +# Assign the key to the Managed Instance: +# $key = 'https://contoso.vault.azure.net/keys/contosokey/' +Add-AzSqlInstanceKeyVaultKey -KeyId $key.id -InstanceName "MyManagedInstance" -ResourceGroupName $resourcegroup + +# Set TDE operation mode to BYOK: +$tdeProtectorParams = @{ + Type = "AzureKeyVault" + InstanceName = "MyManagedInstance" + ResourceGroup = $resourcegroup + KeyId = $key.id +} +Set-AzSqlInstanceTransparentDataEncryptionProtector @tdeProtectorParams +#