In this blog post, you’ll learn how to configure an Azure virtual machine (VM) as an Azure Arc-enabled server for learning, training, and testing purposes, as I walk you through the easy setup process using Azure PowerShell, a PowerShell script, and the free Azure Bastion Developer SKU.
⚠️ Keep in mind that this blog post and the steps to configure an Azure VM as an Arc-enabled server are meant exclusively for testing and research. They should never be used in a production environment or on critical Azure VMs.
In any normal scenario, you can’t connect an Azure VM as an Azure Arc-enabled server because it’s already represented in Azure Resource Manager, with all native Azure features and capabilities easily accessible if needed.
However, if you attempt to onboard any of your Azure VMs using the OnboardingScript.ps1, you’ll receive an error message stating that it’s unsupported, as shown in the screenshot below.

So, as you can see, by default, this isn’t possible. However, there are a few steps you can take as a workaround to onboard an Azure VM running Windows Server as an Arc-enabled server. This can be particularly useful for testing or learning purposes when you don’t have access to any on-premises machines.
In this blog post, I’ll walk you through the easy setup process using Azure PowerShell, a PowerShell script, and the free Azure Bastion Developer SKU.
Table of Contents
Azure prerequisites
- An Azure subscription is required for this process. Since the VM(s) will be used solely for training and testing, it’s recommended to use a sandboxed Azure subscription.
- An Azure Administrator account with the appropriate RBAC roles, such as Owner or Contributor at the subscription or resource group level.
- An existing Azure Arc OnboardingScript.ps1 file.



Deploying the Azure VM and other required resources with an Azure PowerShell script
To get started, we’ll first provision a new Azure VM in a dedicated resource group within the sandboxed subscription. You can either use the Azure Portal or, for a faster setup, run the Azure PowerShell script below.
This script will create a virtual network (VNet) in a specified resource group, deploy an Azure VM running Windows Server 2022 within the same resource group, and connect the VM to a subnet in the VNet.
To use the script, start by saving a copy as “Create-Azure-Windows-VM-with-VNet-and-RG-for-Azure-Arc-learning.ps1” or downloading it directly from GitHub. Adjust the dynamic and other variables to fit your specific needs, and then run the script using Windows Terminal, Visual Studio Code, or Windows PowerShell.

Before running the script, make sure to sign in with the Connect-AzAccount cmdlet to link your Azure account. If you have multiple Azure tenants, use the Set-AzContext -tenantID cmdlet to select the correct tenant before executing the script.

You can then run the script, with the required parameters.
.\Create-Azure-Windows-VM-with-VNet-and-RG-for-Azure-Arc-Learning.ps1 -SubscriptionName <"Subscription name here">

If you want to use a different VM size than the default “Standard_B2ms“, run the script with the following parameters.
.\Create-Azure-Windows-VM-with-VNet-and-RG-for-Azure-Arc-Learning.ps1 -SubscriptionName <"Subscription name here"> -vmSize <"vm size here">

