What specifically needs to be changed in the Python 3 code below in order to successfully assign the Global Administrator role for an Azure Active Directory Tenant to a given service principal?
We tried to adjust the code from the answer to this other posting so that it can run in Python 3, but we are getting the error below. This has to be agnostic with respect to operating system, so we cannot use the bash code given in the other posting. We also do not want to add a dependency on PowerShell.
And we also tried to do this with an ARM template, but @Philip pointed out that ARM templates are not allowed to assign Active Directory tenant roles.
Note that 62e90394-69f5-4237-9190-012177145e10
is the role definition id for Global Administrator of an Azure Active Directory tenant.
COMMAND AND RESULTING ERROR:
C:\path\to\directory> python .\assignADRoles.py
ERROR: unrecognized arguments: 'valid-service-principal-object-id', 'roleDefinitionId': '62e90394-69f5-4237-9190-012177145e10', 'directoryScopeId': '/'}Examples from AI knowledge base:
az rest --method get --url https://graph.microsoft.com/beta/auditLogs/directoryAudits
Get Audit log through Microsoft Graphhttps://docs.microsoft.com/en-US/cli/azure/reference-index#az_rest
Read more about the command in reference docs
C:\path\to\directory>
Note that valid-service-principal-object-id
refers to an actual valid service principal object id that is redacted here for security reasons.
Also note that the user running the command is also global administrator of the same Azure Active Directory tenant and is also owner of the only in-scope subscription.
CURRENT CODE:
# coding: utf-8import subprocess
import reansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')def callTheAPI():URI="https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments"BODY={"principalId": "valid-service-principal-object-id","roleDefinitionId": "62e90394-69f5-4237-9190-012177145e10","directoryScopeId": "/"}assignGlobalAdminCommand='az rest --method POST --uri '+URI+' --header Content-Type=application/json --body '+str(BODY)proc = subprocess.Popen(assignGlobalAdminCommand,cwd=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)while True:line = proc.stdout.readline()if line:thetext=ansi_escape.sub('', line.decode('utf-8').rstrip('\r|\n'))print(thetext)else:breakcallTheAPI()
Note that the python 3 requests module might be good to use here, but the supposedly working starting point in the other posting linked above uses the az rest
cli command, so it seemed like a good idea to get a version of that working in Python 3 first before trying to put the same API call into the requests module.
POWERSHELL VERSION THAT WORKS:
Here are the successful results of running the az rest
cli command using PowerShell from the answer to this other posting:
PS C:\path\to\directory> $Body = @{
>> "roleDefinitionId" = "62e90394-69f5-4237-9190-012177145e10";
>> "principalId" = "valid-service-principal-object-id";
>> "directoryScopeId" = "/"
>> } | ConvertTo-Json -Compress
PS C:\path\to\directory> $Body = $Body.Replace('"', '\"')
PS C:\path\to\directory> az rest -m post -u "https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments" -b "$Body"
{"@odata.context": "https://graph.microsoft.com/beta/$metadata#roleManagement/directory/roleAssignments/$entity","directoryScopeId": "/","id": "long-alpha-numeric-hash-id","principalId": "valid-service-principal-object-id","principalOrganizationId": "valid-ad-tenant-id","resourceScope": "/","roleDefinitionId": "62e90394-69f5-4237-9190-012177145e10"
}
PS C:\path\to\directory>
But even though this PowerShell invocation of the az rest
cli command works, the Python code above still gives an error. When we paste the string result of the PowerShell $Body = @{ "roleDefinitionId" = "62e90394-69f5-4237-9190-012177145e10"; "principalId" = "valid-service-principal-object-id"; "directoryScopeId" = "/" } | ConvertTo-Json -Compress
command from above into the Python 3 code given above, we get the same error.
How can this working Powershell example be translated into Python 3 starting with the Python 3 code that is given above in the OP?