PowerShell: Create a Virtual Service endpoint and VNet rule for Azure SQL Database
Applies to: Azure SQL Database
Virtual network rules are one firewall security feature that controls whether the logical SQL server for your Azure SQL Database databases, elastic pools, or databases in Azure Synapse accept communications that are sent from particular subnets in virtual networks.
Important
This article applies to Azure SQL Database, including Azure Synapse (formerly SQL DW). For simplicity, the term Azure SQL Database in this article applies to databases belonging to either Azure SQL Database or Azure Synapse. This article does not apply to Azure SQL Managed Instance because it does not have a service endpoint associated with it.
This article demonstrates a PowerShell script that takes the following actions:
- Creates a Azure Virtual Service endpoint on your subnet.
- Adds the endpoint to the firewall of your server, to create a virtual network rule.
For more background, see Virtual Service endpoints for Azure SQL Database.
Tip
If all you need is to assess or add the Virtual Service endpoint type name for Azure SQL Database to your subnet, you can skip ahead to our more direct PowerShell script.
Note
This article uses the Azure Az PowerShell module, which is the recommended PowerShell module for interacting with Azure. To get started with the Az PowerShell module, see Install Azure PowerShell. To learn how to migrate to the Az PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.
Important
The PowerShell Azure Resource Manager module is still supported by Azure SQL Database, but all future development is for the Az.Sql
Cmdlets. For the older module, see AzureRM.Sql. The arguments for the commands in the Az module and in the AzureRm modules are substantially identical.
Major cmdlets
This article emphasizes the New-AzSqlServerVirtualNetworkRule cmdlet that adds the subnet endpoint to the access control list (ACL) of your server, thereby creating a rule.
The following list shows the sequence of other major cmdlets that you must run to prepare for your call to New-AzSqlServerVirtualNetworkRule. In this article, these calls occur in script 3 "Virtual network rule":
- New-AzVirtualNetworkSubnetConfig: Creates a subnet object.
- New-AzVirtualNetwork: Creates your virtual network, giving it the subnet.
- Set-AzVirtualNetworkSubnetConfig: Assigns a Virtual Service endpoint to your subnet.
- Set-AzVirtualNetwork: Persists updates made to your virtual network.
- New-AzSqlServerVirtualNetworkRule: After your subnet is an endpoint, adds your subnet as a virtual network rule, into the ACL of your server.
- This cmdlet Offers the parameter -IgnoreMissingVNetServiceEndpoint, starting in Azure RM PowerShell Module version 5.1.1.
Prerequisites for running PowerShell
- You can already log in to Azure, such as through the Azure portal.
- You can already run PowerShell scripts.
Note
Please ensure that service endpoints are turned on for the VNet/Subnet that you want to add to your Server otherwise creation of the VNet Firewall Rule will fail.
One script divided into four chunks
Our demonstration PowerShell script is divided into a sequence of smaller scripts. The division eases learning and provides flexibility. The scripts must be run in their indicated sequence. If you do not have time now to run the scripts, our actual test output is displayed after script 4.
Script 1: Variables
This first PowerShell script assigns values to variables. The subsequent scripts depend on these variables.
Important
Before you run this script, you can edit the values, if you like. For example, if you already have a resource group, you might want to edit your resource group name as the assigned value.
Your subscription name should be edited into the script.
PowerShell script 1 source code
######### Script 1 ########################################
## LOG into to your Azure account. ##
## (Needed only one time per powershell.exe session.) ##
###########################################################
$yesno = Read-Host 'Do you need to log into Azure (only one time per powershell.exe session)? [yes/no]'
if ('yes' -eq $yesno) { Connect-AzAccount -Environment AzureChinaCloud }
###########################################################
## Assignments to variables used by the later scripts. ##
###########################################################
# You can edit these values, if necessary.
$SubscriptionName = 'yourSubscriptionName'
Select-AzSubscription -SubscriptionName $SubscriptionName
$ResourceGroupName = 'RG-YourNameHere'
$Region = 'chinaeast2'
$VNetName = 'myVNet'
$SubnetName = 'mySubnet'
$VNetAddressPrefix = '10.1.0.0/16'
$SubnetAddressPrefix = '10.1.1.0/24'
$VNetRuleName = 'myFirstVNetRule-ForAcl'
$SqlDbServerName = 'mysqldbserver-forvnet'
$SqlDbAdminLoginName = 'ServerAdmin'
$SqlDbAdminLoginPassword = 'ChangeYourAdminPassword1'
$ServiceEndpointTypeName_SqlDb = 'Microsoft.Sql' # Official type name.
Write-Host 'Completed script 1, the "Variables".'
Script 2: Prerequisites
This script prepares for the next script, where the endpoint action is. This script creates for you the following listed items, but only if they do not already exist. You can skip script 2 if you are sure these items already exist:
- Azure resource group
- Logical SQL server
PowerShell script 2 source code
######### Script 2 ########################################
## Ensure your Resource Group already exists. ##
###########################################################
Write-Host "Check whether your Resource Group already exists."
$gottenResourceGroup = $null
$gottenResourceGroup = Get-AzResourceGroup -Name $ResourceGroupName -ErrorAction SilentlyContinue
if ($null -eq $gottenResourceGroup) {
Write-Host "Creating your missing Resource Group - $ResourceGroupName."
New-AzResourceGroup -Name $ResourceGroupName -Location $Region
} else {
Write-Host "Good, your Resource Group already exists - $ResourceGroupName."
}
$gottenResourceGroup = $null
###########################################################
## Ensure your server already exists. ##
###########################################################
Write-Host "Check whether your server already exists."
$sqlDbServer = $null
$azSqlParams = @{
ResourceGroupName = $ResourceGroupName
ServerName = $SqlDbServerName
ErrorAction = 'SilentlyContinue'
}
$sqlDbServer = Get-AzSqlServer @azSqlParams
if ($null -eq $sqlDbServer) {
Write-Host "Creating the missing server - $SqlDbServerName."
Write-Host "Gather the credentials necessary to next create a server."
$sqlAdministratorCredentials = [pscredential]::new($SqlDbAdminLoginName,(ConvertTo-SecureString -String $SqlDbAdminLoginPassword -AsPlainText -Force))
if ($null -eq $sqlAdministratorCredentials) {
Write-Host "ERROR, unable to create SQL administrator credentials. Now ending."
return
}
Write-Host "Create your server."
$sqlSrvParams = @{
ResourceGroupName = $ResourceGroupName
ServerName = $SqlDbServerName
Location = $Region
SqlAdministratorCredentials = $sqlAdministratorCredentials
}
New-AzSqlServer @sqlSrvParams
} else {
Write-Host "Good, your server already exists - $SqlDbServerName."
}
$sqlAdministratorCredentials = $null
$sqlDbServer = $null
Write-Host 'Completed script 2, the "Prerequisites".'
Script 3: Create an endpoint and a rule
This script creates a virtual network with a subnet. Then the script assigns the Microsoft.Sql endpoint type to your subnet. Finally the script adds your subnet to the access control list (ACL), thereby creating a rule.
PowerShell script 3 source code
######### Script 3 ########################################
## Create your virtual network, and give it a subnet. ##
###########################################################
Write-Host "Define a subnet '$SubnetName', to be given soon to a virtual network."
$subnetParams = @{
Name = $SubnetName
AddressPrefix = $SubnetAddressPrefix
ServiceEndpoint = $ServiceEndpointTypeName_SqlDb
}
$subnet = New-AzVirtualNetworkSubnetConfig @subnetParams
Write-Host "Create a virtual network '$VNetName'.`nGive the subnet to the virtual network that we created."
$vnetParams = @{
Name = $VNetName
AddressPrefix = $VNetAddressPrefix
Subnet = $subnet
ResourceGroupName = $ResourceGroupName
Location = $Region
}
$vnet = New-AzVirtualNetwork @vnetParams
###########################################################
## Create a Virtual Service endpoint on the subnet. ##
###########################################################
Write-Host "Assign a Virtual Service endpoint 'Microsoft.Sql' to the subnet."
$vnetSubParams = @{
Name = $SubnetName
AddressPrefix = $SubnetAddressPrefix
VirtualNetwork = $vnet
ServiceEndpoint = $ServiceEndpointTypeName_SqlDb
}
$vnet = Set-AzVirtualNetworkSubnetConfig @vnetSubParams
Write-Host "Persist the updates made to the virtual network > subnet."
$vnet = Set-AzVirtualNetwork -VirtualNetwork $vnet
$vnet.Subnets[0].ServiceEndpoints # Display the first endpoint.
###########################################################
## Add the Virtual Service endpoint Id as a rule, ##
## into SQL Database ACLs. ##
###########################################################
Write-Host "Get the subnet object."
$vnet = Get-AzVirtualNetwork -ResourceGroupName $ResourceGroupName -Name $VNetName
$subnet = Get-AzVirtualNetworkSubnetConfig -Name $SubnetName -VirtualNetwork $vnet
Write-Host "Add the subnet .Id as a rule, into the ACLs for your server."
$ruleParams = @{
ResourceGroupName = $ResourceGroupName
ServerName = $SqlDbServerName
VirtualNetworkRuleName = $VNetRuleName
VirtualNetworkSubnetId = $subnet.Id
}
New-AzSqlServerVirtualNetworkRule @ruleParams
Write-Host "Verify that the rule is in the SQL Database ACL."
$rule2Params = @{
ResourceGroupName = $ResourceGroupName
ServerName = $SqlDbServerName
VirtualNetworkRuleName = $VNetRuleName
}
Get-AzSqlServerVirtualNetworkRule @rule2Params
Write-Host 'Completed script 3, the "Virtual-Network-Rule".'
Script 4: Clean-up
This final script deletes the resources that the previous scripts created for the demonstration. However, the script asks for confirmation before it deletes the following:
- Logical SQL server
- Azure Resource Group
You can run script 4 any time after script 1 completes.
PowerShell script 4 source code
######### Script 4 ########################################
## Clean-up phase A: Unconditional deletes. ##
## ##
## 1. The test rule is deleted from SQL Database ACL. ##
## 2. The test endpoint is deleted from the subnet. ##
## 3. The test virtual network is deleted. ##
###########################################################
Write-Host "Delete the rule from the SQL Database ACL."
$removeParams = @{
ResourceGroupName = $ResourceGroupName
ServerName = $SqlDbServerName
VirtualNetworkRuleName = $VNetRuleName
ErrorAction = 'SilentlyContinue'
}
Remove-AzSqlServerVirtualNetworkRule @removeParams
Write-Host "Delete the endpoint from the subnet."
$vnet = Get-AzVirtualNetwork -ResourceGroupName $ResourceGroupName -Name $VNetName
Remove-AzVirtualNetworkSubnetConfig -Name $SubnetName -VirtualNetwork $vnet
Write-Host "Delete the virtual network (thus also deletes the subnet)."
$removeParams = @{
Name = $VNetName
ResourceGroupName = $ResourceGroupName
ErrorAction = 'SilentlyContinue'
}
Remove-AzVirtualNetwork @removeParams
###########################################################
## Clean-up phase B: Conditional deletes. ##
## ##
## These might have already existed, so user might ##
## want to keep. ##
## ##
## 1. Logical SQL server ##
## 2. Azure resource group ##
###########################################################
$yesno = Read-Host 'CAUTION !: Do you want to DELETE your server AND your resource group? [yes/no]'
if ('yes' -eq $yesno) {
Write-Host "Remove the server."
$removeParams = @{
ServerName = $SqlDbServerName
ResourceGroupName = $ResourceGroupName
ErrorAction = 'SilentlyContinue'
}
Remove-AzSqlServer @removeParams
Write-Host "Remove the Azure Resource Group."
Remove-AzResourceGroup -Name $ResourceGroupName -ErrorAction SilentlyContinue
} else {
Write-Host "Skipped over the DELETE of SQL Database and resource group."
}
Write-Host 'Completed script 4, the "Clean-Up".'
Verify your subnet is an endpoint
You might have a subnet that was already assigned the Microsoft.Sql type name, meaning it is already a Virtual Service endpoint. You could use the Azure portal to create a virtual network rule from the endpoint.
Or, you might be unsure whether your subnet has the Microsoft.Sql type name. You can run the following PowerShell script to take these actions:
- Ascertain whether your subnet has the Microsoft.Sql type name.
- Optionally, assign the type name if it is absent.
- The script asks you to confirm, before it applies the absent type name.
Phases of the script
Here are the phases of the PowerShell script:
- LOG into to your Azure account, needed only once per PS session. Assign variables.
- Search for your virtual network, and then for your subnet.
- Is your subnet tagged as Microsoft.Sql endpoint server type?
- Add a Virtual Service endpoint of type name Microsoft.Sql, on your subnet.
Important
Before you run this script, you must edit the values assigned to the $-variables, near the top of the script.
Direct PowerShell source code
This PowerShell script does not update anything, unless you respond yes if is asks you for confirmation. The script can add the type name Microsoft.Sql to your subnet. But the script tries the add only if your subnet lacks the type name.
### 1. LOG into to your Azure account, needed only once per PS session. Assign variables.
$yesno = Read-Host 'Do you need to log into Azure (only one time per powershell.exe session)? [yes/no]'
if ('yes' -eq $yesno) { Connect-AzAccount -Environment AzureChinaCloud }
# Assignments to variables used by the later scripts.
# You can EDIT these values, if necessary.
$SubscriptionName = 'yourSubscriptionName'
Select-AzSubscription -SubscriptionName "$SubscriptionName"
$ResourceGroupName = 'yourRGName'
$VNetName = 'yourVNetName'
$SubnetName = 'yourSubnetName'
$SubnetAddressPrefix = 'Obtain this value from the Azure portal.' # Looks roughly like: '10.0.0.0/24'
$ServiceEndpointTypeName_SqlDb = 'Microsoft.Sql' # Do NOT edit. Is official value.
### 2. Search for your virtual network, and then for your subnet.
# Search for the virtual network.
$vnet = $null
$vnet = Get-AzVirtualNetwork -ResourceGroupName $ResourceGroupName -Name $VNetName
if ($vnet -eq $null) {
Write-Host "Caution: No virtual network found by the name '$VNetName'."
return
}
$subnet = $null
for ($nn = 0; $nn -lt $vnet.Subnets.Count; $nn++) {
$subnet = $vnet.Subnets[$nn]
if ($subnet.Name -eq $SubnetName) { break }
$subnet = $null
}
if ($null -eq $subnet) {
Write-Host "Caution: No subnet found by the name '$SubnetName'"
Return
}
### 3. Is your subnet tagged as 'Microsoft.Sql' endpoint server type?
$endpointMsSql = $null
for ($nn = 0; $nn -lt $subnet.ServiceEndpoints.Count; $nn++) {
$endpointMsSql = $subnet.ServiceEndpoints[$nn]
if ($endpointMsSql.Service -eq $ServiceEndpointTypeName_SqlDb) {
$endpointMsSql
break
}
$endpointMsSql = $null
}
if ($null -eq $endpointMsSql) {
Write-Host "Good: Subnet found, and is already tagged as an endpoint of type '$ServiceEndpointTypeName_SqlDb'."
return
} else {
Write-Host "Caution: Subnet found, but not yet tagged as an endpoint of type '$ServiceEndpointTypeName_SqlDb'."
# Ask the user for confirmation.
$yesno = Read-Host 'Do you want the PS script to apply the endpoint type name to your subnet? [yes/no]'
if ('no' -eq $yesno) { return }
}
### 4. Add a Virtual Service endpoint of type name 'Microsoft.Sql', on your subnet.
$setParams = @{
Name = $SubnetName
AddressPrefix = $SubnetAddressPrefix
VirtualNetwork = $vnet
ServiceEndpoint = $ServiceEndpointTypeName_SqlDb
}
$vnet = Set-AzVirtualNetworkSubnetConfig @setParams
# Persist the subnet update.
$vnet = Set-AzVirtualNetwork -VirtualNetwork $vnet
for ($nn = 0; $nn -lt $vnet.Subnets.Count; $nn++) {
$vnet.Subnets[0].ServiceEndpoints # Display.
}