Tutorial: Uso de la automatización para configurar el administrador de Microsoft Entra para SQL Server
Artículo
Se aplica a: SQL Server 2022 (16.x)
Nota:
Esta característica está disponible en SQL Server 2022 (16.x) o versiones posteriores, y solo se admite para SQL Server hosts locales, para hosts de Windows y Linux, y SQL Server 2022 en máquinas virtuales de Windows Azure.
En este artículo, veremos cómo configurar el administrador de Microsoft Entra para permitir la autenticación de Microsoft Entra ID (anteriormente Azure Active Directory) para SQL Server mediante Azure Portal y API como las siguientes:
Aunque Microsoft Entra ID es el nuevo nombre de Azure Active Directory (Azure AD), para evitar interrumpir los entornos existentes, Azure AD sigue estando en algunos elementos codificados de forma rígida como campos de interfaz de usuario, proveedores de conexiones, códigos de error y cmdlets. En este artículo, los dos nombres son intercambiables.
Preparación antes de establecer el administrador de Microsoft Entra
Los permisos siguientes son necesarios para configurar el administrador de Microsoft Entra en los recursos de SQL Server: Azure Arc y de Key Vault.
Configuración de permisos para Azure Arc
Sigue la guía para asegurarte de que SQL Server está conectado a Azure Arc. El usuario que configura el administrador de Microsoft Entra para el recurso SQL Server: Azure Arc debe tener el rol Colaborador para el servidor.
Seleccione SQL Server : Azure Arc y seleccione la instancia del host de SQL Server.
Seleccione Control de acceso (IAM).
Selecciona Agregar>Agregar asignación de roles para agregar el rol Colaborador al usuario que configura el administrador de Microsoft Entra.
Configuración de permisos para Azure Key Vault
Cree un Azure Key Vault si aún no tiene uno. El usuario que configura el administrador de Microsoft Entra debe tener el rol Colaborador en tu Azure Key Vault. Para agregar un rol a un usuario en Azure Key Vault:
Selecciona Agregar>Asignación de roles para agregar el rol Colaborador al usuario que configura el administrador de Microsoft Entra.
Establecimiento de directivas de acceso para el host de SQL Server
En Azure Portal, vaya a la instancia de Azure Key Vault y seleccione Directivas de acceso.
Seleccione Agregar directiva de acceso.
Para permisos de clave, usa Firmar.
En Permisos de secretos, seleccione Obtener y enumerar.
Para los permisos de certificado, seleccione Obtener y enumerar.
Seleccione Siguiente.
En la página Entidad de seguridad, busque el nombre de su instancia de Máquina: Azure Arc, que es el nombre de host del host de SQL Server.
Omita la página Aplicación (opcional) seleccionando Siguiente dos veces o seleccionando Revisar y crear.
Compruebe que el "Id. de objeto" de la Entidad de seguridad coincida con el identificador de entidad de seguridad de la identidad administrada asignada a la instancia.
Para confirmarlo, vaya a la página de recursos y seleccione Vista JSON en la parte superior derecha del cuadro Essentials de la página de información general. En identidad, encontrará el valor principalId.
Seleccione Crear.
Debe seleccionar Crear para asegurarse de que se aplican los permisos. Para asegurarse de que los permisos se han almacenado, actualice la ventana del explorador y compruebe que la fila de su instancia de Azure Arc sigue presente.
Establecimiento de directivas de acceso para usuarios de Microsoft Entra
En Azure Portal, vaya a la instancia de Azure Key Vault y seleccione Directivas de acceso.
Seleccione Agregar directiva de acceso.
En Permisos de clave, seleccione Obtener, Enumerar y Crear.
En Permisos secretos, seleccione Obtener, Enumerar y Establecer.
En Permisos de certificado, seleccione Obtener, Enumerar y Crear.
En Seleccionar entidad de seguridad, agrega el usuario de Microsoft Entra que quieres usar para conectarte a SQL Server.
Seleccione Agregar y, luego, seleccione Guardar.
Configurar el administrador de Microsoft Entra para SQL Server
Las nuevas API y la funcionalidad del portal permiten a los usuarios configurar un administrador de Microsoft Entra para SQL Server sin tener que crear por separado un certificado de Azure y una aplicación de Microsoft Entra. Selecciona una pestaña para aprender a configurar un administrador de Microsoft Entra para tu SQL Server conectado a Azure Arc con la creación automática de certificados y aplicaciones.
Usa Azure Portal para configurar un administrador de Microsoft Entra, crea un certificado de Azure Key Vault y una aplicación de Microsoft Entra en el mismo proceso. Esto es necesario para usar la autenticación de Microsoft Entra con SQL Server.
En el menú del recurso, en Configuración, selecciona Microsoft Entra ID y Purview.
Selecciona Establecer administrador para abrir el panel de Microsoft Entra ID y, a continuación, elige una cuenta que se agregará como inicio de sesión de administrador a SQL Server.
Seleccione Certificado administrado por el servicio.
Seleccione Cambiar almacén de claves y seleccione el recurso de Azure Key Vault existente.
Seleccione Registro de aplicaciones administradas por el servicio.
Seleccione Guardar. Esto envía una solicitud al agente del servidor Arc, que configura la autenticación de Microsoft Entra para esa instancia de SQL Server. La operación puede tardar varios minutos en completarse; espera hasta que el proceso de guardado se confirme con Saved successfully antes de intentar un inicio de sesión de Microsoft Entra.
El registro de aplicaciones administradas por el servicio realiza lo siguiente:
Crea un certificado en el almacén de claves con un nombre que tenga la forma <hostname>-<instanceName><uniqueNumber>.
Crea una aplicación de Microsoft Entra con un nombre como <hostname>-<instanceName><uniqueNumber> y asigna los permisos necesarios para esa aplicación. Para más información, consulte Concesión de permisos de aplicación
Asigna el certificado nuevo de Azure Key Vault a la aplicación.
Guarda esta configuración en Azure Arc.
Nota:
Los certificados creados para Microsoft Entra no se rotan automáticamente. Los clientes pueden optar por proporcionar su propio certificado y aplicación para la configuración del administrador de Microsoft Entra. Para más información, consulta Tutorial: Configuración de la autenticación de Microsoft Entra con SQL Server.
Los certificados creados para la configuración de Microsoft Entra no se rotan automáticamente.
Se requiere la versión 2.37.0 de la CLI de Azure o posterior
Se requiere Az.ConnectedMachine 0.5.1 o posterior
Para instalar el módulo Az.ConnectedMachine, use az extension add --name ConnectedMachine. Para comprobar qué versión de la CLI de Azure está instalada, use az version.
Los parámetros de entrada siguientes se usan en el script de la CLI de Azure:
<applicationName>: nombre de la aplicación que se creará
<certSubjectName>: nombre del certificado que se creará
<keyVaultName>: nombre del almacén de claves. Este almacén de claves debe crearse antes de ejecutar el script
<machineName>: nombre del equipo del host de SQL Server
<resourceGroupName>: nombre del grupo de recursos que contiene la instancia de SQL Server: Azure Arc
<adminAccountName>: cuenta de administrador de Microsoft Entra que quieres establecer para SQL Server
<instanceName>: parámetro opcional para instancias con nombre de SQL Server. Use este parámetro cuando tenga una instancia con nombre. Si se omite, se usa el nombre predeterminado MSSQLSERVER
<tenantId>: parámetro opcional para el identificador de inquilino. Puedes encontrar el identificador de inquilino en Azure Portal y en el recurso de Microsoft Entra ID. En el panel Información general, debería ver el Id. de inquilino. Si se omite, el identificador de inquilino predeterminado se usa como parámetro
<subscriptionId>: parámetro opcional para el identificador de suscripción. Su identificador de suscripción se puede encontrar en el Azure Portal. Si se omite, se usa el identificador de suscripción predeterminado
Para usar el script de la CLI de Azure que aparece a continuación, guarde el script como un archivo .ps1 y ejecute el siguiente comando:
En el caso de los equipos host de SQL Server en Linux, reemplace WindowsAgent.SqlServer por LinuxAgent.SqlServer en el 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"
La ejecución del script puede tardar varios minutos en completarse. Cuando finalice el proceso, aparecerá un mensaje similar al siguiente:
Name Location ProvisioningState
---- -------- -----------------
WindowsAgent.SqlServer westus2 Succeeded
Success
Configuración de un administrador de Microsoft Entra con un certificado y una aplicación existentes mediante la CLI de Azure
Si ya tienes un certificado de Azure Key Vault existente y una aplicación de Azure que deseas usar para configurar un administrador de Microsoft Entra, puede usar el siguiente script de la 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 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"
Los certificados creados para la configuración de Microsoft Entra no se rotan automáticamente.
Los siguientes módulos son necesarios para completar este tutorial. Instale las versiones más recientes de los módulos o posteriores a la versión indicada a continuación:
Az.Accounts 3.37.0
Az.ConnectedMachine 0.5.0
Az.KeyVault 4.5.0
Az.Resources 6.0.0
Los parámetros de entrada siguientes se usan en el script de PowerShell:
<applicationName>: nombre de la aplicación que se creará
<certSubjectName>: nombre del certificado que se creará
<keyVaultName>: nombre del almacén de claves. Este almacén de claves debe crearse antes de ejecutar el script
<machineName>: nombre del equipo del host de SQL Server
<resourceGroupName>: nombre del grupo de recursos que contiene la instancia de SQL Server: Azure Arc
<adminAccountName>: cuenta de administrador de Microsoft Entra que quieres establecer para SQL Server
<instanceName>: parámetro opcional para instancias con nombre de SQL Server. Use este parámetro cuando tenga una instancia con nombre. Si se omite, se usa el nombre predeterminado MSSQLSERVER
<tenantId>: parámetro opcional para el identificador de inquilino. Puedes encontrar el identificador de inquilino en Azure Portal y en el recurso de Microsoft Entra ID. En el panel Información general, debería ver el Id. de inquilino. Si se omite, el identificador de inquilino predeterminado se usa como parámetro
<subscriptionId>: parámetro opcional para el identificador de suscripción. Su identificador de suscripción se puede encontrar en el Azure Portal. Si se omite, se usa el identificador de suscripción predeterminado
Para usar el script de PowerShell que aparece a continuación, guarde el script como un archivo .ps1 y ejecute el siguiente comando:
En el caso de los equipos host de SQL Server en Linux, reemplace WindowsAgent.SqlServer por LinuxAgent.SqlServer en el 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"
Configuración de un administrador de Microsoft Entra con un certificado y una aplicación existentes mediante PowerShell
Si ya tienes un certificado de Azure Key Vault existente y una aplicación de Azure que desea usar para configurar un administrador de Microsoft Entra, puedes usar el siguiente script de 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"
La siguiente plantilla de ARM configura un administrador de Microsoft Entra mediante un certificado de Azure Key Vault existente y una aplicación de Microsoft Entra.
Los siguientes parámetros de entrada se usan para la plantilla de ARM:
<machineName>: nombre del equipo del host de SQL Server
<Location>: ubicación del grupo de recursos de SQL Server: Azure Arc , como West US o Central US
<tenantId>: es posible encontrar el identificador de inquilino en Azure Portal y en el recurso de Microsoft Entra ID. En el panel Información general, debe ver el Identificador de inquilino.
<instanceName>: nombre de la instancia de SQL Server. El nombre predeterminado de la instancia es MSSQLSERVER
<certSubjectName>: nombre del certificado que creó
<subscriptionId>: identificador de suscripción. Su identificador de suscripción se puede encontrar en Azure Portal.
<resourceGroupName>: grupo de recursos que contiene el almacén de claves. Es posible encontrar el valor azureKeyVaultResourceUID completo en el recurso Almacén de claves, seleccionando Propiedades y copiando el identificador de recurso
<keyVaultName>: nombre del almacén de claves
<certIdentifier>: el identificador de certificado para el certificado de Azure Key Vault. Para obtener el identificador de certificado, vaya al recurso Almacén de claves y seleccione Certificados en Configuración. Seleccione la versión actual del certificado que creó y copie el valor Identificador de certificado. Para más información, consulte Agregar un certificado en Key Vault
<certSecret>: el identificador secreto del certificado; se puede encontrar en el mismo menú que el identificador de certificado
<appID>: el identificador de aplicación (cliente) de la aplicación de Microsoft Entra se puede encontrar en el menú Información general de la aplicación
<adminAccountName>: cuenta de administrador de Microsoft Entra que quieres establecer para SQL Server
<adminID>: el identificador de objeto del usuario o grupo de Microsoft Entra o el identificador de aplicación (cliente) de la aplicación si usas otra aplicación como cuenta de administrador de Microsoft Entra. Para obtener más información, consulta Tutorial: Crear usuarios de Microsoft Entra con aplicaciones de Microsoft Entra
<adminType>: usa 0 para usuarios y aplicaciones de Microsoft Entra, y 1 para grupos de Microsoft Entra
Concesión de consentimiento del administrador para la aplicación
Una vez configurado el administrador de Microsoft Entra, el uso de las credenciales de administrador de Microsoft Entra permite conectarse a SQL Server. Sin embargo, cualquier otra actividad de base de datos que implique la creación de nuevos inicios de sesión de Microsoft Entra y usuarios producirá un error hasta que se conceda el consentimiento del administrador a la aplicación de Microsoft Entra.
Nota:
Para conceder consentimiento del administrador a la aplicación, la cuenta que concede el consentimiento requiere un rol de administrador global de Microsoft Entra ID o de administrador de roles con privilegios. Estos roles son necesarios para conceder el consentimiento del administrador a la aplicación, pero no es necesario configurar el administrador de Microsoft Entra.
En Azure Portal, selecciona Microsoft Entra ID>Registros de aplicación y selecciona la aplicación creada más recientemente. La aplicación debe tener un nombre como <hostname>-<instanceName><uniqueNumber>.
Seleccione el menú Permisos de API.
Seleccione Conceder consentimiento de administrador.
Sin conceder el consentimiento del administrador a la aplicación, la creación de un inicio de sesión de Microsoft Entra o un usuario en SQL Server producirá el siguiente error:
Msg 37455, Level 16, State 1, Line 2
Server identity does not have permissions to access MS Graph.
Usar la autenticación de Microsoft Entra para conectarse a SQL Server
La autenticación de Microsoft Entra ahora está configurada para SQL Server conectado a Azure Arc. Sigue las secciones después de configurar el administrador de Microsoft Entra en el artículo Tutorial: Configuración de la autenticación de Microsoft Entra para SQL Server para conectarse a SQL Server mediante la autenticación de Microsoft Entra.