Recently I’ve published a few posts on Upgrade Analytics, like deploying the client script and how to setup a connection between ConfigMgr Current Branch (version 1610+) and Upgrade Analytics. Following down the same path, today I’m sharing the script that I’m using to create the required Azure AD application that the ConfigMgr connection leverages in order to communicate with Upgrade Analytics. With this script, you’re able to setup the connection somewhat faster than manually process described in the other blog post.

When setting up the connection between ConfigMgr and Upgrade Analytics, the wizard in ConfigMgr requires you to enter a Tenant name, Client ID and Secret Key. When using the script in this post, and the execution of it is successful, it will output the required information for the wizard in ConfigMgr.

Requirements

Since this script targets to create an Azure AD web application leveraging Azure Resource Manager, it’s required that the AzureRM module is installed where the script is invoked. The following method can be used when installing the AzureRM module:

Install-Module -Name AzureRM -AllowClobber

The -AllowClobber parameter should be used if the module is installed on a Windows 10 version 1607 system, since portions of what’s included in AzureRM is already installed in the operating system.

Script

Save the script below as e.g. New-AADAppForUpgradeAnalytics.ps1. You can also find the script in my PowerShell repository on GitHub.

<#
.SYNOPSIS
    Use this script to create an Azure AD application required for setting up the connection between ConfigMgr and Upgrade Analytics.

.DESCRIPTION
    This script requires the Azure Resource Manager module to be installed. Use 'Install-Module AzureRM' to install it.

.PARAMETER AppDisplayName
    Name of the Azure AD application to be created.

.PARAMETER ResourceGroupName
    Name of a Resource Group in Azure that the OMS workspace used for Upgrade Analytics belongs to.

.PARAMETER AzureSubscriptionId
    Azure subscription Id, can be retrieved by running the Get-AzureRmSubscription cmdlet.

.EXAMPLE
    .\New-AADAppForUpgradeAnalytics.ps1 -AppDisplayName "ConfigMgrUpgradeAnalytics" -ResourceGroupName "UpgradeAnalytics" -AzureSubscriptionId ""

.NOTES
    FileName:    New-AADAppForUpgradeAnalytics.ps1
    Author:      Nickolaj Andersen
    Contact:     @NickolajA
    Created:     2016-11-22
    Updated:     2016-11-22
    
    Version history:
    1.0.0 - (2016-11-22) Script created
