To onboard many on-premises servers to Azure Arc, register the Arc resource providers, create a dedicated Microsoft Entra service principal with only the Azure Connected Machine Onboarding role on the target resource group, and run a script on each server that installs the Connected Machine agent, runs azcmagent check, and connects with azcmagent connect using the service principal's ID, secret and tenant ID. Microsoft recommends passing the secret through a --config file rather than the command line so it doesn't appear in console logs. Push the script with Group Policy, Configuration Manager, Ansible or PowerShell remoting, then confirm the servers show Connected in Azure.
Who this is for and what you will have at the end
This guide is for server and cloud teams that need to bring a large on-premises or multicloud estate under Azure management: inventory, Azure Policy, Azure Monitor Agent, Update Manager and Extended Security Updates all start with an Arc connection. It assumes local administrator or root access to the servers and Owner or User Access Administrator on the target subscription to assign roles.
At the end you will have:
- A landing resource group, tags and a registered set of resource providers.
- A least-privilege onboarding service principal with a known secret expiry.
- Windows and Linux onboarding scripts that keep the secret out of command lines.
- A wave-based rollout method, a Resource Graph query to track progress, and the error codes you are most likely to hit.
Plan before the first server
Microsoft's at-scale guidance recommends a pilot on representative, non-critical machines before production, with a minimum of 30 days to assess impact. Use the pilot to settle the decisions below.
- Resource groups. Microsoft's plan starts with a dedicated resource group that contains only Arc-enabled servers, which keeps RBAC, policy and monitoring assignments simple.
- Region. The region you choose stores the servers' metadata; it doesn't have to match the resource group's region.
- Tags. Decide on tags such as datacenter, environment and owner up front, because
azcmagent connectcan apply them at onboarding. - Scale. There's no limit on Arc-enabled servers per resource group, subscription or tenant, but each server creates a Microsoft Entra object that counts against the directory quota.
- SQL Server. Servers running SQL Server have their instances connected to Arc automatically. To opt out, add the tag
ArcSQLServerExtensionDeploymentwith the valueDisabledat connect time.
Operating system support
x86-64 is fully supported; Arm64 supports a subset of features, and 32-bit systems aren't supported. Windows Server 2016, 2019, 2022 and 2025 are supported, as are current releases of RHEL, Rocky Linux, AlmaLinux, Oracle Linux, SLES, Ubuntu and Debian. Several older releases, including Windows Server 2012 and 2012 R2, Ubuntu 20.04, RHEL 7 and SLES 15 SP3 to SP6, are marked as approaching the end of Arc support in November 2026; check the prerequisites page for the current list. Extended Security Updates for Windows Server 2012 and 2012 R2 end on October 13, 2026.
Avoid onboarding golden images, clones and servers restored as a second instance: two agents with the same identity behave unpredictably. Onboard after cloning, and don't use Arc for short-lived servers or VDI machines.
Prerequisites
- Local rights. Members of the local Administrators group on Windows, root on Linux.
- Linux packages. systemd, wget, openssl, and gnupg on Debian-based systems.
- Windows logon right. The agent's
NT SERVICE\himdsvirtual account needs Log on as a service. If Group Policy manages that user right, addNT SERVICE\himdsto it. - Azure roles. Azure Connected Machine Onboarding (or Contributor) on the resource group to onboard; Azure Connected Machine Resource Administrator to manage machines afterwards. Creating the service principal requires that users can register applications, or the Application Administrator or Cloud Application Administrator role.
- Outbound TCP 443 to the Arc endpoints. The core set for public Azure is below; allow the service tags
AzureActiveDirectory,AzureTrafficManager,AzureResourceManager,AzureArcInfrastructure,StorageandAzureFrontDoor.Frontendif your firewall works with tags.
| Endpoint | When required |
|---|---|
download.microsoft.com | Windows package download (installation and automatic updates) |
packages.microsoft.com | Linux package download (installation and automatic updates) |
login.microsoftonline.com, *.login.microsoft.com, pas.windows.net | Always (Microsoft Entra ID) |
management.azure.com | When connecting or disconnecting a server |
*.his.arc.azure.com | Always (metadata and hybrid identity) |
*.guestconfiguration.azure.com | Always (extensions and machine configuration) |
guestnotificationservice.azure.com, *.guestnotificationservice.azure.com, *.servicebus.windows.net | Always (notifications) |
Use TLS 1.2 or 1.3. A Log Analytics gateway can't be used as the agent's proxy. Azure Arc gateway can reduce the number of endpoints you have to open, and private link scopes are available if traffic must stay private.
Step 1: Register the resource providers
Register the providers once per subscription that will hold Arc servers. Microsoft.Compute is also listed for Azure Update Manager and automatic extension upgrades.
Connect-AzAccount
Set-AzContext -SubscriptionId '<subscription-id>'
'Microsoft.HybridCompute','Microsoft.GuestConfiguration','Microsoft.HybridConnectivity','Microsoft.AzureArcData','Microsoft.Compute' |
ForEach-Object { Register-AzResourceProvider -ProviderNamespace $_ }If you skip this, onboarding fails with The subscription isn't registered to use namespace 'Microsoft.HybridCompute'.
Step 2: Create the onboarding service principal
Create one service principal per landing zone and scope it to the resource group rather than the whole subscription. In the portal, go to Azure Arc > Additional setup > Service principals > Add, choose resource group scope, set the client secret duration, and select the Azure Connected Machine Onboarding role. With the Azure CLI:
az ad sp create-for-rbac \
--name "sp-arc-onboarding-weu" \
--role "Azure Connected Machine Onboarding" \
--scopes "/subscriptions/<subscription-id>/resourceGroups/rg-arc-servers-weu"The output contains appId (used for --service-principal-id), password (the secret) and tenant. Store the secret in your vault, record its expiry date, and plan to remove the secret or the service principal when the rollout ends. The service principal is used only during onboarding, so deleting it later doesn't disconnect servers.
If you can, use a certificate instead of a secret. The agent accepts --service-principal-cert with a PFX or PEM file that contains the private key (password-protected files aren't supported), or --service-principal-cert-thumbprint for a certificate in the Windows certificate store.
Step 3: Build the onboarding package
You have two starting points.
Portal-generated script. In Azure Arc > Infrastructure > Machines, select Onboard/Create > Onboard existing machines. Choose subscription, resource group, region, operating system, connectivity (public endpoint, private endpoint, proxy URL or Arc gateway), then under Authentication select Authenticate machines automatically and pick your service principal. Add tags and download OnboardingScript.ps1 or OnboardingScript.sh. The Windows script only runs in 64-bit Windows PowerShell. Treat any script that contains the secret as a credential.
Your own wrapper. For large rollouts a small wrapper gives you logging, error handling and secret clean-up. Put the connection settings in a configuration file; each key matches an azcmagent connect option, and command-line values take precedence over the file.
{
"service-principal-id": "<app-id>",
"service-principal-secret": "<secret>",
"tenant-id": "<tenant-id>",
"subscription-id": "<subscription-id>",
"resource-group": "rg-arc-servers-weu",
"location": "westeurope",
"tags": "Datacenter=AMS1,Environment=Production"
}The Windows wrapper installs the agent from a staged MSI (download the latest AzureConnectedMachineAgent.msi from https://aka.ms/AzureConnectedMachineAgent), checks connectivity, connects, and deletes the configuration file whatever the outcome:
# Install-Arc.ps1 - run elevated in 64-bit Windows PowerShell on the target server
$ErrorActionPreference = 'Stop'
$stage = 'C:\ArcOnboarding'
$msiLog = Join-Path $stage 'azcmagent-setup.log'
$install = Start-Process msiexec.exe -Wait -PassThru `
-ArgumentList "/i `"$stage\AzureConnectedMachineAgent.msi`" /qn /l*v `"$msiLog`""
if ($install.ExitCode -ne 0) { throw "Agent install failed ($($install.ExitCode)). See $msiLog" }
$azcmagent = "$env:ProgramFiles\AzureConnectedMachineAgent\azcmagent.exe"
# Optional: agent-specific proxy (agent 1.13 or later)
# & $azcmagent config set proxy.url "http://proxy.contoso.com:8080"
& $azcmagent check --location "westeurope"
try {
& $azcmagent connect --config "$stage\arc-config.json"
if ($LASTEXITCODE -ne 0) { throw "azcmagent connect failed with exit code $LASTEXITCODE" }
}
finally {
Remove-Item "$stage\arc-config.json" -Force -ErrorAction SilentlyContinue
}The Linux equivalent, run as root:
#!/usr/bin/env bash
set -euo pipefail
wget https://aka.ms/azcmagent -O ~/Install_linux_azcmagent.sh
bash ~/Install_linux_azcmagent.sh # add --proxy "proxy.contoso.com:8080" if needed
azcmagent check --location "westeurope"
trap 'rm -f /root/arc-config.json' EXIT
azcmagent connect --config /root/arc-config.jsonazcmagent check tests every required endpoint and shows whether a proxy, private endpoint or Arc gateway was used. Run it before connect so network problems surface as a readable table rather than a failed onboarding.
Step 4: Roll out in waves
Pick the distribution method you already operate. Microsoft documents these at-scale options:
| Method | Platforms |
|---|---|
| Group Policy with the ArcEnabledServersGroupPolicy scripts | Windows, domain-joined |
| Configuration Manager (PowerShell script or custom task sequence) | Windows |
| Ansible (Azure Arc onboarding role) | Windows and Linux |
| PowerShell or a service principal script from your own tooling | Windows and Linux |
| Azure Arc-enabled VMware vSphere guest management | VMware VMs with VMware Tools |
| Multicloud connector | AWS EC2 instances |
Group Policy. Host the agent MSI and configuration on a share that domain computers can change and domain admins fully control, download the latest release of ArcEnabledServersGroupPolicy from GitHub, and run DeployGPO.ps1 on a domain controller:
.\DeployGPO.ps1 -DomainFQDN contoso.com -ReportServerFQDN Server.contoso.com -ArcRemoteShare AzureArcOnBoard `
-ServicePrincipalSecret $ServicePrincipalSecret -ServicePrincipalClientId $ServicePrincipalClientId `
-SubscriptionId $SubscriptionId -ResourceGroup $ResourceGroup -Location $Location -TenantId $TenantIdLink the generated [MSFT] Azure Arc Servers (datetime) GPO to the target OU. It creates a scheduled task that onboards the machines. After the wave is confirmed, disable the GPO so the task doesn't run again at every reboot or policy refresh.
PowerShell remoting. For workgroup servers or smaller waves, copy the files into each session and run the wrapper. Copying with -ToSession avoids the second-hop problem of reading a file share from inside a remote session.
$servers = Get-Content .\wave-01.txt
foreach ($server in $servers) {
$session = New-PSSession -ComputerName $server
try {
Invoke-Command -Session $session -ScriptBlock { New-Item -ItemType Directory -Path 'C:\ArcOnboarding' -Force | Out-Null }
Copy-Item -ToSession $session -Path .\AzureConnectedMachineAgent.msi, .\arc-config.json -Destination 'C:\ArcOnboarding\'
Invoke-Command -Session $session -FilePath .\Install-Arc.ps1
}
finally {
Remove-PSSession $session
}
}Keep waves small enough to troubleshoot the same day, and widen them once the failure rate is close to zero.
Verification
On a server, azcmagent show reports the agent status and the effective proxy configuration. In Azure, open Azure Arc > Machines and check Arc agent status. To track a whole wave, query Resource Graph:
Resources
| where type == 'microsoft.hybridcompute/machines'
| where resourceGroup =~ 'rg-arc-servers-weu'
| project name, status = tostring(properties.status), osName = tostring(properties.osName), domain = tostring(properties.domainName)
| summarize Machines = count() by status, osNameRun it in Resource Graph Explorer, with az graph query -q "<query>", or with Search-AzGraph -Query "<query>". Compare the count with your wave list to find servers that never connected.
After onboarding
- Create a Resource Health alert for Azure Arc-enabled servers that fires when the status changes from Available to Unavailable. A server that stops sending heartbeats for more than 15 minutes may be offline, have its network connection blocked, or have a stopped agent.
- Create an Azure Advisor alert for Upgrade to the latest version of the Azure Connected Machine agent, or enable automatic agent upgrade (preview).
- Deploy monitoring next: Azure Monitor Agent with data collection rules works the same way on Arc-enabled servers as on Azure VMs.
- Bring the servers into a patch schedule with Azure Update Manager.
- Rotate or delete the onboarding secret when the last wave completes.
Troubleshooting
Add --verbose to any azcmagent command. Logs are written to %ProgramData%\AzureConnectedMachineAgent\Log\azcmagent.log on Windows and /var/opt/azcmagent/log/azcmagent.log on Linux; the Windows MSI writes to the path you pass with /l*v.
| Error | Probable cause | Fix |
|---|---|---|
| AZCM0018 | Command not run as administrator or root | Rerun elevated |
| AZCM0026 | Network configuration error or required endpoint unreachable | Run azcmagent check; for private link, pass --private-link-scope |
| AZCM0041 | Invalid credentials | Check the app ID, secret and expiry, and that the service principal is in the same tenant as the target subscription |
| AZCM0042 | Arc resource creation failed | Check the role assignment on the resource group |
| AZCM0044 | A resource with the same name exists | Use --resource-name or delete the stale Arc resource |
| AZCM0067 | Machine already connected | Run azcmagent disconnect first if you really want to reconnect |
| AZCM0141 (Linux), AZCM0147 (Windows) | Installing on an Azure VM | Don't onboard Azure VMs; on Linux, AZCM0147 instead means the requested agent version wasn't found |
Messages you may see in the verbose log:
Failed to acquire authorization token from SPN: Invalid client secret is providedmeans the secret is wrong or expired.Application with identifier '...' wasn't found in the directory '...'points to a wrong app ID or tenant ID.- A 403 for
Microsoft.HybridCompute/machines/readmeans the service principal lacks Azure Connected Machine Onboarding at that scope. Forbiddenresponses forlogin.windows.netormanagement.azure.commean a proxy or firewall is blocking the endpoint;azcmagent checkconfirms which one.- When creating the service principal,
ServiceManagementReference field is required for Create, but is missing in the requestmeans your account needs the Application Administrator or Cloud Application Administrator role, or your tenant's app registration policy must be satisfied.
Checklist
- Pilot completed on representative, non-critical servers.
- Resource providers registered; landing resource group, region and tags decided.
- Service principal scoped to the resource group with only Azure Connected Machine Onboarding; secret expiry recorded, or a certificate used.
- Endpoints and service tags allowed;
azcmagent checkpasses from each network segment. - Wrapper scripts connect with
--configand delete the file afterwards. - Waves rolled out; Group Policy object disabled after each wave.
- Resource Graph count matches the wave lists; Resource Health and Advisor alerts in place.
- Onboarding secret rotated or removed after the final wave.
References
- Connect hybrid machines to Azure at scale
- Connected Machine agent prerequisites
- Connected Machine agent network requirements
- CLI reference for azcmagent connect
- CLI reference for azcmagent check
- azcmagent CLI reference
- Connect hybrid machines using a deployment script
- Connect machines at scale using Group Policy
- Azure Connected Machine agent deployment options
- Plan and deploy Azure Arc-enabled servers
- Manage Connected Machine agent proxy settings
- Troubleshoot Connected Machine agent connection issues
- Azure Resource Graph sample queries for Arc-enabled servers