1

我正在运行以下命令

$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 Active 目录中注册。要获取 Azure Active Directory 组的列表,请使用 Get-AzADGroup,或者要获取 Azure Active Directory 用户的列表,请使用 Get-AzADUser。在 line:1 char:1 + Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName 'data ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 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 权限没有帮助。

4

2 回答 2

3

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

在此处输入图像描述

Azure powershellSet-AzSqlServerActiveDirectoryAdministrator将调用 Azure AD GraphgetObjectsByObjectIds: Get objects from a list of object IDs来验证对象是否正确。如果结果的类型不是Azure AD security group,它会进一步调用Get a user。所以如果结果的类型是服务主体,它也会调用Get a user,那么就会导致问题。您可以使用 fiddler 工具来捕获请求,如下所示。

在此处输入图像描述

在此处输入图像描述

因此,如果您想使用Set-AzSqlServerActiveDirectoryAdministrator,您可以在 Azure AD 中创建一个security group(不是 office 组),将服务主体添加到该组,然后将该组添加到 sql server admin,如 @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

注意:要运行上面的脚本,你需要给你的AD App一个 Directory.ReadWrite.All Application权限( Azure Active Directory Graphnot Microsoft Graph),并且会有一些延迟,稍等片刻再测试。 在此处输入图像描述

在此处输入图像描述

于 2020-05-11T07:53:35.470 回答
0

很可能虽然我无法确认这一点,因为我不是 100% 确定,但我认为 set-azsqlserveractivedirectoryadministrator 仅按 azaduser 或 azadgroup 过滤。它可能不会搜索服务主体。但是,如果您想完成此操作,则可以作为一种解决方法。您可以创建一个名为 dbas 或其他名称的天蓝色广告组。并将服务主体添加到该组。然后使用该 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% 直接回答您的要求,但我相信这是一个可行的解决方法,希望符合您的要求。

于 2020-05-10T14:55:35.437 回答