#>
[CmdletBinding(SupportsShouldProcess=$true)]
param(
    [parameter(Mandatory=$true, HelpMessage="Name of the Azure AD application to be created.")]
    [ValidateNotNullOrEmpty()]
    [string]$AppDisplayName,

    [parameter(Mandatory=$true, HelpMessage="Name of a Resource Group in Azure that the OMS workspace used for Upgrade Analytics belongs to.")]
    [ValidateNotNullOrEmpty()]
    [string]$ResourceGroupName,

    [parameter(Mandatory=$true, HelpMessage="Azure subscription Id, can be retrieved by running the Get-AzureRmSubscription cmdlet.")]
    [ValidateNotNullOrEmpty()]
    [string]$AzureSubscriptionId
)
Begin {
    # Authenticate against an Azure subscription
    try {
        Write-Verbose -Message "Aquiring required credentials for logging on to Azure"
        $AzureLogin = Login-AzureRmAccount -ErrorAction Stop
    }
    catch [System.Exception] {
        Write-Warning -Message $_.Exception.Message ; break
    }
}
Process {
    # Functions
    function New-SecretKey {
        param(
            [parameter(Mandatory=$true)]
            [int]$Length,

            [parameter(Mandatory=$true)]
            [int]$SpecialCharacters
        )
        try {
            # Load required assembly
            Add-Type -AssemblyName "System.Web" -ErrorAction Stop

            # Generate password
            $Password = [Web.Security.Membership]::GeneratePassword($Length, $SpecialCharacters)

            # return password
            return $Password
        }
        catch [System.Exception] {
            Write-Warning -Message $_.Exception.Message ; break
        }
    }

    # Validate Azure context
    try {
        Write-Verbose -Message "Validating Azure context"
        $AzureContext = Get-AzureRmContext -ErrorAction Stop
        if ($AzureContext -ne $null) {
            # Validate Azure subscription Id
            Write-Verbose -Message "Attempting to locate subscription for '$($AzureSubscriptionId)'"
            $AzureSubscription = Get-AzureRmSubscription -SubscriptionId $AzureSubscriptionId -ErrorAction Stop
            if ($AzureSubscription -ne $null) {
                # Validate Resource Group exists
                try {
                    Write-Verbose -Message "Attempting to locate resource group '$($ResourceGroupName)'"
                    $AzureResourceGroup = Get-AzureRmResourceGroup -Name $ResourceGroupName -ErrorAction Stop
                    if ($AzureResourceGroup -ne $null) {
                        # Create new Azure AD Application
                        try {
                            # Generate secret key
                            $AppPassword = New-SecretKey -Length 24 -SpecialCharacters 3

                            Write-Verbose -Message "Creating new Azure AD application '$($AppDisplayName)'"
                            $AADApplicationArgs = @{
                                DisplayName = $AppDisplayName
                                HomePage = "https://localhost:8000"
                                IdentifierUris = "https://localhost:8001"
                                Password = $AppPassword
                                ErrorAction = "Stop"
                            }
                            $AADApplication = New-AzureRmADApplication @AADApplicationArgs
                        }
                        catch [System.Exception] {
                            Write-Warning -Message $_.Exception.Message ; break
                        }

                        # Create a new Service Principal for the application
                        try {
                            Write-Verbose -Message "Creating new service principal for application with Id '$($AADApplication.ApplicationId)'"
                            $AADServicePrincipal = New-AzureRmADServicePrincipal -ApplicationId $AADApplication.ApplicationId -ErrorAction Stop
                        }
                        catch [System.Exception] {
                            Write-Warning -Message $_.Exception.Message ; break
                        }
                        
                        # Create role assignment between application and resource group
                        try {
                            do {
                                # Validate that the service principal got created
                                Write-Verbose -Message "Attempting to locate service principal, retry in 15 seconds"
                                $ServicePrincipal = Get-AzureRmADServicePrincipal -ObjectId $AADServicePrincipal.Id

                                # Sleep for 15 seconds
                                Start-Sleep -Seconds 15
                            }
                            while ($ServicePrincipal -eq $null)

                            Write-Verbose -Message "Creating new role assignment between application Id '$($AADApplication.ApplicationId)' and resource group '$($AzureResourceGroup.ResourceGroupName)'"
                            $AzureRoleAssignmentArgs = @{
                                ResourceGroupName = $AzureResourceGroup.ResourceGroupName
                                ServicePrincipalName = $AADApplication.ApplicationId
                                RoleDefinitionName = "Contributor"
                                ErrorAction = "Stop"
                            }
                            $AzureRoleAssignment = New-AzureRmRoleAssignment @AzureRoleAssignmentArgs
                            Write-Verbose -Message "Successfully created Azure AD application and assigned Contributor role for specified resource group"
                        }
                        catch [System.Exception] {
                            Write-Warning -Message $_.Exception.Message ; break
                        }

                        # Return information required for ConfigMgr connection setup with Upgrade Analytics
                        $TenantName = (Get-AzureRmTenant -TenantId $AzureSubscription.TenantId).Domain
                        $ReturnData = [PSCustomObject]@{
                            Tenant = $TenantName
                            ClientID = $AADApplication.ApplicationId
                            SecretKey = $AppPassword
                        }
                        Write-Output -InputObject $ReturnData
                    }
                }
                catch [System.Exception] {
                    Write-Warning -Message $_.Exception.Message ; break
                }
            }
            else {
                Write-Warning -Message "Unable to locate Azure Subscription based of specified Subscription Id" ; break
            }
        }
    }
    catch [System.Exception] {
        Write-Warning -Message $_.Exception.Message ; break
    }
}

Usage

Using this script requires a few inputs in terms of the following:

  • Display name for the web application in Azure AD
  • Name of the Resource Group where the workspace containing your Upgrade Analytics solution belongs to
  • Azure Subscription ID

As for the Azure Subscription ID, you can get that by running the following code:

Login-AzureRmAccount
Get-AzureRmSubscription

If the Get-AzureRmSubscription cmdlet returns multiple objects, make sure that you identify the correct subscription ID.

1. Open a PowerShell console and browse where you’ve saved the above script.
2. Run the following command:

.\New-AADAppForUpgradeAnalytics.ps1 -AppDisplayName "CMUpgradeAnalytics" -ResourceGroupName "CMUpgradeAnalytics" -AzureSubscriptionId "<Id>"

3. When prompted to login, enter credentials for a Global Admin account associated with the subscription.

220_2
4. Once the script has completed, notice the output at the end giving you the required information to setup the connection between ConfigMgr and Upgrade Analytics.

220_3

Nickolaj Andersen
Principal Consultant and Enterprise Mobility MVP since 2016. Nickolaj has been in the IT industry for the past 10 years specializing in Enterprise Mobility and Security, Windows devices and deployments including automation. Currently working for TrueSec as a Principal Consultant. Awarded as PowerShell Hero in 2015 by the community for his script and tools contributions. Creator of ConfigMgr Prerequisites Tool, ConfigMgr OSD FrontEnd, ConfigMgr WebService to name a few. Frequent speaker at conferences and user groups.

(479)

There are no comments.

Leave a Reply