Advanced Installation: Create Entra ID Application
Traditional Nerdio Manager deployments should follow the steps and instructions provided in our Installation Guide. See Nerdio Manager Installation Guide for details. The advanced install methods outlined here should only be used for specific situations as warranted.
Warning: This is an advanced, custom, install of Nerdio Manager recommended only for special circumstances. Please use this with the advice and guidance of Nerdio Support. Please contact us with any questions at all: nme.support@getnerdio.com.
Note: Updates for Nerdio Manager require running Cloud Shell or PowerShell scripts. See Update the Nerdio Manager Application for details.
Advanced Install steps for manually creating Nerdio Manager application in Entra ID:
Azure Marketplace deployment (Completed by subscription owner).
AzureAD application registration and setup (Completed by global admin).
Azure resource configuration (Completed by subscription owner).
Create the Application and Service Principal
The following procedure creates the application and service principal.
To create the application and service principal:
In the Azure portal, navigate to Microsoft Entra ID > App Registrations > New registration.
Enter the following information:
Name: nerdio-nmw-app (optionally rename the default application)
Account type: 'Accounts in any organizational directory (Any Entra ID directory - Multitenant)'
Redirect URL: Web, https://<app_service_name>.azurewebsites.net/
Save the Application ID. (To be provided for Nerdio Manager deployment.)
Navigate to Microsoft Entra ID > App Registrations > All Applications > nerdio-nmw-app (or custom app name) > Authentication.
Enter the following information:
Redirect URLs > Add URL: https://<app_service_name>.azurewebsites.net/signin-oidc
Front-channel logout URL: https://<app_service_name>.azurewebsites.net/signout-oidc
Implicit grant and hybrid flows: Enable Access tokens & ID tokens
Navigate to Microsoft Entra ID > Enterprise Applications > All Applications > nerdio-nmw-app (or custom app name)
Save the Object ID. (To be provided for Nerdio Manager deployment.)
Alternatively, the following PowerShell script completes these changes:
$webAppName = "" # REQUIRED: Name of app service provisioned in marketplace deployment
$appName = "nerdio-nmw-app" # Optionally rename the default application
$webAppUrl = 'https://' + $webAppName + '.azurewebsites.net/'
$loginUrl = $webAppUrl + 'signin-oidc'
$logoutUrl = $webAppUrl + 'signout-oidc'
$application = New-AzureADApplication -DisplayName $appName -HomePage $webAppUrl -LogoutUrl $logoutUrl -ReplyUrls $webAppUrl, $loginUrl -AvailableToOtherTenants $True -Oauth2AllowImplicitFlow $true -PublicClient $False
New-AzureADServicePrincipal -AppId $application.AppId -Tags {WindowsAzureActiveDirectoryIntegratedApp} -AppRoleAssignmentRequired $True
$servicePrincipal = Get-AzureADServicePrincipal -Filter "AppID eq '$($application.AppID)'"
Write-Host "Application ID to be saved in to app service $($Application.AppID)"
Write-Host "Service Principal ID to be provided to Nerdio Manager deployment: $($servicePrincipal.ObjectId)"
Configure Application Roles and Assign AVD Admin
The following procedure configures the application roles and assigns the AVD admin.
Note: The app roles require a specific ID to be assigned for each role. The role name, description, and ID can be added to the app registration by modifying the app's manifest.
To configure app roles and assign AVD admin:
In the Azure portal, navigate to Microsoft Entra ID > App Registrations > All Applications > nerdio-nmw-app (or custom app name) > Manifest.
Replace the "appRoles": [] entry (typically on line 8) with the following value:
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"description": "Complete access to all areas of NMW.",
"displayName": "WVD Admin",
"id": "d1c2ade8-98f8-45fd-aa4a-6d06b947c66f",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "WvdAdmin"
},
{
"allowedMemberTypes": [
"User"
],
"description": "Complete access to User sessions, ability to view Host Pools, hosts and restart them, but no ability to add/remove or change any settings.",
"displayName": "Desktop Admin",
"id": "ed0cdef0-4267-4470-bfff-5e0b6944f9e4",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "DesktopAdmin"
},
{
"allowedMemberTypes": [
"User"
],
"description": "Complete access to User sessions only.",
"displayName": "Help Desk",
"id": "a94e83da-b314-4232-b8c8-94508c5ed533",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "HelpDesk"
},
{
"allowedMemberTypes": [
"User"
],
"description": "View access to all areas of NMW; no ability to save or make changes.",
"displayName": "Reviewer",
"id": "0a1b7425-f55a-44a6-9caa-b9a5cc9448da",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "Reviewer"
},
{
"allowedMemberTypes": [
"User"
],
"description": "View & manage own sessions (Message, Log off, Disconnect). Personal desktop users can restart, power off and power their personal desktops.",
"displayName": "End-user",
"id": "e856de81-1e53-486a-8668-7d564866ae39",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "EndUser"
},
{
"allowedMemberTypes": [
"Application"
],
"description": "Rest client description",
"displayName": "Rest client display name",
"id": "3807160f-e77a-4fcf-959a-df572bcc3767",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "RestClient"
}
],
Select Save.
In App Roles, confirm each role is available.
Navigate to Microsoft Entra ID > Enterprise Applications > All Applications > nerdio-nmw-app (or custom app name) > Properties.
Ensure that the option Visible to user? is set to Yes.
Navigate to Microsoft Entra ID > Enterprise Applications > All Applications > nerdio-nmw-app (or custom app name) > Users and groups > Add user/group.
Enter the following information:
Users and groups: Select and search for user completing the Nerdio Manager deployment in the Azure portal.
Select a role: From the drop-down list, select WVD Admin.
Once you have entered all the required information, select Save.
Alternatively, the following PowerShell script completes these changes:
$userPrincipalName = "" # REQUIRED: Fill in UPN of subscription owner completing Nerdio Manager deployment
$appName = "nerdio-nmw-app" # Optionally rename the default application
function BuildAppRole([string] $displayName, [string] $value, [Guid] $id, [string] $description) {
$newAppRole = [Microsoft.Open.AzureAD.Model.AppRole]::new()
$newAppRole.DisplayName = $displayName
$newAppRole.Description = $description
$newAppRole.Value = $value
$newAppRole.Id = $id
$newAppRole.IsEnabled = $true
$newAppRole.AllowedMemberTypes = New-Object System.Collections.Generic.List[string]
$newAppRole.AllowedMemberTypes.Add("User")
return $newAppRole;
}
function GetNewAppRoles() {
$reviewer = BuildAppRole -displayName "Reviewer" -value "Reviewer" -id "0a1b7425-f55a-44a6-9caa-b9a5cc9448da" -description "View access to all areas of NMW; no ability to save or make changes."
$helpDesk = BuildAppRole -displayName "Help Desk" -value "HelpDesk" -id "a94e83da-b314-4232-b8c8-94508c5ed533" -description "Complete access to User sessions only."
$endUser = BuildAppRole -displayName "End-user" -value "EndUser" -id "e856de81-1e53-486a-8668-7d564866ae39" -description "View & manage own sessions (Message, Log off, Disconnect). Personal desktop users can restart, power off and power their personal desktops."
$desktopAdmin = BuildAppRole -displayName "Desktop Admin" -value "DesktopAdmin" -id "ed0cdef0-4267-4470-bfff-5e0b6944f9e4" -description "Complete access to User sessions, ability to view Host Pools, hosts and restart them, but no ability to add/remove or change any settings."
$wvdAdmin = BuildAppRole -displayName "WVD Admin" -value "WvdAdmin" -id 'd1c2ade8-98f8-45fd-aa4a-6d06b947c66f' -description "Complete access to all areas of NMW."
$newAppRoles = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.AppRole]
$newAppRoles.Add($reviewer)
$newAppRoles.Add($helpDesk)
$newAppRoles.Add($endUser)
$newAppRoles.Add($desktopAdmin)
$newAppRoles.Add($wvdAdmin)
return $newAppRoles
}
$appRoles = GetNewAppRoles
$application = Get-AzureADApplication -Filter ("DisplayName eq '" + $appName + "'")
Set-AzureADApplication -ObjectId $application.ObjectId -AppRoles $appRoles
$userId = (Get-AzureADUser -Filter "UserPrincipalName eq '$userPrincipalName'").ObjectId
$servicePrincipal = Get-AzureADServicePrincipal -Filter ("AppId eq '" + $application.AppId + "'")
$wvdAdminRoleId = 'd1c2ade8-98f8-45fd-aa4a-6d06b947c66f'
New-AzureADUserAppRoleAssignment -ObjectId $userId -PrincipalId $userId -ResourceId $servicePrincipal.ObjectId -Id $WVDAdminRoleID
Configure API Permissions
The following procedure configures the API permissions.
To configure the API permissions:
In the Azure portal, navigate to Microsoft Entra ID > App Registrations > All Applications > nerdio-nmw-app (or custom app name) > API permissions.
Add or confirm the following permissions for Microsoft APIs > Microsoft Graph > Delegated permissions:
User.Read (included by default)
User.ReadBasic.All
User.Read.All
Group.Read.All
GroupMember.Read.All
Application.Read.All
Organization.Read.All
AppRoleAssignment.ReadWrite.All
Application.ReadWrite.All
Mail.Send (optional for enabling email notifications)
offline_access
openid
profile
Add the following permissions for Microsoft APIs > Microsoft Graph > Application permissions:
Group.Read.All
GroupMember.Read.All
Organization.Read.All
User.Read.All
Add the following permissions for Microsoft APIs > Azure Service Management > Delegated permissions:
user_impersonation
(For WVD Classic Only) APIs my organization uses > Windows Virtual Desktop (Application ID 5a0aa725-4958-4b0c-80a9-34562e23f3b7):
Add Delegated permissions: user_impersonation
Add Application permissions: TenantCreator
Alternatively, the following PowerShell script completes these changes:
$appName = "nerdio-nmw-app" # Optionally rename the default application
$azureEnv = "AzureCloud" # Change to AzureUSGovernment for government cloud deployments
$wvdClassicEnabled = $False # Optionally include permissions for WVD Classic
$readDelagatedPermissions = "User.Read|User.ReadBasic.All|Directory.Read.All"
# Or if you wanna replace Directory.Read.All then:
# - set value to: "User.Read|User.ReadBasic.All|User.Read.All|Group.Read.All|Application.Read.All|Organization.Read.All"
# - add add service setting: AzureAD:DefaultGraphScopes "User.Read|User.ReadBasic.All|User.Read.All|Group.Read.All|Application.Read.All|Organization.Read.All"
function AddResourcePermission($requiredAccess, $exposedPermissions, [string]$requiredAccesses, [string]$permissionType) {
foreach ($permission in $requiredAccesses.Trim().Split("|")) {
foreach ($exposedPermission in $exposedPermissions) {
if ($exposedPermission.Value -eq $permission) {
$resourceAccess = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$resourceAccess.Type = $permissionType
$resourceAccess.Id = $exposedPermission.Id
$requiredAccess.ResourceAccess.Add($resourceAccess)
}
}
}
}
function GetRequiredPermissions([string] $applicationDisplayName, [string] $requiredDelegatedPermissions, [string]$requiredApplicationPermissions, $servicePrincipal) {
if ($servicePrincipal) {
$sp = $servicePrincipal
}
else {
$sp = Get-AzureADServicePrincipal -Filter "DisplayName eq '$applicationDisplayName'"
}
$appid = $sp.AppId
$requiredAccess = New-Object Microsoft.Open.AzureAD.Model.RequiredResourceAccess
$requiredAccess.ResourceAppId = $appid
$requiredAccess.ResourceAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]
if ($requiredDelegatedPermissions) {
AddResourcePermission $requiredAccess -exposedPermissions $sp.Oauth2Permissions -requiredAccesses $requiredDelegatedPermissions -permissionType "Scope"
}
if ($requiredApplicationPermissions) {
AddResourcePermission $requiredAccess -exposedPermissions $sp.AppRoles -requiredAccesses $requiredApplicationPermissions -permissionType "Role"
}
return $requiredAccess
}
$application = Get-AzureADApplication -Filter ("DisplayName eq '" + $appName + "'")
$graphPermissions = GetRequiredPermissions -applicationDisplayName "Microsoft Graph" -requiredDelegatedPermissions "$readDelagatedPermissions|AppRoleAssignment.ReadWrite.All|Application.ReadWrite.All|offline_access|openid|profile|Mail.Send" -requiredApplicationPermissions "Group.Read.All|GroupMember.Read.All|Organization.Read.All|User.Read.All"
if ($wvdClassicEnabled) {
$wvdClassicSP = Get-AzureADServicePrincipal -Filter "AppId eq '5a0aa725-4958-4b0c-80a9-34562e23f3b7'" # Required for WVD classic only
$wvdClassicPermissions = GetRequiredPermissions -applicationDisplayName "Microsoft Graph" -requiredDelegatedPermissions "user_impersonation" -requiredApplicationPermissions "TenantCreator" -servicePrincipal $wvdClassicSP # Required for WVD classic only
}
if ($azureEnv -eq 'AzureCloud') {
$rmPermissions = GetRequiredPermissions -applicationDisplayName "Windows Azure Service Management API" -requiredDelegatedPermissions "user_impersonation"
}
if ($azureEnv -eq 'AzureUSGovernment') {
$rmPermissions = GetRequiredPermissions -applicationDisplayName "Azure Government Cloud Management API" -requiredDelegatedPermissions "user_impersonation"
}
$requiredResourcesAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.RequiredResourceAccess]
$requiredResourcesAccess.Add($graphPermissions)
$requiredResourcesAccess.Add($rmPermissions)
if ($wvdClassicEnabled) {
$requiredResourcesAccess.Add($wvdClassicPermissions) # Required for WVD classic only
}
Set-AzureADApplication -ObjectId $application.ObjectId -RequiredResourceAccess $requiredResourcesAccess
Assign Subscription Owner User Account as Owner on the Service Principal
The following procedure assigns the subscription owner user account as owner on the service principal.
To assign the subscription owner:
In the Azure portal, navigate to Microsoft Entra ID > Enterprise Applications > All Applications > nerdio-nmw-app (or custom app name) > Owners > Add.
Search for the user account that deployed Nerdio Manager from Azure Marketplace and is completing the installation and Select.
Alternatively, the following PowerShell script completes these changes:
$userPrincipalName = "" # REQUIRED: Fill in UPN of subscription owner completing Nerdio Manager deployment
$appName = "nerdio-nmw-app" # Optionally rename the default application
$application = Get-AzureADApplication -Filter "DisplayName eq '$appName'"
$servicePrincipal = Get-AzureADServicePrincipal -Filter "AppID eq '$($application.AppID)'"
$userId = (Get-AzureADUser -Filter "UserPrincipalName eq '$userPrincipalName'").ObjectId
Add-AzureADServicePrincipalOwner -ObjectId $servicePrincipal.ObjectId -RefObjectId $userId
Grant Admin Consent
The following procedure grants admin consent.
To grant admin consent:
In the Azure portal, navigate to Microsoft Entra ID > App Registrations > All Applications > nerdio-nmw-app (or custom app name) > API permissions.
Select 'Grant admin consent for <tenant_name>'.
Select 'Grant consent on behalf of my organization' if prompted.
Navigate to Microsoft Entra ID > Enterprise Applications > All Applications > nerdio-nmw-app (or custom app name) > Permissions.
Select 'Grant admin consent for <tenant_name>'.
Select 'Grant consent on behalf of my organization' if prompted.
Alternatively, the following PowerShell script completes these changes:
Note: Fill in Entra ID tenant ID for $tenantID.
$tenantId = "" # REQUIRED: Fill in Entra ID tenant ID
$appName = "nerdio-nmw-app" # Optionally rename the default application
$microsoftLogin = 'https://login.microsoftonline.com'
$application = Get-AzureADApplication -Filter ("DisplayName eq '" + $appName + "'")
Start-Process -FilePath "$microsoftLogin/$tenantId/adminconsent?client_id=$($application.AppId)"
Generate New Application Secret (nerdio-nmw-app)
This step may optionally be completed by the subscription owner user instead of global admin user. In this case, the subscription owner user should be added as Owner on the application under App Registrations, in addition to Owner added on the service principal under Enterprise Applications above.
To generate a new application secret:
Navigate to Microsoft Entra ID > App Registrations > All Applications > nerdio-nmw-app (or custom app name) > Certificates & Secrets > New client secret.
Enter the following information:
Description: Nerdio Manager Secret (optional)
Expires: Select Custom.
Start: Select today's date.
End: This should be set to the longest duration allowed by your company policy.
Note: The Entra ID portal may limit this value to a maximum of 2 years.
Save the generated secret's value.
Note: This is required to complete the installation in the Azure portal (by subscription owner user). Ensure the value is used, not the ID of the secret.
Alternatively, the following PowerShell script completes these changes:
$appName = "nerdio-nmw-app" # Optionally rename the default application
$application = Get-AzureADApplication -Filter "DisplayName eq '$appName'"
$appSecret = New-AzureADApplicationPasswordCredential -ObjectId $application.ObjectId -StartDate ([DateTime]::Now) -EndDate ([DateTime]::Now.AddYears(10))
Write-Host "Application secret to be saved in Azure KeyVault: $($appSecret.Value)"
Finalize
Share the below values with the user completing Nerdio Manager deployment in the Azure portal (subscription owner):
Application ID
Application client secret (Make sure this is the generated value of the secret, not the ID.)
Service principal ID (This is the object ID of the application from Enterprise Applications.)
Comments (0 comments)