How does Azure PowerShell work with username/password based auth?

Question

I want to understand how Azure PowerShell makes Azure API calls using AAD username/password based credentials.

My understanding is that an app needs a client-id before it can make Azure API calls. This client ID must be registered with a user’s account.

Does Azure PowerShell have a client-id? If so, how does it work without explicitly registering it with Azure accounts? Is it a special id that has been whitelisted across accounts?

Solution

You don't need to create an application registration in Azure Active Directory for Azure Powershell. To leverage username/password credentials of an Azure AD user, you can use the Add-AzureAccount cmdlet:

$username = "admin@your_account.onmicrosoft.com"
$password = "SuperSecretPassword" | ConvertTo-SecureString -AsPlainText -Force

$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password 
Add-AzureAccount -Credential $credential 

Just make sure you have the latest version of the Azure PowerShell module installed, and the account you're using is an organizational account (as opposed to a Microsoft account) or a native Azure AD user.

To answer the last part of your question, there is a well-known client ID for Azure PowerShell ("1950a258-227b-4e31-a9cf-717495945fc2"). It's hard coded in the Azure Powershell module and can be used to authenticate PowerShell scripts to Azure AD when they invoke the Azure Management APIs directly:

# Load Active Directory Authentication Library (ADAL) Assemblies
$adal = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$adalforms = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll"
[System.Reflection.Assembly]::LoadFrom($adal)
[System.Reflection.Assembly]::LoadFrom($adalforms)

# Set Azure AD Tenant name
$adTenant = "yourtenant.onmicrosoft.com" 

# Set well-known client ID for Azure PowerShell
$clientId = "1950a258-227b-4e31-a9cf-717495945fc2" 

# Set redirect URI for Azure PowerShell
$redirectUri = "urn:ietf:wg:oauth:2.0:oob"

# Set Resource URI to Azure Service Management API
$resourceAppIdURI = "https://management.core.windows.net/"

# Set Authority to Azure AD Tenant
$authority = "https://login.windows.net/$adTenant"

# Set user credentials (*** obviously you wouldn't have the password in clear text in a production script ***)
$userName = "admin@your_tenant.onmicrosoft.com"
$password = "SecretPassword"
$creds = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential" -ArgumentList $userName,$password

# Create AuthenticationContext tied to Azure AD Tenant
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority

# Acquire token
$authResult = $authContext.AcquireToken($resourceAppIdURI,$clientId,$creds)