How to create a service principal name for Azure Stack Hub using PowerShell
This article explains how to create a service principal name (SPN) to manage Azure and Azure Stack Hub using PowerShell.
It will guide you through the creation of:
An Azure application
A service principal name
Role assignment
Permissions
What is a service principal name?
An Azure SPN is a security identity used by user-created applications, services, and automation tools to access specific Azure resources. Think of it as a 'user identity' (username and password or certificate) with a specific role, and tightly controlled permissions. It only needs to be able to do specific things, unlike a general user identity. It improves security if you grant it only the minimum permissions level needed to perform its management tasks.
To log in and manage your resources via SPN you'll need to create an Azure application and then assign SPN to it. Only then will you be able to perform tasks against your environment.
Prerequisites
Prerequisites from a Windows-based external client are:
PowerShell 5.1, AzureStack and Azure AD PowerShell Modules
Azure AD PowerShell Module:
Install-Module -Name AzureAD -Force -Verbose
Azure Active Directory
Declare variables
Enter details below to provide values for the variables in the scripts in this article:
Variable name | Variable description | Input |
---|---|---|
$PublicAzureAdminUsername | The username of a user with admin privileges for public Azure | |
$PublicAzureAdminPassword | The password of a user with admin privileges for public Azure | |
$AzureStackUsernameAdmin | The username of a user with admin privileges for Azure Stack Hub | |
$AzureStackUserPasswordAdmin | The password of a user with admin privileges for Azure Stack Hub | |
$AppName | The name of the SPN to be created | |
$AppURL | The homepage URL of the SPN to be created | |
$AppPassword | The app password for the SPN | |
$TenantDomain | Your Azure Active Directory tenant domain | |
$ArmEndpoint | The Azure Resource Manager endpoint for Azure Stack Hub | |
$PublicAzureResourceGroup | Resource group to be created in public Azure to test the SPN | |
$AzureStackResourceGroup | Resource group to be created in Azure Stack Hub to test the SPN | |
$PublicAzureRegion | Region in public Azure to create the test resource group in | |
$PublicAzureRole | Role to assign SPN in public Azure | |
$AzureStackRole | Role to assign SPN in Azure Stack Hub |
Create a service principal name
Overview of the creation process for public Azure and Azure Stack Hub SPN
The following steps outline the process for the Azure and Azure Stack Hub SPN creation code.
Declare your variables accordingly.
Log in to your public Azure Subscription.
Create your Azure application.
Create a new service principal name for the Azure application.
Assign the appropriate Role to your service principal name.
Grant Azure AD permissions to your Azure application.
Log in to the public Azure using the SPN account.
Create a new resource group using the SPN account in the public Azure.
Remove the resource group you just created from the public Azure.
Create your Azure Stack Hub environment.
Log in to your Azure Stack Hub Subscription with administrator user credentials (needs to have Owner role).
Assign the appropriate Role to your Azure application inside your Azure Stack Hub Subscription.
Log in to your Azure Stack Hub Subscription using the SPN account.
Create a new resource group using the SPN account in Azure Stack Hub.
Remove the resource group you just created from Azure Stack Hub.
Azure and Azure Stack Hub SPN creation code
# Declare variables
$AppName = ""
$AppURL = ""
# You can also generate a GUID app password by using: (New-Guid).Guid
$AppPassword = ""
$AppPasswordSecure = ConvertTo-SecureString -String $AppPassword -AsPlainText -Force
$TenantDomain = ""
$ArmEndpoint = ""
$PublicAzureResourceGroup = ""
$AzureStackResourceGroup = ""
$PublicAzureRegion = ""
$PublicAzureRole = ""
$AzureStackRole = ""
# Create your Public Azure admin credentials in order to log in to your Azure subscription which you will be creating your SPN in
$PublicAzureAdminUsername = ""
$PublicAzureAdminPassword = ConvertTo-SecureString -String "" -AsPlainText -Force
$PublicAzureAdminCreds = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $PublicAzureAdminUsername, $PublicAzureAdminPassword
# Log in to your public Azure subscription and Azure AD you will be creating your SPN in
Connect-AzureAD -Credential $PublicAzureAdminCreds -TenantId $TenantDomain
Connect-AzAccount -Credential $PublicAzureAdminCreds
# List subscriptions
$SubId = Get-AzSubscription | Select-Object -Property SubscriptionId, TenantId
# Set context to be your active subscription
Get-AzSubscription -SubscriptionId $SubId.SubscriptionId -TenantId $SubId.TenantId | Set-AzContext
# Create an Azure AD application, this is the object that you need in order to set the SPN record against
try {
$App = New-AzADApplication -DisplayName $AppName -HomePage $AppUrl -IdentifierUris $AppUrl -Password $AppPasswordSecure
$AppGet = Get-AzADApplication -ObjectId $App.ObjectId.Guid
$AppGet
# Create a Service Principal Name (SPN) for the application created earlier
$SPN = New-AzADServicePrincipal -ApplicationId $AppGet.AppId
Write-Output -InputObject "Waiting for the SPN to be created..."
Start-Sleep -Seconds 35
# Assign the Service Principal Name a role
New-AzRoleAssignment -RoleDefinitionName $PublicAzureRole -ServicePrincipalName $AppGet.AppId | Out-Null
Get-AzRoleAssignment -ObjectId $SPN.Id.Guid
}
catch {
Write-Error -Message "$($_.Exception.Message)"
break
}
# Grant permission to Azure Active Directory to SPN
$Required = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$Required.ResourceAppId = "00000002-0000-0000-c000-000000000000"
$Acc1 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "5778995a-e1bf-45b8-affa-663a9f3f4d04", "Role"
$Acc2 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "abefe9df-d5a9-41c6-a60b-27b38eac3efb", "Role"
$Acc3 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "78c8a3c8-a07e-4b9e-af1b-b5ccab50a175", "Role"
$Acc4 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "1138cb37-bd11-4084-a2b7-9f71582aeddb", "Role"
$Acc5 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "9728c0c4-a06b-4e0e-8d1b-3d694e8ec207", "Role"
$Acc6 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "824c81eb-e3f8-4ee6-8f6d-de7f50d565b7", "Role"
$Acc7 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "1cda74f2-2616-4834-b122-5cb1b07f8a59", "Role"
$Acc8 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "aaff0dfd-0295-48b6-a5cc-9f465bc87928", "Role"
$Acc9 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "a42657d6-7f20-40e3-b6f0-cee03008a62a", "Scope"
$Acc10 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "5778995a-e1bf-45b8-affa-663a9f3f4d04", "Scope"
$Acc11 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "78c8a3c8-a07e-4b9e-af1b-b5ccab50a175", "Scope"
$Acc12 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "970d6fa6-214a-4a9b-8513-08fad511e2fd", "Scope"
$Acc13 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "6234d376-f627-4f0f-90e0-dff25c5211a3", "Scope"
$Acc14 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "c582532d-9d9e-43bd-a97c-2667a28ce295", "Scope"
$Acc15 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "cba73afc-7f69-4d86-8450-4978e04ecd1a", "Scope"
$Acc16 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "311a71cc-e848-46a1-bdf8-97ff7156d8e6", "Scope"
$Acc17 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList "2d05a661-f651-4d57-a595-489c91eda336", "Scope"
$Required.ResourceAccess = $Acc1, $Acc2, $Acc3, $Acc4, $Acc5, $Acc6, $Acc7, $Acc8, $Acc9, $Acc10, $Acc11, $Acc12, $Acc13, $Acc14, $Acc15, $Acc16, $Acc17
Set-AzADApplication -ObjectId $AppGet.ObjectId -RequiredResourceAccess $Required | Out-Null
Get-AzADApplication -ObjectId $AppGet.ObjectId | Select-Object -Property *
# Create your SPN credentials login
# Note: Username is "ApplicationId"
$SPNCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AppGet.AppId, $AppPasswordSecure
# Log in to public Azure using SPN account
Connect-AzAccount -Credential $SPNCreds -ServicePrincipal -TenantId $TenantDomain
# Test your SPN account by creating a new resource group in public Azure
New-AzResourceGroup -Name $PublicAzureResourceGroup -Location $PublicAzureRegion
# Remove test resource group
Remove-AzResourceGroup -Name $PublicAzureResourceGroup -Force
# Create Azure Stack Hub environment so that you can log in to it
Add-AzEnvironment -Name "AzureStackUser" -ArmEndpoint $ArmEndpoint
# Create your Azure Stack Hub Admin (Subscription Owner) credentials
# Note: This account CAN, but does not have to, be the same as your public Azure account
$AzureStackUsernameAdmin = ""
$AzureStackUserPasswordAdmin = ConvertTo-SecureString -String "" -AsPlainText -Force
$AzureStackCredAdmin = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AzureStackUsernameAdmin, $AzureStackUserPasswordAdmin
# Login to Azure Stack Hub as Admin (Subscription Owner)
Connect-AzAccount -EnvironmentName "AzureStackUser" -Credential $AzureStackCredAdmin
# Find application details from Azure AD
$AzureStackApp = Get-AzADApplication -DisplayNameStartWith $AppGet.DisplayName
# Find Object Id of your Service Principal Name in Azure Stack Hub
$SPNAzureStackGet = Get-AzADServicePrincipal -SearchString $AzureStackApp.DisplayName
$SPNAzureStackGet
# Assign the Service Principal Name a role i.e. Owner, Contributor, Reader, etc. - In Azure Stack Hub
New-AzRoleAssignment -RoleDefinitionName $AzureStackRole -ServicePrincipalName $AzureStackApp.ApplicationId.Guid | Out-Null
Get-AzRoleAssignment -ObjectId $SPNAzureStackGet.Id.Guid
# Log in to Azure Stack Hub using SPN account
Connect-AzAccount -EnvironmentName "AzureStackUser" -Credential $SPNCreds -ServicePrincipal -TenantId $TenantDomain
# Pull location from environment
$Location = (Get-AzLocation).Location
# Test your SPN account by creating a new resource group in Azure Stack Hub
New-AzResourceGroup -Name $AzureStackResourceGroup -Location $Location
# Remove test resource group
Remove-AzResourceGroup -Name $AzureStackResourceGroup -Force
# Export data of your SPN
$SPN = [PSCustomObject]@{
ArmEndpoint = $ArmEndpoint
SubscriptionId = $SubId.SubscriptionId
ClientId = $AppGet.AppId
ClientSecret = $AppPassword
TenantId = $SubId.TenantId
}
# Present SPN credentials
foreach ($Item in $SPN) {
Write-Output -InputObject $Item
}
Feedback
If you find a problem with this article, click Improve this Doc to make the change yourself or raise an issue in GitHub. If you have an idea for how we could improve any of our services, send an email to feedback@ukcloud.com.