Typically if you want to create an account to sign in to MSOL (for Azure AD - because you can't use the Live ID) you log in to the portal, create an account, make that account a co-administrator, and then log into MSOL.
Is it possible to perform those steps entirely through Powershell?
So can I log in with a Live ID, then create an account I can log into AAD with purely from Powershell. ie can I go from a brand new Azure subscription, to logging in to AAD without going near the portal.
My only thought so far has been to create a service principal, but I haven't figured out how to give that directory permission without the portal or an admin account for MSOL.
Failing this, a canonical answer as to why this isn't possible will suffice.
You can use the Graph API to add a user to the default AD of you subscription, and then, you can use the REST API to assign that user to be a classic administrator. Here is the PowerShell script I wrote.
$subscriptionID = "<the Subscription ID>"
# This is the tenant id of you subscription
$tenantID = "<the tenant id of your subscription>"
# The login endpoint. It can be https://login.microsoftonline.com/, too. $loginEndpoint = "https://login.windows.net/"
# This is the resource URI for Graph API.
$graphResourceURI = "https://graph.windows.net/"
# This is the resource URI for Azure Management REST API. It can be https://management.azure.com/ for ARM
$managementResourceURI = "https://management.core.windows.net/"
# The redirect URI for PowerShell
$redirectURI = "urn:ietf:wg:oauth:2.0:oob"
# The common client id.
$clientID = "1950a258-227b-4e31-a9cf-717495945fc2"
# the URL for requesting the Authorization code.
$authorizeURLGraph = $loginEndpoint+$tenantID+"/oauth2/authorize?response_type=code&client_id="+$clientID+"&resource="+[system.uri]::EscapeDataString($graphResourceURI)+"&redirect_uri="+[system.uri]::EscapeDataString($redirectURI)
# Create an IE session in PowerShell
$ie = new-object -ComObject "InternetExplorer.Application"
# Set the IE session to be silent, so that it won't prompt for confirmation.
$ie.silent = $true
# Browsing the URL for requesting the Authorization code.
$ie.navigate($authorizeURLGraph)
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
# Getting the Parameters from the redirect URL.
$parameters = $ie.LocationURL.Substring($redirectURI.length + 1).split("{&}")
# Identify Authorization code.
foreach ($parameter in $parameters){
if ($parameter.substring(0,5) -eq "code="){
$code = $parameter.substring(5)
break
}
}
# the URL for requesting access token.
$tokenURL = $loginEndpoint+$tenantID+"/oauth2/token"
# the token request body.
$body = "grant_type=authorization_code&client_id="+$clientID+"&code="+$code+"&redirect_uri="+[system.uri]::EscapeDataString($redirectURI)+"&resource="+[system.uri]::EscapeDataString($graphResourceURI)
# the token request headers.
$headers = @{"Content-Type"="application/x-www-form-urlencoded"}
# Acquiring an access token.
$authenticationResult = Invoke-RestMethod -Method POST -Uri $tokenURL -Headers $headers -Body $body
# Use the access token to setup headers for your http request.
$authHeader = $authenticationResult.token_type + " " + $authenticationResult.access_token
$headers = @{"Authorization"=$authHeader; "Content-Type"="application/json"}
# Create a user.
Invoke-RestMethod -Method POST -Uri "https://graph.windows.net/$tenantID/users?api-version=1.6-internal" `
-Headers $headers -InFile ./user.json
# The same as above, except the resource URI.
$authorizeURLGraph = $loginEndpoint+$tenantID+"/oauth2/authorize?response_type=code&client_id="+$clientID+"&resource="+[system.uri]::EscapeDataString($managementResourceURI)+"&redirect_uri="+[system.uri]::EscapeDataString($redirectURI)
$ie = new-object -ComObject "InternetExplorer.Application"
$ie.silent = $true
$ie.navigate($authorizeURLGraph)
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
$parameters = $ie.LocationURL.Substring($redirectURI.length + 1).split("{&}")
foreach ($parameter in $parameters){
if ($parameter.substring(0,5) -eq "code="){
$code = $parameter.substring(5)
break
}
}
$tokenURL = $loginEndpoint+$tenantID+"/oauth2/token"
$body = "grant_type=authorization_code&client_id="+$clientID+"&code="+$code+"&redirect_uri="+[system.uri]::EscapeDataString($redirectURI)+"&resource="+[system.uri]::EscapeDataString($managementResourceURI)
$headers = @{"Content-Type"="application/x-www-form-urlencoded"}
$authenticationResult = Invoke-RestMethod -Method POST -Uri $tokenURL -Headers $headers -Body $body
$authHeader = $authenticationResult.token_type + " " + $authenticationResult.access_token
$headers = @{"Authorization"=$authHeader; "Content-Type"="application/json"}
# Assign the new user to be co-admin.
Invoke-RestMethod -Method PUT -Uri "https://management.azure.com/subscriptions/$subscriptionID/providers/Microsoft.Authorization/classicAdministrators/newAdmin?api-version=2015-06-01" `
-Headers $headers -InFile ./admin.json
Here is a sample of user.json and admin.json.
user.json:
{
"accountEnabled": true,
"displayName": "graphtest",
"mailNickname": "graphtest",
"passwordProfile": {
"password": "Test1234",
"forceChangePasswordNextLogin": false
},
"userPrincipalName": "graphtest@<subdomain>.onmicrosoft.com"
}
admin.json
{
"properties": {
"emailAddress": "graphtest@<subdomain>.onmicrosoft.com",
"role": "CoAdministrator"
},
"type": "Microsoft.Authorization/classicAdministrators",
"name": "newAdmin"
}
This PowerShell script depends on your IE session, so before you use this script, you should log into your live id in IE. I am still looking at the in private browsing. Hopefully, I will be able to login with PowerShell, not IE session.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.