简体   繁体   中英

Create account and sign in to MSOL purely from Powershell

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM