Set-AzSqlServerActiveDirectoryAdministrator:找不到 Azure Active Directory 对象 'service_principal_name'

Set-AzSqlServerActiveDirectoryAdministrator : Cannot find the Azure Active Directory object 'service_principal_name'

我是运行以下命令

$sp = az ad sp show --id $env:ARM_CLIENT_ID --query '{objectId: objectId, displayName: displayName}'
az sql server ad-admin create --resource-group data-eastus2 `
    --server-name data-eastus2-sqlsvr `
    --display-name $sp.name `
    --object-id $sp.id

无需向服务主体提供任何 Graph API 权限即可完美运行。 尝试使用 Az Powershell 模块模仿此功能,通过 运行 以下

Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName 'data-eastus2'  -ServerName 'data-eastus2-sqlsvr' -DisplayName $sp.name -ObjectId $sp.id

产生异常

Set-AzSqlServerActiveDirectoryAdministrator:找不到 Azure Active Directory 对象 'service_principal_name'。请确保您授权的用户或组已在 当前订阅的 Azure 活动目录。要获取 Azure Active Directory 组的列表,请使用 Get-AzADGroup,或 要获取 Azure Active Directory 用户列表,请使用 Get-AzADUser。 在 line:1 char:1 + Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName '数据... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ + CategoryInfo:CloseError:(:) [Set-AzSqlServer...ryAdministrator]、ArgumentException + FullyQualifiedErrorId : Microsoft.Azure.Commands.Sql.ServerActiveDirectoryAdministrator.Cmdlet.SetAzureSqlServerActiveDirectoryAdministrator

提供 Azure Active Directory Graph - Directory.Read.All 和 Microsoft Graph - Directory.Read.All API 权限没有帮助。

最有可能的是,虽然我不能确认这一点,因为我不是 100% 确定,但我认为 set-azsqlserveractivedirectoryadministrator,只能通过 azaduser 或 azadgroup 进行过滤。它可能不会搜索服务主体。 作为解决方法,如果你想完成这个。您可以创建一个名为 dbas 之类的 azure 广告组。并将服务主体添加到该组。然后使用 set-azsql 命令将该组添加到 sql 服务器。

所以像这样:

$sp = Get-AzADServicePrincipal -DisplayName "theserviceprincipalname"
Add-AzADGroupMember -MemberObjectId $($sp.id) -TargetGroupDisplayName "AAD Group Name"

Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName 'data-eastus2'  -ServerName 'data-eastus2-sqlsvr' -DisplayName "AAD Group Name"

希望这对你有用,不是 100% 直接回答你的问题,但我相信这是一个符合你的要求的可行解决方法。

Azure CLI az sql server ad-admin create 不会调用 Azure AD Graph 来验证您传递的参数,它只会调用 REST API Server Azure AD Administrators - Create Or Update 来设置管理员。即使你传错了--display-name--object-id(也需要是Guid格式),命令也能正常工作。您可以使用 --debug 参数查看详细信息。

Azure powershell Set-AzSqlServerActiveDirectoryAdministrator 将调用 Azure AD Graph getObjectsByObjectIds: Get objects from a list of object IDs to validate if the object is correct or not. And if the result's type is not an Azure AD security group, it will further call Get a user. So if the result's type is a service principal, it will also call Get a user,然后它会导致问题。您可以使用 fiddler 工具来捕获如下所示的 reuqest。

因此,如果您想使用 Set-AzSqlServerActiveDirectoryAdministrator,您可以在 Azure AD 中创建一个 security group(不是办公室组),将服务主体添加到组中,然后将组添加到sql 服务器管理员,如@alphaz18 的回复所述。

$sp = Get-AzADServicePrincipal -ObjectId "<object-id>"
$group = Get-AzADGroup -DisplayName "joysec"
Add-AzADGroupMember -TargetGroupObjectId $group.Id -MemberObjectId $sp.Id
Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName "<groupname>" -ServerName "<servername>" -DisplayName $group.DisplayName -ObjectId $group.Id

注意: 要运行上面的脚本,你需要给一个 Directory.ReadWrite.All 申请权限Azure Active Directory Graph(不是Microsoft Graph)的AD App,有一些延迟,稍等片刻再测试。