Tutorial: usando automação para configurar o administrador do Microsoft Entra para SQL Server
Artigo
Aplica-se a: SQL Server 2022 (16.x)
Observação
Esse recurso está disponível no SQL Server 2022 (16.x) ou em versões posteriores e só tem suporte no SQL Server local para hosts Windows e Linux e SQL Server 2022 em VMs do Windows Azure.
Neste artigo, veremos como configurar o administrador do Microsoft Entra para permitir autenticação com o Microsoft Entra ID (anteriormente Azure Active Directory) para SQL Server usando o portal do Azure e APIs como:
Embora o Microsoft Entra ID seja o novo nome do Azure Active Directory (Azure AD), para evitar a interrupção de ambientes existentes, o Azure AD ainda permanecerá em alguns elementos codificados, como campos de interface do usuário, provedores de conexão, códigos de erro e cmdlets. Neste artigo, os dois nomes são intercambiáveis.
Preparação antes de definir o administrador do Microsoft Entra
As permissões a seguir são necessárias para configurar o administrador do Microsoft Entra nos recursos SQL Server – Azure Arc e cofre de chaves.
Configurar permissões para o Azure Arc
Siga o guia para verificar se o SQL Server está conectado ao Azure Arc. O usuário que configura o administrador do Microsoft Entra para o recurso SQL Server – Azure Arc deve ter a função Colaborador para o servidor.
Selecione SQL Server – Azure Arc e escolha a instância do host do SQL Server.
Selecione IAM (Controle de acesso) .
Selecione Adicionar>Adicionar atribuição de função para adicionar a função Colaborador ao usuário que configura o administrador do Microsoft Entra.
Configurar permissões para o Azure Key Vault
Crie um Azure Key Vault, se ainda não tiver um. O usuário que está configurando o administrador do Microsoft Entra deve ter a função Colaborador no Azure Key Vault. Para adicionar uma função a um usuário no Azure Key Vault:
Selecione Adicionar>Adicionar atribuição de função para adicionar a função Colaborador ao usuário que configura o administrador do Microsoft Entra.
Configurar políticas de acesso para o host do SQL Server
No portal do Azure, navegue até a instância do Azure Key Vault e selecione Políticas de acesso.
Selecione Adicionar Política de Acesso.
Para Permissões de chave, use Assinar.
Selecione Permissões de segredo e escolha Obter e Listar.
Em Permissões de certificado, escolha Obter e Listar.
Selecione Avançar.
Na página Entidade de segurança, pesquise o nome do seu computador - instância do Azure Arc, que é o nome do host do SQL Server.
Ignore a páginaAplicativo (opcional) selecionando duas vezes Avançar ou selecionando Analisar + criar.
Verifique se a "ID de objeto" da Entidade de segurança corresponde à ID de entidade de segurança da identidade gerenciada atribuída à instância.
Para confirmar, vá para a página de recursos e selecione Exibição JSON no canto superior direito da caixa Essenciais na página de Visão geral. Em identidade, você encontrará o principalId.
Selecione Criar.
Você deve selecionar Criar para garantir que as permissões sejam aplicadas. Para garantir que as permissões tenham sido armazenadas, atualize a janela do navegador e verifique se a linha da instância do Azure Arc ainda está presente.
Definir políticas de acesso para usuários do Microsoft Entra
No portal do Azure, navegue até a instância do Azure Key Vault e selecione Políticas de acesso.
Selecione Adicionar Política de Acesso.
Em Permissões de chave, escolha Obter, Listar e Criar.
Selecione Permissões de segredo e escolha Obter, Listar e Definir.
Em Permissões de certificado, escolha Obter, Listar e Criar.
Em Selecionar entidade de segurança, adicione o usuário do Microsoft Entra que você quer usar para se conectar ao SQL Server.
Selecione Adicionar e, em seguida, Salvar.
Configurando o administrador do Microsoft Entra para SQL Server
Com as novas APIs e a funcionalidade do portal, os usuários podem configurar um administrador do Microsoft Entra para SQL Server sem criar um certificado do Azure e um aplicativo do Microsoft Entra separadamente. Selecione uma guia para saber como configurar um administrador do Microsoft Entra para seu SQL Server conectado ao Azure Arc com criação automática de certificados e aplicativos.
Use o portal do Azure para configurar um administrador do Microsoft Entra, crie um certificado do Azure Key Vault e um aplicativo do Microsoft Entra no mesmo processo. Isso é necessário para usar a autenticação do Microsoft Entra com o SQL Server.
Selecione Microsoft Entra ID e Purview no menu Configurações do menu de recursos.
Selecione Definir Administrador para abrir o painel do Microsoft Entra ID e escolha uma conta que será adicionada como logon de administrador ao SQL Server.
Selecione Certificado de gerenciamento de Serviços.
Selecione Alterar cofre de chaves e selecione seu recurso do Azure Key Vault existente.
Escolha Registro de aplicativo gerenciado pelo serviço.
Selecione Salvar. Isso envia uma solicitação ao agente do servidor do Arc que configura a autenticação do Microsoft Entra para a instância do SQL Server. A operação pode levar vários minutos para ser concluída; aguarde até que o processo de salvamento seja confirmado com Saved successfully antes de tentar fazer logon no Microsoft Entra.
O registro de aplicativo gerenciado pelo serviço faz o seguinte para você:
Cria um certificado no cofre de chaves com um nome na forma <hostname>-<instanceName><uniqueNumber>.
Cria um aplicativo do Microsoft Entra com um nome como <hostname>-<instanceName><uniqueNumber> e atribui as permissões necessárias ao aplicativo. Veja mais informações em Conceder permissões de aplicativo
Atribui o novo certificado do Azure Key Vault ao aplicativo.
Salve as configurações no Azure Arc.
Observação
Os certificados criados para o Microsoft Entra não são alternados automaticamente. Os clientes podem fornecer o próprio certificado e aplicativo para configuração do administrador do Microsoft Entra. Veja mais informações no Tutorial: configurar a autenticação do Microsoft Entra para o SQL Server.
Az.ConnectedMachine 0.5.1 ou posterior é obrigatório
Para instalar o módulo Az.ConnectedMachine, use az extension add --name ConnectedMachine. Para verificar a versão da CLI do Azure instalada, use az version.
Os seguintes parâmetros de entrada são usados no script da CLI do Azure:
<applicationName>: nome do aplicativo que será criado
<certSubjectName>: nome do certificado que será criado
<keyVaultName>: o nome do cofre de chaves. Esse cofre de chaves deve ser criado antes da execução do script
<machineName>: nome do computador do host do SQL Server
<resourceGroupName>: nome do grupo de recursos que contém a instância SQL Server – Azure Arc
<adminAccountName>: conta do administrador do Microsoft Entra que você quer definir para o SQL Server
<instanceName>: parâmetro opcional para instâncias nomeadas do SQL Server. Use esse parâmetro quando tiver uma instância nomeada. Se ele for omitido, será usado nome padrão MSSQLSERVER
<tenantId>: parâmetro opcional para ID do locatário. Você pode encontrar a ID do locatário acessando o portal do Azure e o recurso Microsoft Entra ID. No painel de Visão geral, você precisa ver sua ID de Locatário. Se omitida, será usada a ID do locatário padrão como parâmetro
<subscriptionId>: parâmetro opcional para ID da assinatura. Sua ID da assinatura pode ser encontrada no portal do Azure. Se omitida, será usada a ID da assinatura padrão
Para usar o script da CLI do Azure abaixo, salve o script como arquivo .ps1 e execute este comando:
Para o SQL Server em computadores host do Linux, substitua WindowsAgent.SqlServer por LinuxAgent.SqlServer no script.
# AZ CLI and AZ CLI's connected machine extension must be installed before running this script
param (
[Parameter(mandatory=$true)] $applicationName,
[Parameter(mandatory=$true)] $certSubjectName,
[Parameter(mandatory=$true)] $keyVaultName,
[Parameter(mandatory=$true)] $machineName,
[Parameter(mandatory=$true)] $resourceGroupName,
[Parameter(mandatory=$true)] $adminAccountName,
$instanceName,
$tenantId,
$subscriptionId
)
# Constants
#
$NUMRETRIES = 60
# Helper functions
#
function ConvertFrom-StringArray {
param (
[string[]] $stringArray
)
if (!$stringArray)
{
return $null
}
else
{
return ConvertFrom-JSON ($stringArray -join "`n")
}
}
# Check parameters
#
if ([string]::IsNullOrEmpty($instanceName))
{
Write-Host "Warning: SQL Instance name (-instanceName) not provided. Default of MSSQLSERVER will be used"
$instanceName = "MSSQLSERVER"
}
$tenantIdArgument = ""
if ([string]::IsNullOrEmpty($tenantId))
{
Write-Host "Warning: Tenant ID (-tenantId) not supplied to the script, so default tenant is being used"
}
else
{
$tenantIdArgument = "-TenantId '" + $tenantId + "'"
}
$subscriptionIdArgument = ""
if ([string]::IsNullOrEmpty($subscriptionId))
{
Write-Host "Warning: Subscription ID (-subscriptionId) not supplied to the script, so default subscription is being used"
}
else
{
$subscriptionIdArgument = "-SubscriptionId '" + $subscriptionId + "'"
}
# Login and select subscription
#
$login = az login --tenant $tenantId --use-device-code
if (!$login)
{
Write-Error "Login to Azure AD failed. Exiting."
exit 1
}
if ($subscriptionId)
{
az account set -s $subscriptionId
}
$accountInfo = ConvertFrom-StringArray (az account show)
if (!$accountInfo)
{
Write-Error "Cannot query logged in Azure AD account. Check that 'az login' and 'az account set' succeeded"
exit 1
}
if ($subscriptionId)
{
if ($subscriptionId.ToLower() -ne $accountInfo.id.ToLower())
{
Write-Error "Could not select the desired subscription"
exit 1
}
}
else
{
$subscriptionId = $accountInfo.id
}
# Check AKV path exists
#
$keyVault = ConvertFrom-StringArray (az keyvault show --name $keyVaultName)
if (!$keyVault)
{
Write-Error "Azure key vault '$keyVaultName' does not exist"
exit 1
}
# Check certificate doesn't exist
#
$cert = ConvertFrom-StringArray (az keyvault certificate show --name $certSubjectName --vault-name $keyVaultName 2>$null)
if ($cert)
{
Write-Error "Certificate '$certSubjectName' already exists in key vault '$keyVaultName'"
exit 1
}
# Check app registration doesn't exist
#
$applications = ConvertFrom-StringArray (az ad app list --display-name $applicationName --only-show-errors)
if ($applications.length -gt 0)
{
Write-Error "App registration with name '$applicationName' already exists"
exit 1
}
# Check Arc SQL instance is valid
#
$extension = ConvertFrom-StringArray (az connectedmachine extension show --machine-name $machineName --name "WindowsAgent.SqlServer" --resource-group $resourceGroupName)
if (!$extension)
{
Write-Error "SQL Server Arc Server not found for machine '$machineName' in resource group '$resourceGroupName'"
exit 1
}
$arcServicePrincipals = ConvertFrom-StringArray(az ad sp list --display-name $machineName --only-show-errors)
if (!$arcServicePrincipals -or $arcServicePrincipals.length -eq 0)
{
Write-Error "Could not find a service principal account with the name '$machineName'"
exit 1
}
else
{
$principalFound = $false
for ($i = 0; $i -lt $arcServicePrincipals.length; $i++)
{
if ($arcServicePrincipals[$i].displayName.toLower() -eq $machineName.toLower()) {
if ($principalFound) {
Write-Error "Could not find exactly one service principal account with the name '$machineName'"
exit 1
}
$arcServicePrincipal = $arcServicePrincipals[$i]
$principalFound = $true
}
}
if (!$principalFound) {
Write-Error "Could not find a service principal account with the name '$machineName'"
exit 1
}
}
# Check if admin account exists
#
$adminAccount = ConvertFrom-StringArray (az ad user show --id $adminAccountName --only-show-errors 2>$null)
$adminAccountType = 0
if (!$adminAccount)
{
$adminAccounts = ConvertFrom-StringArray (az ad user list --filter "mail eq '$adminAccountName'" --only-show-errors 2>$null)
if ($adminAccounts -and $adminAccounts.length -gt 0)
{
if ($adminAccounts.length -eq 1)
{
$adminAccount = $adminAccounts[0]
}
else
{
Write-Error "Multiple Azure AD accounts found with identifier '$adminAccountName'"
exit 1
}
}
else
{
$adminAccount = ConvertFrom-StringArray (az ad group show --group $adminAccountName --only-show-errors 2>$null)
if (!$adminAccount)
{
$adminAccounts = ConvertFrom-StringArray (az ad app list --display-name $adminAccountName --only-show-errors 2>$null)
if ($adminAccounts -and $adminAccounts.length -gt 0)
{
if ($adminAccounts.length -eq 1)
{
$adminAccount = $adminAccounts[0]
}
else
{
Write-Error "Multiple Azure AD applications found with identifier '$adminAccountName'"
exit 1
}
}
else
{
Write-Error "Admin account not found"
exit 1
}
}
else
{
$adminAccountType = 1
}
}
}
if ($adminAccount)
{
$adminAccountSid = $adminAccount.id
}
else
{
Write-Error "Admin account not found"
exit 1
}
# Create certificate in AKV
#
$keyVaultPolicy = ConvertFrom-StringArray (az keyvault certificate get-default-policy)
if (!$keyVaultPolicy)
{
Write-Error "Could not get default key vault policy"
exit 1
}
$keyVaultPolicy.x509CertificateProperties.subject = "CN=" + $certSubjectName
$policyString = (ConvertTo-JSON -Depth 8 $keyVaultPolicy).replace("`r`n", "")
$escapedPolicyString = $policyString.replace("`"", "\`"")
$cert = ConvertFrom-StringArray (az keyvault certificate create --vault-name $keyVaultName --name $certSubjectName --policy $escapedPolicyString)
if (!$cert)
{
Write-Error "Failed to create certificate '$certSubjectName'"
exit 1
}
# Wait until cert is created?
#
$cert = ConvertFrom-StringArray (az keyvault certificate show --vault-name $keyVaultName --name $certSubjectName)
for (($i = 0); $i -lt $NUMRETRIES -and (!$cert -or !$cert.attributes.enabled); $i++)
{
$cert = ConvertFrom-StringArray (az keyvault certificate show --vault-name $keyVaultName --name $certSubjectName)
if (!$cert -or !$cert.attributes.enabled)
{
Start-Sleep -Seconds 5
}
}
# Allow Arc to access AKV
#
$newPerms = ConvertFrom-StringArray (az keyvault set-policy --name $keyVaultName --secret-permissions get list --certificate-permissions get list --object-id $arcServicePrincipal.id)
if (!$newPerms)
{
Write-Host "Warning: Unable to add permissions to key vault '$keyVaultName' for Arc's service principal's identity '$($arcServicePrincipal.id)'. Arc may not be able to configure Azure AD authentication"
}
# Create an Azure AD application
#
$application = ConvertFrom-StringArray (az ad app create --display-name $applicationName --only-show-errors)
if (!$application)
{
Write-Error "Unable to create the app registration '$applicationName'"
exit 1
}
# Set perms on app registration
#
az ad app permission add --id $application.id --api 00000003-0000-0000-c000-000000000000 --api-permissions c79f8feb-a9db-4090-85f9-90d820caa0eb=Scope --only-show-errors # Delegated Application.Read.All
az ad app permission add --id $application.id --api 00000003-0000-0000-c000-000000000000 --api-permissions 0e263e50-5827-48a4-b97c-d940288653c7=Scope --only-show-errors # Delegated Directory.AccessAsUser.All
az ad app permission add --id $application.id --api 00000003-0000-0000-c000-000000000000 --api-permissions 7ab1d382-f21e-4acd-a863-ba3e13f7da61=Role --only-show-errors # Application Directory.Read.All
az ad app permission add --id $application.id --api 00000003-0000-0000-c000-000000000000 --api-permissions 5f8c59db-677d-491f-a6b8-5f174b11ec1d=Scope --only-show-errors # Delegated Group.Read.All
az ad app permission add --id $application.id --api 00000003-0000-0000-c000-000000000000 --api-permissions a154be20-db9c-4678-8ab7-66f6cc099a59=Scope --only-show-errors # Delegated User.Read.All
# Upload cert to Azure AD
#
$certUploadRes = ConvertFrom-StringArray (az ad app credential reset --id $application.id --cert $certSubjectName --keyvault $keyVaultName --append --only-show-errors)
if (!$certUploadRes)
{
Write-Error "Failed to set certificate '$certSubjectName' as a credential for app registration '$applicationName'"
exit 1
}
# Remove the version from the secret ID if present
#
$secretId = $cert.sid
if ($secretId -Match "(https:\/\/[^\/]+\/secrets\/[^\/]+)(\/.*){0,1}$") {
if ($Matches[1]) {
$secretId = $Matches[1]
}
}
# Create the settings object to write to the Azure extension for SQL Server
#
$instanceSettings = @{
instanceName = $instanceName
adminLoginName = $adminAccountName
adminLoginSid = $adminAccountSid
azureCertSecretId = $secretId
azureCertUri = $cert.id
azureKeyVaultResourceUID = $keyVault.id
managedCertSetting = "CUSTOMER MANAGED CERT"
managedAppSetting = "CUSTOMER MANAGED APP"
appRegistrationName = $application.displayName
appRegistrationSid = $application.appId
tenantId = $tenantId
aadCertSubjectName = $certSubjectName
adminLoginType = $adminAccountType
}
$extension = ConvertFrom-StringArray (az connectedmachine extension show --machine-name $machineName --name "WindowsAgent.SqlServer" --resource-group $resourceGroupName)
if ($extension.properties.Settings.AzureAD)
{
$aadSettings = $extension.properties.Settings.AzureAD
$instanceFound = $false
$instanceNameLower = $instanceName.ToLower()
$instanceIndex = 0
for (($i = 0); $i -lt $aadSettings.Length; $i++)
{
if ($aadSettings[$i].instanceName.ToLower() -eq $instanceNameLower)
{
$instanceIndex = $i
$instanceFound = $true
break
}
}
if ($instanceFound)
{
$aadSettings[$instanceIndex] = $instanceSettings
}
else
{
$aadSettings += $instanceSettings
}
$extension.properties.Settings.AzureAD = $aadSettings
}
else
{
$aadSettings = , $instanceSettings
$extension.properties.Settings | Add-Member -Name 'AzureAD' -Value $aadSettings -MemberType NoteProperty
}
$settingsString = (ConvertTo-Json $extension.properties.Settings).replace("`"", "\`"").replace("`r`n", "")
# Push settings to Arc
#
Write-Host "Writing Azure AD setting to Azure extension for SQL Server. This may take several minutes..."
$updateRes = az connectedmachine extension update --machine-name $machineName --name "WindowsAgent.SqlServer" --resource-group $resourceGroupName --settings $settingsString
if (!$updateRes)
{
Write-Error "Failed to update Azure extension for SQL Server with Azure AD settings"
exit 1
}
Write-Output "Success"
A execução do script pode levar vários minutos para ser concluída. Quando o processo é concluído, exibe-se uma mensagem como esta:
Name Location ProvisioningState
---- -------- -----------------
WindowsAgent.SqlServer westus2 Succeeded
Success
Configurando um administrador do Microsoft Entra com certificado e aplicativo já criados usando a CLI do Azure
Se você já tiver um certificado do Azure Key Vault e um aplicativo Azure que deseja usar para configurar o administrador do Microsoft Entra, poderá usar este script da CLI:
# Set up Microsoft Entra admin for user's existing key vault, certificate, and application
# Requires input parameters indicated below
# Connect statement
AZ Login
#Input parameters
$subscriptionId="<subscriptionId>"
$tenantId="<tenantId>"
$machineName="<machineName>" # hostname
$instanceName="<instanceName>" # SQL Server is define as `machine_name\instance_name`
$resourceGroupName="<resourceGroupName>"
$keyVaultName="<keyVaultName>"
$certSubjectName="<certSubjectName>" # Your existing certificate name
$applicationName="<applicationName>" # Your existing application name
$adminAccountName="<adminAccountName>"
$adminAccountSid="<adminID>" # Use object ID for the Azure AD user and group, or client ID for the Azure AD application
$adminAccountType= 0 # 0 – for Azure AD user and application, 1 for Azure AD group
# Helper function
#
function ConvertFrom-StringArray {
param (
[string[]] $stringArray
)
if (!$stringArray)
{
return $null
}
else
{
return ConvertFrom-JSON ($stringArray -join "`n")
}
}
$keyVault = ConvertFrom-StringArray (az keyvault show --name $keyVaultName)
if (!$keyVault)
{
Write-Error "Azure key vault '$keyVaultName' does not exist"
exit 1
}
$cert = ConvertFrom-StringArray (az keyvault certificate show --name $certSubjectName --vault-name $keyVaultName 2>$null)
if (!$cert)
{
Write-Error "Supplied certificate $certSubjectName was not found for this key vault. Please specify an existing certficate"
exit 1
}
$secretId = $cert.sid
if ($secretId -Match "(https:\/\/[^\/]+\/secrets\/[^\/]+)(\/.*){0,1}$") {
if ($Matches[1]) {
$secretId = $Matches[1]
}
}
$application = ConvertFrom-StringArray (az ad app list --display-name $applicationName --only-show-errors)
if (!$application)
{
Write-Error "Supplied application was not found in the subscription. Please specify an existing application"
exit 1
}
# Create the settings object to write to the Arc extension
#
$instanceSettings = @{
instanceName = $instanceName
adminLoginName = $adminAccountName
adminLoginSid = $adminAccountSid
azureCertSecretId = $secretId
azureCertUri = $cert.id
azureKeyVaultResourceUID = $keyVault.id
managedCertSetting = "CUSTOMER MANAGED CERT"
managedAppSetting = "CUSTOMER MANAGED APP"
appRegistrationName = $application.displayName
appRegistrationSid = $application.appId
tenantId = $tenantId
aadCertSubjectName = $certSubjectName
adminLoginType = $adminAccountType
}
$extension = ConvertFrom-StringArray (az connectedmachine extension show --machine-name $machineName --name "WindowsAgent.SqlServer" --resource-group $resourceGroupName)
if ($extension.properties.Settings.AzureAD)
{
$aadSettings = $extension.properties.Settings.AzureAD
$instanceFound = $false
$instanceNameLower = $instanceName.ToLower()
$instanceIndex = 0
for (($i = 0); $i -lt $aadSettings.Length; $i++)
{
if ($aadSettings[$i].instanceName.ToLower() -eq $instanceNameLower)
{
$instanceIndex = $i
$instanceFound = $true
break
}
}
if ($instanceFound)
{
$aadSettings[$instanceIndex] = $instanceSettings
}
else
{
$aadSettings += $instanceSettings
}
$extension.properties.Settings.AzureAD = $aadSettings
}
else
{
$aadSettings = , $instanceSettings
$extension.properties.Settings | Add-Member -Name 'AzureAD' -Value $aadSettings -MemberType NoteProperty
}
$settingsString = (ConvertTo-Json $extension.properties.Settings).replace("`"", "\`"").replace("`r`n", "")
# Push settings to Arc
#
Write-Host "Writing Azure AD setting to SQL Server Arc Extension. This may take several minutes..."
$updateRes = az connectedmachine extension update --machine-name $machineName --name "WindowsAgent.SqlServer" --resource-group $resourceGroupName --settings $settingsString
if (!$updateRes)
{
Write-Error "Failed to update SQL Arc Extension with Azure AD settings"
exit 1
}
Write-Output "Success"
Os certificados criados para a configuração do Microsoft Entra não são alternados automaticamente.
Para acompanhar este tutorial, você precisará dos módulos a seguir. Instale as últimas versões dos módulos ou posteriores à versão indicada abaixo:
Az.Accounts 3.37.0
Az.ConnectedMachine 0.5.0
Az.KeyVault 4.5.0
Az.Resources 6.0.0
Estes parâmetros de entrada são usados para o script do PowerShell:
<applicationName>: nome do aplicativo que será criado
<certSubjectName>: nome do certificado que será criado
<keyVaultName>: o nome do cofre de chaves. Esse cofre de chaves deve ser criado antes da execução do script
<machineName>: nome do computador do host do SQL Server
<resourceGroupName>: nome do grupo de recursos que contém a instância SQL Server – Azure Arc
<adminAccountName>: conta do administrador do Microsoft Entra que você quer definir para o SQL Server
<instanceName>: parâmetro opcional para instâncias nomeadas do SQL Server. Use esse parâmetro quando tiver uma instância nomeada. Se ele for omitido, será usado nome padrão MSSQLSERVER
<tenantId>: parâmetro opcional para ID do locatário. Você pode encontrar a ID do locatário acessando o portal do Azure e o recurso Microsoft Entra ID. No painel de Visão geral, você precisa ver sua ID de Locatário. Se omitida, será usada a ID do locatário padrão como parâmetro
<subscriptionId>: parâmetro opcional para ID da assinatura. Sua ID da assinatura pode ser encontrada no portal do Azure. Se omitida, será usada a ID da assinatura padrão
Para usar o script da CLI do PowerShell abaixo, salve o script como arquivo .ps1 e execute este comando:
Para o SQL Server em computadores host do Linux, substitua WindowsAgent.SqlServer por LinuxAgent.SqlServer no script.
param (
[Parameter(mandatory=$true)] $applicationName,
[Parameter(mandatory=$true)] $certSubjectName,
[Parameter(mandatory=$true)] $keyVaultName,
[Parameter(mandatory=$true)] $machineName,
[Parameter(mandatory=$true)] $resourceGroupName,
[Parameter(mandatory=$true)] $adminAccountName,
$instanceName,
$tenantId,
$subscriptionId
)
Import-Module Az.Accounts
Import-Module Az.ConnectedMachine
Import-Module Az.KeyVault
Import-Module Az.Resources
# Constants
#
$NUMRETRIES = 60
# Check parameters
#
if ([string]::IsNullOrEmpty($instanceName))
{
Write-Host "Warning: SQL Instance name (-instanceName) not provided. Default of MSSQLSERVER will be used"
$instanceName = "MSSQLSERVER"
}
$tenantIdArgument = ""
if ([string]::IsNullOrEmpty($tenantId))
{
Write-Host "Warning: Tenant ID (-tenantId) not supplied to the script, so default tenant is being used"
}
else
{
$tenantIdArgument = "-TenantId '" + $tenantId + "'"
}
$subscriptionIdArgument = ""
if ([string]::IsNullOrEmpty($subscriptionId))
{
Write-Host "Warning: Subscription ID (-subscriptionId) not supplied to the script, so default subscription is being used"
}
else
{
$subscriptionIdArgument = "-SubscriptionId '" + $subscriptionId + "'"
}
# Login
#
try
{
$loginRes = Invoke-Expression -Command ("Connect-AzAccount " + $tenantIdArgument + " " + $subscriptionIdArgument + " -ErrorAction stop -UseDeviceAuthentication")
}
catch
{
Write-Error $_
Write-Error "Failed to login to Azure. Script can not continue"
exit 1
}
# Get subscription ID
#
if ([string]::IsNullOrEmpty($subscriptionId))
{
$context = Get-AzContext
if ($context)
{
if ($context.Name -Match "[^(]+\(([^)]{36})\)")
{
if ($Matches[1])
{
$subscriptionId = $Matches[1]
}
}
}
}
if ([string]::IsNullOrEmpty($subscriptionId))
{
Write-Error "Failed to find default subscription"
exit 1
}
# Check AKV path exists
#
$keyVault = Get-AzKeyVault -VaultName $keyVaultName
if (!$keyVault)
{
Write-Error "Supplied key vault was not found in the subscription. Please specify an existing key vault"
exit 1
}
# Check certificate doesn't exist
#
$cert = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name $certSubjectName
if ($cert)
{
Write-Error "Certificate $certSubjectName already exists"
exit 1
}
# Check app registration doesn't exist
#
$application = Get-AzADApplication -DisplayName $applicationName
if ($application)
{
Write-Error "Application $applicationName already exists"
exit 1
}
# Check Arc SQL instance is valid
#
$arcInstance = Get-AzConnectedMachineExtension -SubscriptionId $subscriptionId -MachineName $machineName -ResourceGroupName $resourceGroupName -Name "WindowsAgent.SqlServer"
if (!$arcInstance)
{
Write-Error "Could not find a SQL Server Arc instance in subscription '$subscriptionId' and resource group '$resourceGroupName' with name '$machineName'"
exit 1
}
# Check if admin account exists
#
$adminAccount = Get-AzADUser -UserPrincipalName $adminAccountName
$adminAccountType = 0
if (!$adminAccount)
{
# Check for guest user
#
$adminAccount = Get-AzADUser -Mail $adminAccountName
if (!$adminAccount)
{
$adminAccount = Get-AzADGroup -DisplayName $adminAccountName
if (!$adminAccount)
{
$adminAccount = Get-AzADServicePrincipal -DisplayName $adminAccountName
}
else
{
$adminAccountType = 1
}
}
}
if ($adminAccount)
{
if ($adminAccount.Length -gt 1)
{
Write-Error "Multiple accounts with found with name $adminAccountName"
exit 1
}
$adminAccountSid = $adminAccount.Id
}
else
{
Write-Error "Could not find an account with name $adminAccountName"
exit 1
}
# Create certificate in AKV
#
$Policy = New-AzKeyVaultCertificatePolicy -SecretContentType "application/x-pkcs12" -SubjectName "CN=$certSubjectName" -IssuerName "Self" -ValidityInMonths 12 -ReuseKeyOnRenewal
try
{
$addCertRes = Add-AzKeyVaultCertificate -VaultName $keyVaultName -Name $certSubjectName -CertificatePolicy $Policy -ErrorAction stop
}
catch
{
Write-Error $_
Write-Error "Certificate $certSubjectName could not be created"
exit 1
}
for (($i = 0); $i -lt $NUMRETRIES -and (!$cert -or !$cert.enabled); $i++)
{
$cert = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name $certSubjectName
if (!$cert -or !$cert.enabled)
{
Start-Sleep -Seconds 5
}
}
if (!$cert)
{
Write-Error "Certificate $certSubjectName could not be created"
exit 1
}
# Allow Arc to access AKV
#
$arcServicePrincipal = Get-AzADServicePrincipal -DisplayName $machineName
if ($arcServicePrincipal -and ![string]::IsNullOrEmpty($arcServicePrincipal.Id))
{
try
{
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId $arcServicePrincipal.Id -PermissionsToSecrets Get,List -PermissionsToCertificates Get,List
}
catch
{
Write-Error $_
Write-Host "Warning: Could not find the identity of the Azure extension for SQL Server and thus, could not add permissions for the Arc process to read from AKV. Ensure the Arc identity has the required permissions to read from AKV."
}
}
else
{
Write-Host "Warning: Could not find the identity of the Azure extension for SQL Server and thus, could not add permissions for the Arc process to read from AKV. Ensure the Arc identity has the required permissions to read from AKV."
}
# Create an Azure AD application
#
$application = New-AzADApplication -DisplayName $applicationName
if (!$application)
{
Write-Error "Application could not be created"
exit 1
}
# Set perms on app registration
#
Add-AzADAppPermission -ObjectId $application.Id -ApiId 00000003-0000-0000-c000-000000000000 -PermissionId c79f8feb-a9db-4090-85f9-90d820caa0eb # Delegated Application.Read.All
Add-AzADAppPermission -ObjectId $application.Id -ApiId 00000003-0000-0000-c000-000000000000 -PermissionId 0e263e50-5827-48a4-b97c-d940288653c7 # Delegated Directory.AccessAsUser.All
Add-AzADAppPermission -ObjectId $application.Id -ApiId 00000003-0000-0000-c000-000000000000 -PermissionId 7ab1d382-f21e-4acd-a863-ba3e13f7da61 -Type Role # Application Directory.Read.All
Add-AzADAppPermission -ObjectId $application.Id -ApiId 00000003-0000-0000-c000-000000000000 -PermissionId 5f8c59db-677d-491f-a6b8-5f174b11ec1d # Delegated Group.Read.All
Add-AzADAppPermission -ObjectId $application.Id -ApiId 00000003-0000-0000-c000-000000000000 -PermissionId a154be20-db9c-4678-8ab7-66f6cc099a59 # Delegated User.Read.All
# Upload cert to Azure AD
#
try
{
$base64Cert = [System.Convert]::ToBase64String($cert.Certificate.GetRawCertData())
New-AzADAppCredential -ApplicationObject $application -CertValue $base64Cert -EndDate $cert.Certificate.NotAfter -StartDate $cert.Certificate.NotBefore -ErrorAction stop
}
catch
{
Write-Error $_
Write-Error "Failed to add certificate to app registration"
exit 1
}
# Remove the version from the secret ID if present
#
$secretId = $cert.SecretId
if ($secretId -Match "(https:\/\/[^\/]+\/secrets\/[^\/]+)(\/.*){0,1}$") {
if ($Matches[1]) {
$secretId = $Matches[1]
}
}
# Create the settings object to write to the Azure extension for SQL Server
#
$instanceSettings = @{
instanceName = $instanceName
adminLoginName = $adminAccountName
adminLoginSid = $adminAccountSid
azureCertSecretId = $secretId.replace(":443", "")
azureCertUri = $cert.Id.replace(":443", "")
azureKeyVaultResourceUID = $keyVault.ResourceId
managedCertSetting = "CUSTOMER MANAGED CERT"
managedAppSetting = "CUSTOMER MANAGED APP"
appRegistrationName = $application.DisplayName
appRegistrationSid = $application.AppId
tenantId = $tenantId
aadCertSubjectName = $certSubjectName
adminLoginType = $adminAccountType
}
$arcInstance = Get-AzConnectedMachineExtension -SubscriptionId $subscriptionId -MachineName $machineName -ResourceGroupName $resourceGroupName -Name "WindowsAgent.SqlServer"
if ($arcInstance.Setting.AdditionalProperties.AzureAD)
{
$aadSettings = $arcInstance.Setting.AdditionalProperties.AzureAD
$instanceFound = $false
$instanceNameLower = $instanceName.ToLower()
$instanceIndex = 0
for (($i = 0); $i -lt $aadSettings.Length; $i++)
{
if ($aadSettings[$i].instanceName.ToLower() -eq $instanceNameLower)
{
$instanceIndex = $i
$instanceFound = $true
break
}
}
if ($instanceFound)
{
$aadSettings[$instanceIndex] = $instanceSettings
}
else
{
$aadSettings += $instanceSettings
}
$arcInstance.Setting.AdditionalProperties.AzureAD = $aadSettings
}
else
{
$aadSettings = , $instanceSettings
$arcInstance.Setting.AdditionalProperties | Add-Member -Name 'AzureAD' -Value $aadSettings -MemberType NoteProperty
}
Write-Host "Writing Microsoft Entra setting to SQL Server Arc Extension. This may take several minutes..."
# Push settings to Arc
#
try
{
Update-AzConnectedMachineExtension -MachineName $machineName -Name "WindowsAgent.SqlServer" -ResourceGroupName $resourceGroupName -Setting $arcInstance.Setting
}
catch
{
Write-Error $_
Write-Error "Failed to write settings to Arc host"
exit 1
}
Write-Output "Success"
Configurando um administrador do Microsoft Entra com certificado e aplicativo já criados usando a CLI do PowerShell
Se você já tiver um certificado do Azure Key Vault e um aplicativo Azure que deseja usar para configurar o administrador do Microsoft Entra, poderá usar este script do PowerShell:
# Connect statement
Connect-AzAccount
#Input parameters
$subscriptionId="<subscriptionId>"
$tenantId="<tenantId>"
$machineName="<machineName>" # hostname
$instanceName="<instanceName>" # SQL Server is define as `machine_name\instance_name`
$resourceGroupName="<resourceGroupName>"
$keyVaultName="<keyVaultName>"
$certSubjectName="<certSubjectName>" # Your existing certificate name
$applicationName="<applicationName>" # Your existing application name
$adminAccountName="<adminAccountName>"
$adminAccountSid="<adminID>" # Use object ID for the Microsoft Entra user and group, or client ID for the Microsoft Entra application
$adminAccountType= 0 # 0 – for Microsoft Entra user and application, 1 for Microsoft Entra group
$keyVault = Get-AzKeyVault -VaultName $keyVaultName
if (!$keyVault)
{
Write-Error "Supplied key vault was not found in the subscription. Please specify an existing key vault"
exit 1
}
$cert = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name $certSubjectName
if (!$cert)
{
Write-Error "Supplied certificate $certSubjectName was not found for this key vault. Please specify an existing certificate"
exit 1
}
$secretId = $cert.SecretId
if ($secretId -Match "(https:\/\/[^\/]+\/secrets\/[^\/]+)(\/.*){0,1}$") {
if ($Matches[1]) {
$secretId = $Matches[1]
}
}
$application = Get-AzADApplication -DisplayName $applicationName
if (!$application)
{
Write-Error "Supplied application was not found in the subscription. Please specify an existing application"
exit 1
}
# Create the settings object to write to the Arc extension
#
$instanceSettings = @{
instanceName = $instanceName
adminLoginName = $adminAccountName
adminLoginSid = $adminAccountSid
azureCertSecretId = $secretId.replace(":443", "")
azureCertUri = $cert.Id.replace(":443", "")
azureKeyVaultResourceUID = $keyVault.ResourceId
managedCertSetting = "CUSTOMER MANAGED CERT"
managedAppSetting = "CUSTOMER MANAGED APP"
appRegistrationName = $application.DisplayName
appRegistrationSid = $application.AppId
tenantId = $tenantId
aadCertSubjectName = $certSubjectName
adminLoginType = $adminAccountType
}
$arcInstance = Get-AzConnectedMachineExtension -SubscriptionId $subscriptionId -MachineName $machineName -ResourceGroupName $resourceGroupName -Name "WindowsAgent.SqlServer"
if ($arcInstance.Setting.AdditionalProperties.AzureAD)
{
$aadSettings = $arcInstance.Setting.AdditionalProperties.AzureAD
$instanceFound = $false
$instanceNameLower = $instanceName.ToLower()
$instanceIndex = 0
for (($i = 0); $i -lt $aadSettings.Length; $i++)
{
if ($aadSettings[$i].instanceName.ToLower() -eq $instanceNameLower)
{
$instanceIndex = $i
$instanceFound = $true
break
}
}
if ($instanceFound)
{
$aadSettings[$instanceIndex] = $instanceSettings
}
else
{
$aadSettings += $instanceSettings
}
$arcInstance.Setting.AdditionalProperties.AzureAD = $aadSettings
}
else
{
$aadSettings = , $instanceSettings
$arcInstance.Setting.AdditionalProperties | Add-Member -Name 'AzureAD' -Value $aadSettings -MemberType NoteProperty
}
Write-Host "Writing Microsoft Entra setting to SQL Server Arc Extension. This may take several minutes..."
# Push settings to Arc
#
try
{
Update-AzConnectedMachineExtension -MachineName $machineName -Name "WindowsAgent.SqlServer" -ResourceGroupName $resourceGroupName -Setting $arcInstance.Setting
}
catch
{
Write-Error $_
Write-Error "Failed to write settings to Arc host"
exit 1
}
Write-Output "Success"
O modelo do ARM a seguir configura um administrador do Microsoft Entra usando um certificado do Azure Key Vault e um aplicativo Microsoft Entra já criados.
Utilizam-se este parâmetros de entrada com o modelo do ARM:
<machineName>: nome do computador do host do SQL Server
<Location>: localização do grupo de recursos do SQL Server – Azure Arc, como West US ou Central US
<tenantId>: a ID do locatário pode ser encontrada acessando o portal do Azure e o .recurso Microsoft Entra ID. No painel Visão geral, você verá a ID de Locatário
<instanceName>: o nome da instância do SQL Server O nome da instância padrão do SQL Server é MSSQLSERVER
<certSubjectName>: nome do certificado que você criou
<subscriptionId>: ID da assinatura. Sua ID da assinatura pode ser encontrada no portal do Azure
<resourceGroupName>: o nome do grupo de recursos que contém o cofre de chaves. Encontre o valor completo de azureKeyVaultResourceUID acessando o recurso Cofre de chaves, selecionando Propriedades e copiando a ID do recurso
<keyVaultName>: o nome do cofre de chaves
<certIdentifier>: o identificador de certificado do certificado do Azure Key Vault. Para obter o identificador de certificado, vá para o recurso Cofre de chaves e selecione Certificados em Configurações. Selecione a versão atual do certificado que você criou e copie o valor do identificador de certificado. Para obter mais informações, confira Adicionar um certificado ao Key Vault
<certSecret>: o identificador secreto do certificado, e pode ser encontrado no mesmo menu que o identificador do certificado
Dar consentimento do administrador para o aplicativo
Quando o administrador do Microsoft Entra estiver configurado, você poderá se conectar ao SQL Server usando as credenciais de administrador do Microsoft Entra. Porém, outras atividades de banco de dados que envolvam a criação de novos logons e usuários do Microsoft Entra falharão até que o consentimento do administrador seja concedido ao aplicativo do Microsoft Entra.
Observação
Para dar o Consentimento do administrador ao aplicativo, a conta que dá consentimento requer uma função de administrador global do Microsoft Entra ou administrador de funções com privilégios. Essas funções são necessárias para conceder consentimento do administrador ao aplicativo, mas não para configurar o administrador do Microsoft Entra.
No portal do Azure, selecione Microsoft Entra ID>Registros de aplicativo e selecione o aplicativo recém-criado. O aplicativo deve ter um nome como <hostname>-<instanceName><uniqueNumber>.
Escolha o menu Permissões da API.
Selecione Conceder consentimento do administrador.
Sem conceder consentimento do administrador ao aplicativo, criar um logon ou usuário do Microsoft Entra no SQL Server resultará no seguinte erro:
Msg 37455, Level 16, State 1, Line 2
Server identity does not have permissions to access MS Graph.
Usando a autenticação do Microsoft Entra para conectar-se ao SQL Server
A autenticação do Microsoft Entra agora está configurada para o SQL Server conectado ao Azure Arc. Siga as seções após configurar o administrador do Microsoft Entra no artigo Tutorial: configurar a autenticação do Microsoft Entra para o SQL Server e se conecte ao SQL Server usando a autenticação do Microsoft Entra.