• Improve this Doc

    Show / Hide Table of Contents

    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

      • Configure the Azure Stack Hub user's PowerShell environment

      • 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

    • Public Azure and Azure Stack Hub SPN
    • Azure Stack Hub SPN

    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.

    1. Declare your variables accordingly.

    2. Log in to your public Azure Subscription.

    3. Create your Azure application.

    4. Create a new service principal name for the Azure application.

    5. Assign the appropriate Role to your service principal name.

    6. Grant Azure AD permissions to your Azure application.

    7. Log in to the public Azure using the SPN account.

    8. Create a new resource group using the SPN account in the public Azure.

    9. Remove the resource group you just created from the public Azure.

    10. Create your Azure Stack Hub environment.

    11. Log in to your Azure Stack Hub Subscription with administrator user credentials (needs to have Owner role).

    12. Assign the appropriate Role to your Azure application inside your Azure Stack Hub Subscription.

    13. Log in to your Azure Stack Hub Subscription using the SPN account.

    14. Create a new resource group using the SPN account in Azure Stack Hub.

    15. Remove the resource group you just created from Azure Stack Hub.

    Azure and Azure Stack Hub SPN creation code

    # Declare variables
    $AppName = "TestApp"
    $AppURL = "https://test.app"
    # You can also generate a GUID app password by using: (New-Guid).Guid
    $AppPassword = "Password123!"
    $AppPasswordSecure = ConvertTo-SecureString -String $AppPassword -AsPlainText -Force
    $TenantDomain = "contoso.onmicrosoft.com"
    $ArmEndpoint = "https://management.frn00006.azure.ukcloud.com"
    $PublicAzureResourceGroup = "RGTest01"
    $AzureStackResourceGroup = "RGTest01"
    $PublicAzureRegion = "ukwest"
    $PublicAzureRole = "Owner"
    $AzureStackRole = "Owner"
    
    # Create your Public Azure admin credentials in order to log in to your Azure subscription which you will be creating your SPN in
    $PublicAzureAdminUsername = "user@contoso.onmicrosoft.com"
    $PublicAzureAdminPassword = ConvertTo-SecureString -String "Password123!" -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 = "user@contoso.onmicrosoft.com"
    $AzureStackUserPasswordAdmin = ConvertTo-SecureString -String "Password123!" -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
    }
    

    Overview of the creation process for Azure Stack Hub SPN

    1. Declare your variables accordingly.

    2. Create your Azure Stack Hub environment.

    3. Log in to your Azure Stack Hub Subscription with administrator user credentials (needs to have Owner role).

    4. Create your Azure application.

    5. Create a new service principal name for the Azure application.

    6. Assign the appropriate Role to your service principal name.

    7. Log in to your Azure Stack Hub Subscription using the SPN account.

    8. Create a new resource group using the SPN account in Azure Stack Hub.

    9. Remove the resource group you just created from Azure Stack Hub.

    Azure Stack Hub SPN creation code

    # Declare variables
    $AppName = "TestApp"
    $AppURL = "https://test.app"
    # You can also generate a GUID app password by using: (New-Guid).Guid
    $AppPassword = "Password123!"
    $AppPasswordSecure = ConvertTo-SecureString -String $AppPassword -AsPlainText -Force
    $TenantDomain = "contoso.onmicrosoft.com"
    $ArmEndpoint = "https://management.frn00006.azure.ukcloud.com"
    $AzureStackResourceGroup = "RGTest01"
    $AzureStackRole = "Owner"
    
    # 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 = "user@contoso.onmicrosoft.com"
    $AzureStackUserPasswordAdmin = ConvertTo-SecureString -String "Password123!" -AsPlainText -Force
    $AzureStackCredAdmin = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AzureStackUsernameAdmin, $AzureStackUserPasswordAdmin
    
    # Login to Azure Stack Hub as admin (Subscription Owner) and Azure AD
    Connect-AzureAD -Credential $AzureStackCredAdmin -TenantId $TenantDomain
    Connect-AzAccount -EnvironmentName "AzureStackUser" -Credential $AzureStackCredAdmin
    
    # 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 "Owner" -ServicePrincipalName $AppGet.AppId | Out-Null
        Get-AzRoleAssignment -ObjectId $SPN.Id.Guid
    }
    catch {
        Write-Error -Message "$($_.Exception.Message)"
        break
    }
    
    # Create your SPN credentials login
    # Note: (Username is "ApplicationId")
    $AzureStackCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AppGet.AppId, $AppPasswordSecure
    
    # Log in to Azure Stack Hub using SPN account
    Connect-AzAccount -EnvironmentName "AzureStackUser" -Credential $AzureStackCred -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.

    ☀
    ☾
    Generated by DocFX
    Back to top
    © UKCloud Ltd, 2021. All Rights Reserved.
    Privacy Policy. Terms of Use. Contribute.

    The UKCloud Knowledge Centre uses cookies to ensure that we give you the best experience on our website. If you continue we assume that you consent to receive all cookies on this website.