Si applica a:
SQL Server 2022 (16.x)
Questo articolo descrive come configurare l'amministratore di Microsoft Entra per consentire l'autenticazione con Microsoft Entra ID (in precedenza Azure Active Directory) per SQL Server usando il portale di Azure e le API, ad esempio:
- PowerShell
- L'interfaccia della riga di comando di Azure
- Modello ARM
Verranno inoltre illustrate le funzionalità aggiornate per configurare un amministratore di Microsoft Entra per SQL Server nel portale di Azure che consenta la creazione automatica dei certificati e la registrazione dell'applicazione. In precedenza, la configurazione dell'autenticazione di Microsoft Entra per SQL Server richiedeva la configurazione manuale dell'amministratore di Microsoft Entra con un certificato di Azure e la registrazione dell’applicazione.
Nota
Anche se Microsoft Entra ID è il nuovo nome per Azure Active Directory (Azure AD), per evitare l'interruzione degli ambienti esistenti, la denominazione Azure AD è tuttora mantenuta in alcuni elementi hardcoded, ad esempio campi dell'interfaccia utente, provider di connessioni, codici errore e cmdlet. In questo articolo i due nomi sono intercambiabili.
Prerequisiti
Preparazione prima della configurazione di un amministratore di Microsoft Entra
Le autorizzazioni seguenti sono necessarie per configurare un amministratore di Microsoft Entra nelle risorse di SQL Server - Azure Arc e Key Vault.
Segui la guida per assicurarti che SQL Server sia connesso ad Azure Arc. L'utente che configura l'amministratore di Microsoft Entra per la risorsa SQL Server - Azure Arc deve avere il ruolo Collaboratore per il server.
- Accedere al portale di Azure
- Seleziona SQL Server - Azure Arc e seleziona l'istanza per l'host SQL Server.
- Seleziona Controllo di accesso (IAM).
- Seleziona Aggiungi>Aggiungi assegnazione di ruolo per aggiungere il ruolo Collaboratore all'utente che configura l'amministratore di Microsoft Entra.
Se non hai un account Azure Key Vault, crealo. L'utente che configura l'amministratore di Microsoft Entra deve avere il ruolo di Collaboratore in Azure Key Vault. Per aggiungere un ruolo a un utente in Azure Key Vault:
- Accedere al portale di Azure
- Vai alla risorsa Key Vault.
- Seleziona Controllo di accesso (IAM).
- Seleziona Aggiungi>Aggiungi assegnazione di ruolo per aggiungere il ruolo Collaboratore all'utente che configura l'amministratore di Microsoft Entra.
Impostare i criteri di accesso per l'host di SQL Server
Nel portale di Azure, accedi all’istanza di Azure Key Vault e seleziona Criteri di accesso.
Seleziona Aggiungi criteri di accesso.
Per Autorizzazioni chiave, usa Sign.
Per Autorizzazioni segrete, seleziona Get e List.
Per Autorizzazioni certificati, seleziona Ottieni e Elenca.
Selezionare Avanti.
Nella pagina Principale, cerca il nome della tua istanza di Machine - Azure Arc, che è l'hostname del server SQL Server.
Ignora la pagina Applicazione (facoltativa) selezionando Avanti due volte oppure selezionando Rivedi e crea.
Verifica che l'ID oggetto del Principale corrisponda all'ID Principale dell'identità gestita assegnata all'istanza.
Per confermare, vai alla pagina della risorsa e seleziona Visualizzazione JSON in alto a destra nella casella Essentials nella pagina Panoramica. In Identità sarà disponibile il principalId.
Seleziona Crea.
Devi selezionare Crea per assicurarti che vengano applicate le autorizzazioni. Per assicurarti che le autorizzazioni siano state archiviate, aggiorna la finestra del browser e verifica che la riga per l'istanza di Azure Arc sia ancora presente.
Impostare i criteri di accesso per gli utenti di Microsoft Entra
- Nel portale di Azure, accedi all’istanza di Azure Key Vault e seleziona Criteri di accesso.
- Seleziona Aggiungi criteri di accesso.
- Per Autorizzazioni chiave, seleziona Get, List e Create.
- Per Autorizzazioni segrete, seleziona Get, List e Set.
- Per Autorizzazioni del certificato, seleziona Get, List e Create.
- Per Seleziona principale, aggiungi l'utente Microsoft Entra che vuoi usare per connetterti a SQL Server.
- Seleziona Aggiungi e quindi Salva.
Configurazione dell'amministratore di Microsoft Entra per SQL Server
Le nuove API e le funzionalità del portale consentono agli utenti di configurare un amministratore di Microsoft Entra per SQL Server senza dover creare separatamente un certificato di Azure e un'applicazione Microsoft Entra. Seleziona una scheda per informazioni su come configurare un amministratore di Microsoft Entra per SQL Server connesso ad Azure Arc con la creazione automatica di certificati e applicazioni.
Usa il portale di Azure per configurare un amministratore di Microsoft Entra, creare un certificato di Azure Key Vault e un'applicazione Microsoft Entra nello stesso processo. Questa operazione è necessaria per usare l'autenticazione di Microsoft Entra con SQL Server.
Configurazione dell'amministratore di Microsoft Entra usando il portale di Azure
Accedi al portale di Azure e seleziona SQL Server – Azure Arc. Seleziona l’istanza per l’host SQL Server.
Controlla lo stato della risorsa SQL Server - Azure Arc e verifica se è connessa dal menu Proprietà. Per altre informazioni, vedi Convalidare le risorse di SQL Server abilitate per Arc.
Seleziona Microsoft Entra ID e Purview in Impostazioni dal menu della risorsa.
Seleziona Imposta amministratore per aprire il riquadro Microsoft Entra ID e scegli un account che verrà aggiunto come account di accesso amministratore a SQL Server.
Seleziona Certiificato gestito dal servizio.
Seleziona Cambia insieme di credenziali delle chiavi e seleziona la risorsa Azure Key Vault esistente.
Seleziona Registrazione app gestita dal servizio.
Seleziona Salva. In questo modo viene inviata una richiesta all'agente server Arc, che configura l'autenticazione di Microsoft Entra per l'istanza di SQL Server. Il completamento dell'operazione può richiedere alcuni minuti; attendi fino a quando il processo di salvataggio non viene confermato con Saved successfully
prima di tentare un accesso a Microsoft Entra.
La registrazione dell'app gestita dal servizio esegue le operazioni seguenti:
- Crea un certificato nel tuo gestore di chiavi con un nome nel formato
<hostname>-<instanceName><uniqueNumber>
.
- Crea un'applicazione Microsoft Entra con un nome come
<hostname>-<instanceName><uniqueNumber>
e assegna le autorizzazioni necessarie a tale applicazione. Per altre informazioni, vedi Concedere le autorizzazioni delle applicazioni
- Assegna il nuovo certificato in Azure Key Vault all'applicazione.
- Salva queste impostazioni in Azure Arc.
Lo script dell'interfaccia della riga di comando di Azure seguente configura un amministratore di Microsoft Entra, crea un certificato di Azure Key Vault e crea un'applicazione Microsoft Entra. È disponibile una sezione aggiuntiva che fornisce uno script di esempio per configurare un amministratore di Microsoft Entra quando esistono già un certificato e un'applicazione.
Nota
I certificati creati per la configurazione di Microsoft Entra non vengono ruotati automaticamente.
Per installare il modulo Az.ConnectedMachine
usa az extension add --name ConnectedMachine
. Per verificare quale versione dell'interfaccia della riga di comando di Azure è installata, utilizza az version
.
Per lo script dell'interfaccia della riga di comando di Azure vengono usati i parametri di input seguenti:
-
<applicationName>
- Nome dell’applicazione che verrà creata
-
<certSubjectName>
- Nome del certificato che verrà creato
-
<keyVaultName>
- Nome del Key Vault. Questo Key Vault deve essere creato prima di eseguire lo script
-
<machineName>
- Nome del computer dell'host di SQL Server
-
<resourceGroupName>
- Nome del gruppo di risorse che contiene l’istanza di SQL Server - Azure Arc
-
<adminAccountName>
- L’account amministratore di Microsoft Entra che vuoi configurare per SQL Server
-
<instanceName>
- Parametro facoltativo per le istanze denominate di SQL Server. Utilizza questo parametro quando disponi di un'istanza denominata. Se omesso, viene utilizzato il nome predefinito di MSSQLSERVER
-
<tenantId>
- Parametro facoltativo per l'ID tenant. L'ID tenant è disponibile aprendo il portale di Azure e andando alla risorsa Microsoft Entra ID. Nel riquadro Panoramica dovrebbe essere visualizzato il tuo ID tenant. Se omesso, l'ID tenant predefinito viene usato come parametro
-
<subscriptionId>
- Parametro facoltativo per l'ID sottoscrizione. L'ID sottoscrizione è disponibile nel portale di Azure. Se omesso, viene usato l'ID sottoscrizione predefinito
Per usare lo script dell'interfaccia della riga di comando di Azure seguente, salva lo script come file .ps1
ed esegui questo comando:
./aadAzCliSetup.ps1 -applicationName "<applicationName>" -certSubjectName "<certSubjectName>" -keyVaultName "<keyVaultName>" -machineName "<machineName>" -resourceGroupName "<resourceGroupName>" -adminAccountName "<adminAccountName>" -instanceName "<instanceName>" -tenantId "<tenantId>" -subscriptionId "<subscriptionId>"
Script CLI di Azure
Nota
Per i computer host SQL Server in Linux, sostituisci WindowsAgent.SqlServer
con LinuxAgent.SqlServer
nello 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"
Il completamento dell’esecuzione dello script può richiedere alcuni minuti. Al termine del processo, verrà visualizzato un messaggio simile al seguente:
Name Location ProvisioningState
---- -------- -----------------
WindowsAgent.SqlServer westus2 Succeeded
Success
Configurazione di un amministratore di Microsoft Entra con un certificato e un'applicazione esistenti usando l'interfaccia della riga di comando di Azure
Se disponi già di un certificato di Azure Key Vault e di un'applicazione Azure che vuoi usare per configurare un amministratore di Microsoft Entra, puoi usare lo script dell'interfaccia della riga di comando seguente:
# 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 certificate"
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"
Lo script di PowerShell seguente configura un amministratore di Microsoft Entra, crea un certificato di Azure Key Vault e crea un'applicazione Microsoft Entra. È disponibile una sezione aggiuntiva che fornisce uno script di esempio per configurare un amministratore di Microsoft Entra quando esistono già un certificato e un'applicazione.
Nota
I certificati creati per la configurazione di Microsoft Entra non vengono ruotati automaticamente.
Per questa esercitazione sono necessari i moduli seguenti. Installa le versioni più recenti dei moduli o versioni successive della versione riportata di seguito:
- Az.Accounts 3.37.0
- Az.ConnectedMachine 0.5.0
- Az.KeyVault 4.5.0
- Az.Resources 6.0.0
Per lo script PowerShell vengono usati i parametri di input seguenti:
-
<applicationName>
- Nome dell’applicazione che verrà creata
-
<certSubjectName>
- Nome del certificato che verrà creato
-
<keyVaultName>
- Nome del Key Vault. Questo Key Vault deve essere creato prima di eseguire lo script
-
<machineName>
- Nome del computer dell'host di SQL Server
-
<resourceGroupName>
- Nome del gruppo di risorse che contiene l’istanza di SQL Server - Azure Arc
-
<adminAccountName>
- L’account amministratore di Microsoft Entra che vuoi configurare per SQL Server
-
<instanceName>
- Parametro facoltativo per le istanze denominate di SQL Server. Utilizza questo parametro quando disponi di un'istanza denominata. Se omesso, viene utilizzato il nome predefinito di MSSQLSERVER
-
<tenantId>
- Parametro facoltativo per l'ID tenant. L'ID tenant è disponibile aprendo il portale di Azure e andando alla risorsa Microsoft Entra ID. Nel riquadro Panoramica dovrebbe essere visualizzato il tuo ID tenant. Se omesso, l'ID tenant predefinito viene usato come parametro
-
<subscriptionId>
- Parametro facoltativo per l'ID sottoscrizione. L'ID sottoscrizione è disponibile nel portale di Azure. Se omesso, viene usato l'ID sottoscrizione predefinito
Per usare lo script di PowerShell seguente, salva lo script come file .ps1
ed esegui il comando seguente:
./aadPowerShellsetup.ps1 -applicationName "<applicationName>" -certSubjectName "<certSubjectName>" -keyVaultName "<keyVaultName>" -machineName "<machineName>" -resourceGroupName "<resourceGroupName>" -adminAccountName "<adminAccountName>" -instanceName "<instanceName>" -tenantId "<tenantId>" -subscriptionId "<subscriptionId>"
Script di PowerShell
Per i computer host SQL Server in Linux, sostituisci WindowsAgent.SqlServer
con LinuxAgent.SqlServer
nello 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
}
}
else
{
$aadSettings = , $instanceSettings
}
Write-Host "Writing Microsoft Entra setting to SQL Server Arc Extension. This may take several minutes..."
# Push settings to Arc
#
try
{
#set the Entra ID / AzureAD setting in the hash table
$SettingsToConfigure = @{
AzureAD = $aadSettings
}
#add any non-AzureAD key value pairs back to the hashtable
$keys = $arcInstance.Setting.Keys | where-object {$_ -notin ("AzureAD")}
foreach ($key in $keys) {
$SettingsToConfigure.$key = $arcInstance.Setting["$key"]
}
#Issue the update of the updated settings
Update-AzConnectedMachineExtension `
-MachineName $machineName `
-Name "WindowsAgent.SqlServer" `
-ResourceGroupName $resourceGroupName `
-Setting $SettingsToConfigure
}
catch
{
Write-Error $_
Write-Error "Failed to write settings to Arc host"
exit 1
}
Write-Output "Success"
Configurazione di un amministratore di Microsoft Entra con un certificato e un'applicazione esistenti usando PowerShell
Se disponi già di un certificato di Azure Key Vault e di un'applicazione Azure che vuoi utilizzare per configurare un amministratore di Microsoft Entra, puoi utilizzare lo script di PowerShell seguente:
# 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
}
}
else
{
$aadSettings = , $instanceSettings
}
Write-Host "Writing Microsoft Entra setting to SQL Server Arc Extension. This may take several minutes..."
# Push settings to Arc
#
try
{
#set the Entra ID / AzureAD setting in the hash table
$SettingsToConfigure = @{
AzureAD = $aadSettings
}
#add any non-AzureAD key value pairs back to the hashtable
$keys = $arcInstance.Setting.Keys | where-object {$_ -notin ("AzureAD")}
foreach ($key in $keys) {
$SettingsToConfigure.$key = $arcInstance.Setting["$key"]
}
#Issue the update of the updated settings
Update-AzConnectedMachineExtension `
-MachineName $machineName `
-Name "WindowsAgent.SqlServer" `
-ResourceGroupName $resourceGroupName `
-Setting $SettingsToConfigure
}
catch
{
Write-Error $_
Write-Error "Failed to write settings to Arc host"
exit 1
}
Write-Output "Success"
Il modello di ARM seguente configura un amministratore di Microsoft Entra usando un certificato di Azure Key Vault esistente e un'applicazione Microsoft Entra.
Per il modello di ARM vengono usati i parametri di input seguenti:
-
<machineName>
- Nome del computer dell'host di SQL Server
-
<Location>
- Posizione della risorsa SQL Server - Azure Arc, ad esempio West US
o Central US
-
<tenantId>
- L'ID tenant è disponibile aprendo il portale di Azure e andando alla risorsa Microsoft Entra ID. Nel riquadro Panoramica dovresti vedere il tuo ID Tenant
-
<instanceName>
- Nome dell'istanza di SQL Server. Il nome dell'istanza predefinita di SQL Server è MSSQLSERVER
-
<certSubjectName>
- Nome del certificato creato
-
<subscriptionId>
- ID sottoscrizione. L'ID sottoscrizione è disponibile nel portale di Azure
-
<resourceGroupName>
- Nome del gruppo di risorse che contiene il tuo Key Vault. Il valore azureKeyVaultResourceUID completo è disponibile andando alla risorsa dell’insieme di credenziali delle chiavi, selezionando Proprietà e copiando l’ID risorsa
-
<keyVaultName>
- Nome del tuo key vault
-
<certIdentifier>
- L’identificatore del certificato del certificato di Azure Key Vault. Per ottenere l’identificatore del certificato, vai alla risorsa dell’insieme di credenziali delle chiavi e seleziona Certificati in Impostazioni. Seleziona la versione corrente del certificato creato e copia il valore dell’identificatore del certificato. Per ulteriori informazioni, consulta Aggiungere un certificato a Key Vault
-
<certSecret>
- L’Identificatore segreto del certificato, disponibile nello stesso menu dell'identificatore del certificato
-
<applicationName>
- Il nome dell'applicazione Microsoft Entra creata
-
<appID>
- L'ID applicazione (client) dell'applicazione Microsoft Entra è disponibile nel menu Panoramica dell'applicazione
-
<adminAccountName>
- L’account amministratore di Microsoft Entra che vuoi configurare per SQL Server
-
<adminID>
- L’ID oggetto dell'utente o del gruppo Microsoft Entra o l’ID applicazione (client) dell'applicazione se usi un'altra applicazione come account amministratore di Microsoft Entra. Per altre informazioni, vedi Esercitazione: Creare utenti di Microsoft Entra usando applicazioni Microsoft Entra
-
<adminType>
- Usa 0
per gli utenti e le applicazioni di Microsoft Entra e 1
per i gruppi di Microsoft Entra
Usa una distribuzione personalizzata nel portale di Azure e crea un modello personalizzato nell'editor.
Salva quindi la configurazione dopo aver incollato l'esempio.
Nota
Per i computer host SQL Server in Linux, sostituisci WindowsAgent.SqlServer
con LinuxAgent.SqlServer
nello script.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"resources": [
{
"type": "Microsoft.HybridCompute/machines/extensions",
"apiVersion": "2022-03-10",
"name": "<machineName>/WindowsAgent.SqlServer",
"location": "<Location>",
"properties": {
"publisher": "Microsoft.AzureData",
"type": "WindowsAgent.SqlServer",
"settings": {
"AzureAD": [
{
"tenantId": "<tenantId>",
"instanceName": "<instanceName>",
"managedCertSetting": "CUSTOMER MANAGED CERT",
"aadCertSubjectName": "<certSubjectName>",
"azureKeyVaultResourceUID": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.KeyVault/vaults/<keyVaultName>",
"azureCertUri": "<certIdentifier>",
"azureCertSecretId": "<certSecret>",
"managedAppSetting": "CUSTOMER MANAGED APP",
"appRegistrationName": "<applicationName>",
"appRegistrationSid": "<appID>",
"adminLoginName": "<adminAccountName>",
"adminLoginSid" : "<adminID>",
"adminLoginType": 0
}
]
}
}
}
]
}
Concedere il consenso amministratore all'applicazione
Dopo aver configurato l'amministratore di Microsoft Entra, l'uso delle credenziali di amministratore di Microsoft Entra ti consente di connetterti a SQL Server. Tuttavia, eventuali ulteriori attività di database che coinvolgono la creazione di nuovi account di accesso e utenti di Microsoft Entra avranno esito negativo fino a quando non viene concesso il consenso amministratore all'applicazione Microsoft Entra.
Nota
Per concedere consenso amministrativo per l'applicazione, l'account che concede il consenso deve avere il ruolo di Amministratore dei ruoli privilegiati di Microsoft Entra ID. Questi ruoli sono necessari per concedere il consenso amministratore per l'applicazione, ma non sono necessari per configurare l'amministratore di Microsoft Entra.
Nel portale di Azure, seleziona Microsoft Entra ID>Registrazioni app, seleziona l’applicazione appena creata. L'applicazione deve avere un nome come <hostname>-<instanceName><uniqueNumber>
.
Seleziona il menu Autorizzazioni API.
Seleziona Concedi consenso amministratore.
Se non si concede il consenso amministratore all'applicazione, la creazione di un account di accesso o di un utente di Microsoft Entra in SQL Server genererà l'errore seguente:
Msg 37455, Level 16, State 1, Line 2
Server identity does not have permissions to access MS Graph.
Uso dell’autenticazione di Microsoft Entra per connettersi a SQL Server
L'autenticazione di Microsoft Entra è ora configurata per SQL Server connesso ad Azure Arc. Segui le sezioni dopo aver configurato l'amministratore di Microsoft Entra nell'articolo Esercitazione: Configurare l'autenticazione di Microsoft Entra per SQL Server per connetterti a SQL Server usando l'autenticazione di Microsoft Entra.
Vedi anche