<#
.SYNOPSIS
A script used to create an Azure Windows VM with a VNet and subnet, specifically for learning and testing with Azure Arc.
.DESCRIPTION
A script used to create an Azure Windows VM with a VNet and subnet, specifically for learning and testing with Azure Arc.
This script will do all of the following:
Suppress Azure PowerShell breaking change warning messages to avoid unnecessary output.
Change the current context to the specified subscription
Store the specified set of tags in a hash table.
Create a resource group for Azure Arc testing purposes, if it not already exists, and apply specified tags.
Create Network Watcher, if it not already exists, and apply specified tags.
Create Subnets, if they not already exist.
Create Virtual Network, if it not already exists, and apply specified tags.
Create the NIC the VM, if it not already exists, and apply specified tags.
Specify the local administrator account.
Get the latest Azure Marketplace VMImage for Windows Server 2022 that match the specified values, and store it in a varialbe for later use.
Create VM 1 if it not already exists, and apply specified tags.
Set tags on all disks in the resource group.
.NOTES
Filename: Create-Azure-Windows-VM-with-VNet-and-RG-for-Azure-Arc-Learning.ps1
Created: 21/02/2025
Last modified: 21/02/2025
Author: Wim Matthyssen
Version: 1.0
PowerShell: Azure PowerShell and Azure Cloud Shell
Requires: PowerShell Az (v10.4.1)
Action: Change variables were needed to fit your needs.
Disclaimer: This script is provided "As Is" with no warranties.
.EXAMPLE
Connect-AzAccount
Get-AzTenant (if not using the default tenant)
Set-AzContext -tenantID "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx" (if not using the default tenant)
.\Create-Azure-Windows-VM-for-Azure-Arc-learning.ps1 -SubscriptionName <"your Azure subscription name here"> -vmSize <"your VM size here">
Example 1: .\Create-Azure-Windows-VM-with-VNet-and-RG-for-Azure-Arc-Learning.ps1 -SubscriptionName "sub-tst-myh-sandbox-01"
Example 2: .\Create-Azure-Windows-VM-with-VNet-and-RG-for-Azure-Arc-Learning.ps1 -SubscriptionName "sub-tst-myh-sandbox-01" -vmSize "Standard__D2s_v3"
.LINK
Azure Arc: Using an Azure Windows VM as an Arc-enabled server for learning and training
#>
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Parameters
param(
# $subscriptionName -> Name of the Azure Subscription
[parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string] $subscriptionName,
# $vmSize -> Specifies the VM size.
[parameter(Mandatory=$false)][ValidateNotNullOrEmpty()][string] $vmSize = "Standard_B2ms"
)
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Variables
# Naming convention: example - rg-tst-arc-01 (resource type - spoke - purpose - inventory number)
# Dynamic variables - Please change the values to if required.
$spoke = "tst" # Abbreviation for the spoke (e.g., 'tst' for test, 'poc' for proof of concept). Change based on your environment.
$purpose = "arc" # Specifies the intended use of the resource group or service (e.g., 'arc' for Azure Arc). Update if different.
$addressPrefix = "10.23.1." # Address prefix for the virtual network subnets. Update if different.
# Other Configuration Variables
$inventoryNumbering = 1 # Inventory number for the resource (e.g., 1, 2, 3, etc. to differentiate resources).
$region = "westeurope" # Azure region (e.g., 'westeurope', 'eastus'). Replace with your current region if needed.
$regionShort = "we" # Short abbreviation for the Azure region (e.g., 'we' for West Europe, 'eus' for East US). Update if different.
# Resource groups Arc resources
$rgNameArcTst = "rg" + "-" + $spoke + "-" + $purpose + "-" + $inventoryNumbering.ToString("D2")
# Networking resources
$networkWatcherName = "nw" + "-" + $spoke + "-" + $regionShort + "-" + $inventoryNumbering.ToString("D2")
$vnetName = "vnet" + "-" + $spoke + "-" + $regionShort + "-" + $inventoryNumbering.ToString("D2")
$subnetNameGateway = "GatewaySubnet"
$subnetNameAzureBastion = "AzureBastionSubnet"
$subnetNameVm = "snet" + "-" + $spoke + "-" + "vm" + "-" + $inventoryNumbering.ToString("D2")
$subnetAddressPrefixGateway = $addressPrefix + "0/26"
$subnetAddressPrefixAzureBastion = $addressPrefix + "64/26"
$subnetAddressPrefixVm = $addressPrefix + "128/26"
$vnetAddressPrefix = $addressPrefix + "0/24"
# VM resources
$vmName01 = "swt" + $purpose + $inventoryNumbering.ToString("D3") # Specifies theVM name. Update if different.
$userName = "loc_arc" # Specifies the username for the VM. Update if different.
$password = "ArcF@lcon_7632" # Specifies the password for the VM. Update if different.
$osSKU01 = "2022-Datacenter" # Specifies the OS SKU for the VM. Update if different.
$osDiskNameVM01 = $vmName01 + "-" + "c" # Specifies the OS disk name for the VM. Update if different.
$osDiskSizeInGB = "127" # Specifies the OS disk size in GB. Update if different.
$diskStorageAccountType = "StandardSSD_LRS" # Premium_LRS = Premium SSD; StandardSSD_LRS = Standard SSD; Standard_LRS = Standard HHD
$nicNameVM01 = "nic" + "-" + "01" + "-" + $vmName01 # Specifies the NIC name for the VM. Update if different.
# Tags
$tagSpokeName = "Env" # The environment tag name you want to use.
$tagSpokeValue = "$($spoke[0].ToString().ToUpper())$($spoke.SubString(1))"
$tagOSVersionName = "OperatingSystem" # The operating system tag name you want to use.
# Other variables
Set-PSBreakpoint -Variable currenttime -Mode Read -Action
Get-AzResourceGroup -Name $rgNameArcTst -ErrorAction Stop | Out-Null
$foregroundColor1 = "Green"
$foregroundColor2 = "Yellow"
$foregroundColor3 = "Red"
$writeEmptyLine = "`n"
$writeSeperatorSpaces = " - "
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Suppress Azure PowerShell breaking change warning messages to avoid unnecessary output.
Set-Item -Path Env:\SuppressAzurePowerShellBreakingChangeWarnings -Value $true | Out-Null
Update-AzConfig -DisplayBreakingChangeWarning $false | Out-Null
Update-AzConfig -DisplayRegionIdentified $false | Out-Null
$warningPreference = "SilentlyContinue"
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script started.
Write-Host ($writeEmptyLine + "# Script started. Without errors, it can take up to 4 minutes to complete" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Change the current context to the specified subscription.
$subName = Get-AzSubscription | Where-Object
New-AzResourceGroup -Name $rgNameArcTst.ToLower() -Location $region -Force
Set-AzContext -SubscriptionId $subName.SubscriptionId | Out-Null
Write-Host ($writeEmptyLine + "# Specified subscription in current tenant selected" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Store the specified set of tags in a hash table.
$tags = @
Get-AzNetworkWatcher -Name $networkWatcherName -ResourceGroupName $rgNameArcTst -ErrorAction Stop
Write-Host ($writeEmptyLine + "# Specified set of tags available to add" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Create a resource group for Azure Arc testing purposes, if it not already exists, and apply specified tags.
try Out-Null
catch Out-Null
# Set tags Azure Arc-enabled servers resource group
Set-AzResourceGroup -Name $rgNameArcTst -Tag $tags | Out-Null
Write-Host ($writeEmptyLine + "# Resource group $rgNameArcTst available" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Create Network Watcher, if it not already exists, and apply specified tags.
try Out-Null
catch
Get-AzNetworkInterface -ResourceGroupName $rgNameArcTst -Name $nicNameVM01 -ErrorAction Stop
Write-Host ($writeEmptyLine + "# Network watcher $rgNameArcTst created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Create Subnets, if they not already exist.
$gatewaySubnet = New-AzVirtualNetworkSubnetConfig -Name $subnetNameGateway -AddressPrefix $subnetAddressPrefixGateway
$azureBastionSubnet = New-AzVirtualNetworkSubnetConfig -Name $subnetNameAzureBastion -AddressPrefix $subnetAddressPrefixAzureBastion
$vmSubnet = New-AzVirtualNetworkSubnetConfig -Name $subnetNameVm -AddressPrefix $subnetAddressPrefixVm
Write-Host ($writeEmptyLine + "# Virtual network subnet configurations $vnetName created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Create Virtual Network, if it not already exists, and apply specified tags.
$subnets = $gatewaySubnet,$azureBastionSubnet,$vmSubnet
try
New-AzNetworkInterface -Name $nicNameVM01.ToLower() -ResourceGroupName $rgNameArcTst -Location $region -SubnetId $subnetID catch Out-Null
# Set tags VNet
$vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupname $rgNameArcTst
$vnet.Tag = $tags
Set-AzVirtualNetwork -VirtualNetwork $vnet | Out-Null
Write-Host ($writeEmptyLine + "# VNet $vnetName created and configured" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Create the NIC the VM, if it not already exists, and apply specified tags.
# Get the VNet to which to connect the NIC
$vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupname $rgNameArcTst
# Get the Subnet ID to which to connect the NIC
$subnetID = (Get-AzVirtualNetworkSubnetConfig -Name $subnetNameVm -VirtualNetwork $vnet).Id
# Create dynamic NIC VM 1
try
Get-AzNetworkInterface -ResourceGroupName $rgNameArcTst -Name $nicNameVM01 -ErrorAction Stop catch Out-Null
# Store NIC VM 1 in a variable
$nicVM01 = Get-AzNetworkInterface -ResourceGroupName $rgNameArcTst -Name $nicNameVM01
# Set private IP address NIC VM 1 to static
$nicVM01.IpConfigurations[0].PrivateIpAllocationMethod = "Static"
Set-AzNetworkInterface -NetworkInterface $nicVM01 | Out-Null
# Set tags on NIC VM1
$nicVM01.Tag = $tags
Set-AzNetworkInterface -NetworkInterface $nicVM01 | Out-Null
Write-Host ($writeEmptyLine + "# NIC $nicNameVM01 created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Specify the local administrator account.
$passwordSec = convertto-securestring $password -asplaintext -force
$creds = New-Object System.Management.Automation.PSCredential($userName,$passwordSec)
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Get the latest Azure Marketplace VMImage for Windows Server 2022 that is not deprecated
$images01 = Get-AzVMImage -Location $region -PublisherName "MicrosoftWindowsServer" -Offer "WindowsServer" -Skus $osSKU01 |
Where-Object { $_.ReplicationStatus -ne "Deprecated" } |
Sort-Object -Descending -Property PublishedDate
# Check if any valid images are available
if (-not $images01) {
throw "No valid VM images found for the specified OS SKU: $osSKU01. Ensure that non-deprecated images are available."
}
Write-Host ($writeEmptyLine + "# Latest non-deprecated Azure Marketplace VM image selected" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Create VM 1 if it not already exists, and apply specified tags.
Write-Host ($writeEmptyLine + "# Creating VM $vmName01 in resource group $rgNameArcTst" + $writeSeperatorSpaces + $currentTime) -ForegroundColor $foregroundColor2 $writeEmptyLine
try {
if (-not (Get-AzVM -ResourceGroupName $rgNameArcTst -Name $vmName01 -ErrorAction SilentlyContinue)) {
# Create a configurable VM object
$vm01 = New-AzVMConfig -Name $vmName01.ToLower() -VMSize $vmSize
# Add the NIC
Add-AzVMNetworkInterface -VM $vm01 -Id $nicVM01.Id | Out-Null
# Specify the image
if (-not $images01) {
throw "No VM images found for the specified OS SKU: $osSKU01"
}
Set-AzVMSourceImage -VM $vm01 -PublisherName $images01[0].PublisherName -Offer $images01[0].Offer -Skus $images01[0].Skus -Version $images01[0].Version | Out-Null
# Set OS properties
Set-AzVMOperatingSystem -VM $vm01 -Windows -ProvisionVMAgent -EnableAutoUpdate -Credential $creds -ComputerName $vmName01 | Out-Null
# Set OS disk properties
Set-AzVMOSDisk -VM $vm01 -name $osDiskNameVM01 -CreateOption fromImage -DiskSizeInGB $osDiskSizeInGB -StorageAccountType $diskStorageAccountType -Windows | Out-Null
# Disable boot diagnostics
$vm01.DiagnosticsProfile = [Microsoft.Azure.Management.Compute.Models.DiagnosticsProfile]@{
BootDiagnostics = [Microsoft.Azure.Management.Compute.Models.BootDiagnostics]@{
Enabled = $false
}
}
# Create VM
New-AzVM -ResourceGroupName $rgNameArcTst -Location $region -VM $vm01 -OSDiskDeleteOption Delete -Confirm:$false | Out-Null
}
} catch {
Write-Host "Error creating VM: $_" -ForegroundColor $foregroundColor3
throw
}
# Set tags on VM1
$vm01 = Get-AzVM -ResourceGroupName $rgNameArcTst -Name $vmName01
Update-AzTag -Tag $tags -ResourceId $vm01.Id -Operation Merge | Out-Null
# Get OS version VM1
$osVersion = $vm01.StorageProfile.ImageReference.Offer + " $($vm01.StorageProfile.ImageReference.Sku)"
# Add OS tag to VM1
$osTag = @{$tagOSVersionName = $osVersion}
Update-AzTag -ResourceId $vm01.Id -Tag $osTag -Operation Merge | Out-Null
Write-Host ($writeEmptyLine + "# VM $vmName01 created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Set tags on all disks in the resource group.
try {
Get-AzDisk -ResourceGroupName $resourceGroupName -DiskName $diskNames | ForEach-Object {New-AzTag -ResourceId $_.Id -Tag $tags} | Out-Null
Write-Host ($writeEmptyLine + "# Tags set to all disks in the resource group $rgVMSpoke" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
} catch {
Write-Host "Error tagging disks: $_" -ForegroundColor $foregroundColor3
}
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script completed.
Write-Host ($writeEmptyLine + "# Script completed" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



Deploy Azure Bastion Developer
To prepare the Azure VM for onboarding to Azure Arc, we need to connect and log in to it in order to perform the necessary steps for configuration.
I prefer using Azure Bastion for this, and fortunately, for Dev/Test purposes, you can now easily set up an Azure Bastion Developer, which is a free, lightweight version of the Azure Bastion service.
Currently, deploying this Bastion SKU with Azure PowerShell is not possible. To set it up, log in to the Azure Portal, and in the global search bar, type in “bastion”. Then click on Bastions.

Then, click on + Create.

Next, fill in all the fields on the Basics page. Select the correct subscription and resource group, provide a name, and choose the appropriate region. Most importantly, select Developer as the Tier and specify the newly created VNet. Then, click Next: Advanced >.

Then, specify the tags you want to use and click Next: Review + create.

Then, click Create to deploy your Bastion Developer host.


Prepare the Azure VM for onboarding to Azure Arc
To manage your Azure VM as an Azure Arc-enabled server, you first need to make a few changes to the VM before installing and configuring it. All these steps will be explained in this section.
First, all VM extensions deployed to the Azure VM should be removed. If you followed the previous steps to deploy a new VM, no extensions, such as the Azure Monitor agent, should be installed. The only extension present should be the default BGInfo extension, which should not be removed.

The next step is to set the environment variable to override the ARC installation on the Azure VM, then disable the Azure VM Guest Agent. Finally, you’ll need to block access to the Azure IMDS endpoint.
To make these steps easier, you can either copy the PowerShell script below or download it from GitHub.
<#
.SYNOPSIS
A script used to prepare an Azure Windows VM for onboarding to Azure Arc, specifically for learning and testing.
.DESCRIPTION
A script used to prepare an Azure Windows VM for onboarding to Azure Arc, specifically for learning and testing.
This script will do all of the following:
Prepare Azure VM for onboarding to Azure Arc.
.NOTES
Filename: Prepare-Azure-Windows-VM-for-onboarding-to-Azure-Arc.ps1
Created: 21/02/2025
Last modified: 21/02/2025
Author: Wim Matthyssen
Version: 1.0
PowerShell: Azure PowerShell and Azure Cloud Shell
Requires: PowerShell Az (v10.4.1)
Action: Change variables were needed to fit your needs.
Disclaimer: This script is provided "As Is" with no warranties.
.EXAMPLE
.\Prepare-Azure-Windows-VM-for-onboarding-to-Azure-Arc
.LINK
Azure Arc: Using an Azure Windows VM as an Arc-enabled server for learning and training
#>
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Variables
Set-PSBreakpoint -Variable currenttime -Mode Read -Action {$global:currenttime = Get-Date -Format "dddd MM/dd/yyyy HH:mm"} | Out-Null
$foregroundColor1 = "Green"
$foregroundColor2 = "Yellow"
$writeEmptyLine = "`n"
$writeSeperatorSpaces = " - "
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script started.
Write-Host ($writeEmptyLine + "# Script started. Without errors, it can take up to 2 minutes to complete" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Prepare Azure VM for onboarding to Azure Arc
# Set the environment variable to override the ARC on an Azure VM installation
[System.Environment]::SetEnvironmentVariable("MSFT_ARC_TEST",'true', [System.EnvironmentVariableTarget]::Machine)
# Disable the Azure VM Guest Agent
Set-Service WindowsAzureGuestAgent -StartupType Disabled -Verbose
Stop-Service WindowsAzureGuestAgent -Force -Verbose
# Block access to Azure IMDS endpoint
New-NetFirewallRule -Name BlockAzureIMDS -DisplayName "Block access to Azure IMDS" -Enabled True -Profile Any -Direction Outbound -Action Block -RemoteAddress 169.254.169.254
Write-Host ($writeEmptyLine + "# Azure VM is now ready for onboarding to Azure Arc" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script completed.
Write-Host ($writeEmptyLine + "# Script completed" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
After copying the script or downloading it from GitHub, open it in Visual Studio Code or your preferred editor.
Then, go to the Azure Portal and navigate to the Azure VM you deployed or want to onboard to Azure Arc. In the VM blade, scroll down to the Connect section and click Bastion.

On the Bastion page, enter the Username and VM Password, then click Connect.
💡 On this screen, you can also adjust the Keyboard Language to match your keyboard settings.

If you’ve entered the correct username and password, the connection to the VM via Bastion Developer will open directly in the Azure portal (using HTML5) over port 443 with the Bastion service, and it will open in a new tab.
When prompted for clipboard permissions, select Allow. This will enable you to use the remote clipboard and the arrows on the left side of the screen.

On the VM, open Windows PowerShell ISE. Then, in a new script file, copy the content of the script you copied above or downloaded from GitHub. After that, click the Run Script button to execute the script.



Onboard the Azure VM as an Azure Arc-enabled server
The final step is to onboard the Azure VM as an Azure Arc-enabled server. To do this, copy the content of the OnboardingScript.ps1 into a new script file in PowerShell ISE on the VM, and then run the script.






Conclusion
While it’s strongly not advised to install Azure Arc-enabled servers on an Azure VM for production scenarios, it is possible to configure Azure Arc-enabled servers on an Azure VM for training and testing purposes only.
In this blog post, I’ll show you how to accomplish this using Azure PowerShell, a standard PowerShell script, and the Azure Bastion Developer host to configure everything in an easy and free way.
If you have any questions or suggestions regarding this blog post and the use scripts, feel free to reach out to me via my X handle (@wmatthyssen) or leave a comment below. I’m happy to help!