Automating the Onboarding of Existing AVD Environments in Nerdio Manager for MSP
Many MSPs already manage Azure Virtual Desktop (AVD) environments before introducing Nerdio Manager for MSP (NMM) into their operational workflow. While onboarding these existing environments through the NMM portal works really well, it can quickly become repetitive and time-consuming at scale. This is where the NMM REST API becomes extremely valuable.
By using the NMM REST API, MSPs can automate the onboarding process for existing AVD environments, reduce manual effort, and standardize deployments across multiple customers and tenants. Whether you are migrating large numbers of host pools into NMM, building customer onboarding workflows, or integrating with internal automation platforms, the API provides a flexible and scalable way to bring existing AVD resources under centralized management.
In this post, we’ll walk through how to use the NMM REST API to automate the onboarding of existing AVD environments quickly and almost effortlessly.
Getting Started
Before automating the onboarding of existing AVD environments, the first step is enabling and configuring the REST API in NMM.
The NMM API exposes the same functionality available in the portal through REST endpoints, making it possible to automate tasks such as linking resource groups, managing host pools, provisioning session hosts, and onboarding existing AVD environments at scale.
To get started:
- In Nerdio Manager for MSP, navigate to
Settings>Integrations. - In the
REST APIsection, enable the API if it is currently disabled. - Run the built-in setup process, which creates the required Azure application registration and permissions.
- Grant admin consent in Azure when prompted.
- Open the Swagger documentation or download the Postman collection to start testing API calls.
A more comprehensive guide, including screenshots, is provided by Nerdio here.
Once the API is enabled, NMM provides all required authentication details, including the Client ID, Tenant ID, and API scope. Authentication uses OAuth 2.0 with Microsoft Entra ID, allowing scripts and automation platforms to securely obtain access tokens before making API requests. We are going to use the authentication details in the next chapter.
For testing and development, Nerdio recommends using Swagger or Postman, but the API can be integrated into PowerShell scripts, CI/CD pipelines, or external ITSM and automation platforms. During the rest of this blog post we will be using PowerShell for “talking” to the NMM REST API.
Authenticating to the NMM REST API with PowerShell
Before you can automate the onboarding of existing AVD environments, you first need to authenticate against the Microsoft identity platform and obtain an access token for the NMM REST API.
In this example, PowerShell is used together with the OAuth 2.0 client credentials flow to request a bearer token from Microsoft Entra ID. The script sends the Tenant ID, Client ID, Client Secret, and API scope to the Microsoft authentication endpoint and returns an access token that can be used for subsequent API requests.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#--------------------------------------------------------- # GET NMM API ACCESS TOKEN #--------------------------------------------------------- $tenantId = "12345678-xxxx-1234-xxxx-123456789012" $clientId = "xxxxxxxx-1234-xxxx-1234-xxxxxxxxxxxx" $clientSecret = "Lcr8Q-xXxXxXxXxX-uXmbXXXywiBpDrXXXXXXa4J" $scope = "12345678-xxxx-1234-xxxx-123456789012/.default" $body = @{ client_id = $clientId scope = $scope client_secret = $clientSecret grant_type = "client_credentials" } $response = Invoke-RestMethod ` -Method Post ` -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" ` -Body $body ` -ContentType "application/x-www-form-urlencoded" $accessToken = $response.access_token |
The returned token is stored in the $accessToken variable and can then be added to the Authorization header for all future REST API calls:
|
1 2 3 4 5 6 7 8 |
#--------------------------------------------------------- # CONSTRUCT HEADER #--------------------------------------------------------- $header = @{ Authorization = "Bearer $accessToken" "Content-Type" = "application/json" } |
This authentication approach is ideal for automation scenarios because it allows scripts, runbooks, and CI/CD pipelines to securely interact with NMM without requiring interactive user sign-in.
Important: Never hardcode production secrets directly into scripts. For real-world implementations, store client secrets securely in solutions such as Microsoft Azure Key Vault, automation variables, or a secure credential management platform.
Authenticating to Azure and Retrieving Access Tokens
In addition to authenticating against the Nerdio Manager API, the automation workflow also requires access to both the Microsoft Azure Resource Manager (ARM) API and the Microsoft Graph API. These APIs are used throughout the onboarding process to discover and validate existing AVD resources, identity objects, and Azure infrastructure components.
The first step is establishing an authenticated Azure PowerShell session using Connect-AzAccount.
|
1 2 3 4 5 |
#--------------------------------------------------------- # AZURE AUTHENTICATION #--------------------------------------------------------- Connect-AzAccount |
Once authenticated, separate access tokens can be requested for both Azure Resource Manager and Microsoft Graph using the Get-AzAccessToken cmdlet. The ARM token is used for interacting with Azure resources such as subscriptions, resource groups, host pools, and session hosts, while the Graph token enables access to identity-related information in Microsoft Entra ID.
|
1 2 3 4 5 6 7 8 9 |
#--------------------------------------------------------- # GET AZURE ARM ACCESS TOKEN #--------------------------------------------------------- $secureToken = (Get-AzAccessToken -ResourceUrl "https://management.azure.com/").Token $mgmtToken = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureToken) ) |
|
1 2 3 4 5 6 7 8 |
#--------------------------------------------------------- # GET AZURE GRAPH API ACCESS TOKEN #--------------------------------------------------------- $secureToken = (Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com/").Token $graphToken = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureToken) ) |
Because Get-AzAccessToken returns the token as a secure string, the script converts it into plain text so it can be included in REST API authorization headers for subsequent API calls.
By separating ARM and Graph authentication, the automation remains flexible and can interact with all required Microsoft APIs during the onboarding workflow. This approach is especially useful when building larger automation frameworks that combine NMM REST API operations with native Azure and Microsoft Graph integrations.
Linking the Customer Tenant to NMM
With authentication in place, the next step is linking the customer Azure tenant to Nerdio Manager for MSP using the linkTenant API endpoint. This provisioning step establishes the connection between NMM and the customer’s existing AVD environment.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#--------------------------------------------------------- # LINK TENANT PROVISIONING STEP (1) #--------------------------------------------------------- $body = @" { "subscriptionId": "12345678-xxxx-1234-xxxx-123456789012", "azureAccessToken": "$mgmtToken", "graphAccessToken": "$graphToken", "companyName": "Cloud Workspace Services (AVD)", "activeDirectoryType": "ExistingAD", "limitedAccessEnabled": false, "desktopDeploymentOptions": { "wvd": true, "selfManagedCloudPc": false, "endpointManagedCloudPc": false, "endpointManagedWithIntune": false } } "@ $response = Invoke-RestMethod ` -Method Post ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/accountprovisioning/linkTenant" ` -Headers $header ` -Body $body ` -ContentType "application/json" Do { $status = Invoke-RestMethod ` -Method Get ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/job/$($response.job.id)" ` -Headers $header ` -ContentType "application/json" Start-Sleep -Seconds 10 } Until ($status.jobStatus -eq "Completed") $id = $response.account.id |
The request includes several important parameters, such as the Azure subscription ID, the Azure Resource Manager access token, and the Microsoft Graph access token obtained earlier in the automation workflow. These tokens allow NMM to validate permissions, discover Azure resources, and configure the required integration components inside the customer tenant.
In this example, the onboarding process is configured for an existing Active Directory deployment by setting the activeDirectoryType to ExistingAD. The desktopDeploymentOptions section also specifies that the environment will use AVD (wvd) while other desktop provisioning options remain disabled, since we only want to onboard for AVD.
After submitting the request, the API immediately returns a provisioning job ID. Because tenant linking is an asynchronous operation, the script continuously polls the job endpoint until the provisioning status changes to Completed. This pattern is important when building reliable automation workflows, since the onboarding process can take several minutes depending on the complexity of the customer environment.
Once the job completes successfully, the returned account ID can be reused in subsequent API calls to continue configuring and onboarding the existing AVD environment into NMM.
Configuring Azure Networking for the Existing AVD Environment
After the customer tenant has been linked successfully, the next step is configuring the Azure infrastructure connection by calling the linkNetwork endpoint in NMM.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#--------------------------------------------------------- # START AZURE CONFIGURATION STEP (2) #--------------------------------------------------------- $body = @" { "accountId": $id, "regionName": "westeurope", "existingResourceGroupName": "rg-remotedesktop-dev", "newResourceGroupName": "", "existingNetwork": { "networkId": "/subscriptions/12345678-xxxx-1234-xxxx-123456789012/resourceGroups/rg-network-avd/providers/Microsoft.Network/virtualNetworks/vnet-westeurope-avd", "subnetName": "snet-remotedesktop-dev" } } "@ $response = Invoke-RestMethod ` -Method Post ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/accountprovisioning/linkNetwork" ` -Headers $header ` -Body $body ` -ContentType "application/json" $response Do { $status = Invoke-RestMethod ` -Method Get ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/job/$($response.job.id)" ` -Headers $header ` -ContentType "application/json" Start-Sleep -Seconds 10 } Until ($status.jobStatus -eq "Completed") |
This step connects NMM to the existing Azure networking resources that are already being used by the AVD environment. Instead of deploying new infrastructure, the API request references an existing resource group, virtual network, and subnet. This approach is especially useful for MSPs onboarding AVD environments where the networking architecture is already standardized and operational.
In the request body, the existingResourceGroupName parameter identifies the Azure resource group containing the AVD resources, while the existingNetwork section specifies both the virtual network resource ID and the target subnet that will be used for session host deployments and management operations.
The script also defines the Azure region (westeurope) where the environment is hosted. Providing these details allows NMM to validate connectivity and establish the required configuration for managing the existing deployment.
Similar to the tenant linking process, the linkNetwork operation runs asynchronously. After submitting the request, the script continuously checks the job status endpoint until the provisioning task completes successfully. Polling the job status ensures the automation workflow remains reliable and prevents later onboarding steps from executing before the Azure configuration is fully completed.
Once this step finishes, the existing AVD environment is connected to the required Azure networking resources and ready for the remaining onboarding and management configuration steps inside NMM.
Connecting NMM to an Existing Active Directory Environment
The next onboarding step connects NMM to the existing Active Directory environment that is already being used by the AVD deployment.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#--------------------------------------------------------- # START CONNECTING TO EXISTING AD STEP (3) #--------------------------------------------------------- $body = @" { "accountId": $id, "domainName": "cloudworkspaceservices.com", "domainAdminUsername": "xxxxxxxx@cloudworkspaceservices.com", "domainAdminPassword": "xxxxxxxxxxxxxx", "activeDirectoryType": "AD", "ouPath": "" } "@ $response = Invoke-RestMethod ` -Method Post ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/accountprovisioning/connectToExistingAd" ` -Headers $header ` -Body $body ` -ContentType "application/json" $response Do { $status = Invoke-RestMethod ` -Method Get ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/job/$($response.job.id)" ` -Headers $header ` -ContentType "application/json" Start-Sleep -Seconds 10 } Until ($status.jobStatus -eq "Completed") |
Using the connectToExistingAd endpoint, the automation workflow provides the required domain information and administrative credentials so NMM can validate connectivity and integrate with the existing domain infrastructure. In this example, the environment uses a traditional Active Directory deployment ("activeDirectoryType": "AD"), allowing existing domain-joined session hosts and identity services to remain unchanged during onboarding.
The API request includes the domain name, a domain administrator account, and optionally an Organizational Unit (OU) path where newly deployed session hosts should be created. Leaving the ouPath empty allows the default computer container to be used, but in production environments it is often recommended to target a dedicated OU for better Group Policy and lifecycle management.
As with the previous provisioning steps, the request starts an asynchronous job in NMM. The script continuously polls the job status endpoint until the operation reaches the Completed state before continuing with the next automation step.
This integration step is critical because it enables NMM to fully manage existing domain-joined AVD resources while preserving the customer’s existing Active Directory architecture, policies, and operational standards.
Important: Administrative credentials should never be hardcoded in production scripts. Store credentials securely using solutions such as Microsoft Azure Key Vault or an enterprise-grade secret management platform.
Configuring Existing File Storage for FSLogix Profiles
After the Active Directory integration has been completed, the next step is configuring the existing file storage location that will be used for FSLogix profile containers within the AVD environment.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#--------------------------------------------------------- # START CONFIGURE FILE SHARE STEP (4) #--------------------------------------------------------- $body = @" { "accountId": $id, "uncPath": "", "fileShareId": "/subscriptions/12345678-xxxx-1234-xxxx-123456789012/resourceGroups/rg-storage-avd/providers/Microsoft.Storage/storageAccounts/stcwsfslogix/fileServices/default/shares/testfslshare" } "@ $response = Invoke-RestMethod ` -Method Post ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/accountprovisioning/configureFileStorage" ` -Headers $header ` -Body $body ` -ContentType "application/json" $response Do { $status = Invoke-RestMethod ` -Method Get ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/job/$($response.job.id)" ` -Headers $header ` -ContentType "application/json" Start-Sleep -Seconds 10 } Until ($status.jobStatus -eq "Completed") |
Using the configureFileStorage endpoint, NMM can connect directly to an existing Azure file share instead of deploying new storage resources. This is especially useful when onboarding AVD environments that already use centralized profile storage for user sessions.
In this example, the API request references an existing Azure Files share through the fileShareId parameter. The full Azure resource ID points to the storage account and file share currently hosting the FSLogix profiles. Because an Azure Files share is being used, the uncPath parameter remains empty, but this field can also be used when integrating with traditional SMB file shares hosted on Windows file servers or third-party storage platforms.
Once the request is submitted, NMM validates access to the storage location and configures the required integration settings. Similar to the previous onboarding operations, the task runs asynchronously, so the script continuously polls the job status endpoint until the configuration process has completed successfully.
Properly configuring the existing file share is an important part of the onboarding workflow because it allows existing FSLogix user profiles to remain intact while bringing the environment under centralized management in NMM.
Linking Existing Azure Resource Groups
With the core onboarding configuration completed, the next step is linking the existing Azure resource groups to NMM. This allows NMM to discover and manage the AVD resources that already exist within the customer environment.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#--------------------------------------------------------- # LINK AZURE RESOURCE GROUPS #--------------------------------------------------------- $body = @" { "resourceGroup": "rg-remotedesktop-acc", "subscriptionId": "12345678-xxxx-1234-xxxx-123456789012" } "@ $response = Invoke-RestMethod ` -Method Post ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/accounts/$id/resource-group/linked" ` -Headers $header ` -Body $body ` -ContentType "application/json" $response Do { $status = Invoke-RestMethod ` -Method Get ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/job/$($response.job.id)" ` -Headers $header ` -ContentType "application/json" Start-Sleep -Seconds 10 } Until ($status.jobStatus -eq "Completed") |
Using the /resource-group/linked endpoint, the automation workflow submits the name of the target resource group together with the Azure subscription ID. In this example, the script links the rg-remotedesktop-acc resource group, which contains existing AVD-related resources such as host pools, session hosts, etc.
Linking resource groups is an important step because NMM uses these associations to identify which Azure resources should be managed and monitored within the platform. This approach makes it possible to onboard existing deployments without redeploying or restructuring the customer environment.
As with the earlier onboarding operations, the API processes the request asynchronously and returns a job ID immediately after submission. The script then continuously polls the job endpoint until the task reaches the Completed state before continuing with additional onboarding or automation steps.
For MSPs managing multiple customer environments, automating resource group linking through the REST API significantly reduces onboarding time and ensures a consistent operational process across tenants and subscriptions.
Complete Script Example
Here are all the snippets from previous chapters combined into one single script. You can use it as an example reference for your own scripting and automation.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
#--------------------------------------------------------- # GET NMM API ACCESS TOKEN #--------------------------------------------------------- $tenantId = "12345678-xxxx-1234-xxxx-123456789012" $clientId = "xxxxxxxx-1234-xxxx-1234-xxxxxxxxxxxx" $clientSecret = "Lcr8Q-xXxXxXxXxX-uXmbXXXywiBpDrXXXXXXa4J" $scope = "12345678-xxxx-1234-xxxx-123456789012/.default" $body = @{ client_id = $clientId scope = $scope client_secret = $clientSecret grant_type = "client_credentials" } $response = Invoke-RestMethod ` -Method Post ` -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" ` -Body $body ` -ContentType "application/x-www-form-urlencoded" $accessToken = $response.access_token #--------------------------------------------------------- # CONSTRUCT HEADER #--------------------------------------------------------- $header = @{ Authorization = "Bearer $accessToken" "Content-Type" = "application/json" } #--------------------------------------------------------- # AZURE AUTHENTICATION #--------------------------------------------------------- Connect-AzAccount #--------------------------------------------------------- # GET AZURE ARM ACCESS TOKEN #--------------------------------------------------------- $secureToken = (Get-AzAccessToken -ResourceUrl "https://management.azure.com/").Token $mgmtToken = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureToken) ) #--------------------------------------------------------- # GET AZURE GRAPH API ACCESS TOKEN #--------------------------------------------------------- $secureToken = (Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com/").Token $graphToken = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureToken) ) #--------------------------------------------------------- # LINK TENANT PROVISIONING STEP (1) #--------------------------------------------------------- $body = @" { "subscriptionId": "12345678-xxxx-1234-xxxx-123456789012", "azureAccessToken": "$mgmtToken", "graphAccessToken": "$graphToken", "companyName": "Cloud Workspace Services (AVD)", "activeDirectoryType": "ExistingAD", "limitedAccessEnabled": false, "desktopDeploymentOptions": { "wvd": true, "selfManagedCloudPc": false, "endpointManagedCloudPc": false, "endpointManagedWithIntune": false } } "@ $response = Invoke-RestMethod ` -Method Post ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/accountprovisioning/linkTenant" ` -Headers $header ` -Body $body ` -ContentType "application/json" Do { $status = Invoke-RestMethod ` -Method Get ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/job/$($response.job.id)" ` -Headers $header ` -ContentType "application/json" Start-Sleep -Seconds 10 } Until ($status.jobStatus -eq "Completed") $id = $response.account.id #--------------------------------------------------------- # START AZURE CONFIGURATION STEP (2) #--------------------------------------------------------- $body = @" { "accountId": $id, "regionName": "westeurope", "existingResourceGroupName": "rg-remotedesktop-dev", "newResourceGroupName": "", "existingNetwork": { "networkId": "/subscriptions/12345678-xxxx-1234-xxxx-123456789012/resourceGroups/rg-network-avd/providers/Microsoft.Network/virtualNetworks/vnet-westeurope-avd", "subnetName": "snet-remotedesktop-dev" } } "@ $response = Invoke-RestMethod ` -Method Post ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/accountprovisioning/linkNetwork" ` -Headers $header ` -Body $body ` -ContentType "application/json" $response Do { $status = Invoke-RestMethod ` -Method Get ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/job/$($response.job.id)" ` -Headers $header ` -ContentType "application/json" Start-Sleep -Seconds 10 } Until ($status.jobStatus -eq "Completed") #--------------------------------------------------------- # START CONNECTING TO EXISTING AD STEP (3) #--------------------------------------------------------- $body = @" { "accountId": $id, "domainName": "cloudworkspaceservices.com", "domainAdminUsername": "xxxxxxxx@cloudworkspaceservices.com", "domainAdminPassword": "xxxxxxxxxxxxxx", "activeDirectoryType": "AD", "ouPath": "" } "@ $response = Invoke-RestMethod ` -Method Post ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/accountprovisioning/connectToExistingAd" ` -Headers $header ` -Body $body ` -ContentType "application/json" $response Do { $status = Invoke-RestMethod ` -Method Get ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/job/$($response.job.id)" ` -Headers $header ` -ContentType "application/json" Start-Sleep -Seconds 10 } Until ($status.jobStatus -eq "Completed") #--------------------------------------------------------- # START CONFIGURE FILE SHARE STEP (4) #--------------------------------------------------------- $body = @" { "accountId": $id, "uncPath": "", "fileShareId": "/subscriptions/12345678-xxxx-1234-xxxx-123456789012/resourceGroups/rg-storage-avd/providers/Microsoft.Storage/storageAccounts/stcwsfslogix/fileServices/default/shares/testfslshare" } "@ $response = Invoke-RestMethod ` -Method Post ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/accountprovisioning/configureFileStorage" ` -Headers $header ` -Body $body ` -ContentType "application/json" $response Do { $status = Invoke-RestMethod ` -Method Get ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/job/$($response.job.id)" ` -Headers $header ` -ContentType "application/json" Start-Sleep -Seconds 10 } Until ($status.jobStatus -eq "Completed") #--------------------------------------------------------- # LINK AZURE RESOURCE GROUPS #--------------------------------------------------------- $body = @" { "resourceGroup": "rg-remotedesktop-acc", "subscriptionId": "12345678-xxxx-1234-xxxx-123456789012" } "@ $response = Invoke-RestMethod ` -Method Post ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/accounts/$id/resource-group/linked" ` -Headers $header ` -Body $body ` -ContentType "application/json" $response Do { $status = Invoke-RestMethod ` -Method Get ` -Uri "https://web-admin-portal-1234567890123.azurewebsites.net/rest-api/v1/job/$($response.job.id)" ` -Headers $header ` -ContentType "application/json" Start-Sleep -Seconds 10 } Until ($status.jobStatus -eq "Completed") |
But There is More
Nerdio also provides the NMM-PS module. A PowerShell module for automating Nerdio Manager for MSP (NMM) operations, which can be found here.
I hope this post was informative and happy automating… 😉



