This page contains Windows bias

About This Page

This page is part of the Azure documentation. It contains code examples and configuration instructions for working with Azure services.

Bias Analysis

Bias Types:
⚠️ windows_first
⚠️ windows_tools
⚠️ missing_linux_example
⚠️ powershell_heavy
Summary:
The documentation demonstrates a notable Windows bias, particularly in the testing and validation phases. While the infrastructure setup is cross-platform (Portal, PowerShell, CLI), the test virtual machines in both spokes are exclusively Windows Server 2022, and all test/validation steps (IIS installation, browser-based tests using Microsoft Edge, PowerShell scripts) are Windows-centric. There are no equivalent examples or instructions for deploying or testing with Linux-based VMs in the spokes, nor are Linux tools (e.g., curl, Apache/nginx, SSH) mentioned for validation. The use of PowerShell and Windows tools is prevalent, and Windows-based patterns are presented as the default for validation.
Recommendations:
  • Provide parallel Linux-based test VM instructions for the spokes, including deployment, configuration, and validation steps (e.g., using Ubuntu or CentOS, installing Apache/nginx, and using curl or wget for testing).
  • Include Linux command-line examples for validation (e.g., curl http://<ip-address> to test web server connectivity, or using lynx/w3m as text browsers).
  • When demonstrating IIS installation and testing, also show how to install and test a web server on Linux (e.g., sudo apt install apache2, echo 'Hello World' > /var/www/html/index.html).
  • Instruct on using SSH and Linux shell commands for connectivity and troubleshooting, not just RDP/Edge/PowerShell.
  • Balance the use of Windows and Linux tools in all test and validation sections, and avoid assuming the user will always use Windows VMs or Microsoft browsers.
  • Explicitly mention that either Windows or Linux VMs can be used for testing, and provide guidance for both.
GitHub Create pull request

Scan History

Date Scan ID Status Bias Status
2025-08-17 00:01 #83 in_progress ✅ Clean
2025-07-13 21:37 #48 completed ✅ Clean
2025-07-12 23:44 #41 in_progress ❌ Biased
2025-07-09 13:09 #3 cancelled ✅ Clean
2025-07-08 04:23 #2 cancelled ❌ Biased

Flagged Code Snippets

$routeTableParams = @{ ResourceGroupName = "test-rg" Name = "route-table-nat-spoke-1" Location = "southcentralus" } New-AzRouteTable @routeTableParams
$nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-1" SubnetId = (Get-AzVirtualNetwork -ResourceGroupName "test-rg" -Name "vnet-spoke-1").Subnets[0].Id NetworkSecurityGroupId = (Get-AzNetworkSecurityGroup -ResourceGroupName "test-rg" -Name "nsg-spoke-1").Id Location = "southcentralus" } New-AzNetworkInterface @nicParams
$vmParams = @{ VM = $vmConfig ResourceGroupName = "test-rg" Location = "southcentralus" } New-AzVM @vmParams
az vm extension set \ --publisher Microsoft.Compute \ --version 1.8 \ --name CustomScriptExtension \ --vm-name vm-spoke-1 \ --resource-group test-rg \ --settings '{"commandToExecute":"powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\default.htm\" -Value $($env:computername)"}'
$routeTableParams = @{ ResourceGroupName = "test-rg" Name = "route-table-nat-spoke-2" Location = "westus2" } New-AzRouteTable @routeTableParams
$nsgParams = @{ ResourceGroupName = "test-rg" Name = "nsg-spoke-2" Location = "westus2" } New-AzNetworkSecurityGroup @nsgParams
$cred = Get-Credential
$vmParams = @{ VM = $vmConfig ResourceGroupName = "test-rg" Location = "westus2" } New-AzVM @vmParams
Success Restart Needed Exit Code Feature Result ------- -------------- --------- -------------- True No Success {Common HTTP Features, Default Document, D...
$rgParams = @{ Name = "test-rg" Force = $true } Remove-AzResourceGroup @rgParams
$rgParams = @{ Name = "test-rg" Location = "eastus2" } New-AzResourceGroup @rgParams
$publicIpParams = @{ ResourceGroupName = "test-rg" Name = "public-ip-nat" Sku = "Standard" AllocationMethod = "Static" Location = "eastus2" Zone = 1,2,3 } $publicIp = New-AzPublicIpAddress @publicIpParams
$natGatewayParams = @{ ResourceGroupName = "test-rg" Name = "nat-gateway" PublicIpAddress = $publicIp Sku = 'Standard' IdleTimeoutInMinutes = 4 Location = "eastus2" } New-AzNatGateway @natGatewayParams
$subnetPrivateParams = @{ Name = "subnet-private" AddressPrefix = "10.0.0.0/24" } $privateSubnetConfig = New-AzVirtualNetworkSubnetConfig @subnetPrivateParams $subnetBastionParams = @{ Name = "AzureBastionSubnet" AddressPrefix = "10.0.1.0/26" } $bastionSubnetConfig = New-AzVirtualNetworkSubnetConfig @subnetBastionParams $subnetPublicParams = @{ Name = "subnet-public" AddressPrefix = "10.0.253.0/28" NatGateway = (Get-AzNatGateway -ResourceGroupName "test-rg" -Name "nat-gateway") } $publicSubnetConfig = New-AzVirtualNetworkSubnetConfig @subnetPublicParams
$vNetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-hub" AddressPrefix = "10.0.0.0/16" Location = "eastus2" Subnet = $privateSubnetConfig, $bastionSubnetConfig, $publicSubnetConfig } $vNet = New-AzVirtualNetwork @vNetParams
$publicIpParams = @{ ResourceGroupName = "test-rg" Name = "public-ip-bastion" Sku = "Standard" AllocationMethod = "Static" Location = "eastus2" Zone = 1,2,3 } New-AzPublicIpAddress @publicIpParams
$bastionParams = @{ ResourceGroupName = "test-rg" Name = "bastion" VirtualNetworkName = "vnet-hub" PublicIpAddressName = "public-ip-bastion" PublicIPAddressRgName = "test-rg" VirtualNetworkRgName = "test-rg" } New-AzBastion @bastionParams
$nsgParams = @{ ResourceGroupName = "test-rg" Name = "nsg-nva" Location = "eastus2" } New-AzNetworkSecurityGroup @nsgParams
$nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-public" SubnetId = (Get-AzVirtualNetwork -ResourceGroupName "test-rg" -Name "vnet-hub").Subnets[1].Id NetworkSecurityGroupId = (Get-AzNetworkSecurityGroup -ResourceGroupName "test-rg" -Name "nsg-nva").Id Location = "eastus2" } New-AzNetworkInterface @nicParams
$cred = Get-Credential
$vmConfigParams = @{ VMName = "vm-nva" VMSize = "Standard_DS4_v2" } $vmConfig = New-AzVMConfig @vmConfigParams
$osParams = @{ VM = $vmConfig ComputerName = "vm-nva" Credential = $cred } $vmConfig = Set-AzVMOperatingSystem @osParams -Linux -DisablePasswordAuthentication $imageParams = @{ VM = $vmConfig PublisherName = "Canonical" Offer = "ubuntu-24_04-lts" Skus = "server" Version = "latest" } $vmConfig = Set-AzVMSourceImage @imageParams
# Get the network interface object $nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-public" } $nic = Get-AzNetworkInterface @nicParams $vmConfigParams = @{ VM = $vmConfig Id = $nic.Id } $vmConfig = Add-AzVMNetworkInterface @vmConfigParams
$vmParams = @{ VM = $vmConfig ResourceGroupName = "test-rg" Location = "eastus2" SshKeyName = "ssh-key" } New-AzVM @vmParams -GenerateSshKey
$nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-public" } $nic = Get-AzNetworkInterface @nicParams $nic.EnableIPForwarding = $true Set-AzNetworkInterface -NetworkInterface $nic
$nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-public" } $nic = Get-AzNetworkInterface @nicParams $nic.IpConfigurations[0].PrivateIpAllocationMethod = "Static" $nic.IpConfigurations[0].PrivateIpAddress = "10.0.253.10" Set-AzNetworkInterface -NetworkInterface $nic
$vmParams = @{ ResourceGroupName = "test-rg" Name = "vm-nva" } $vm = Get-AzVM @vmParams $nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-public" } $nic = Get-AzNetworkInterface @nicParams $vm.NetworkProfile.NetworkInterfaces | ForEach-Object { $_.Primary = $false } $vm.NetworkProfile.NetworkInterfaces | Where-Object { $_.Id -eq $nic.Id } | ForEach-Object { $_.Primary = $true } $updateParams = @{ ResourceGroupName = "test-rg" VM = $vm } Update-AzVM @updateParams
$nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-private" SubnetId = (Get-AzVirtualNetwork -ResourceGroupName "test-rg" -Name "vnet-hub").Subnets[0].Id PrivateIpAddress = "10.0.0.10" Location = "eastus2" } New-AzNetworkInterface @nicParams
$vmParams = @{ ResourceGroupName = "test-rg" Name = "vm-nva" Force = $true } Stop-AzVM @vmParams
$vmParams = @{ ResourceGroupName = "test-rg" Name = "vm-nva" } $vm = Get-AzVM @vmParams $nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-private" } $nic = Get-AzNetworkInterface @nicParams $vm = Add-AzVMNetworkInterface -VM $vm -Id $nic.Id $updateParams = @{ ResourceGroupName = "test-rg" VM = $vm } Update-AzVM @updateParams
$startVmParams = @{ ResourceGroupName = "test-rg" Name = "vm-nva" } Start-AzVM @startVmParams
$routeTableParams = @{ ResourceGroupName = "test-rg" Name = "route-table-nat-hub" Location = "eastus2" } New-AzRouteTable @routeTableParams
$routeConfigParams = @{ Name = "default-via-nat-hub" AddressPrefix = "0.0.0.0/0" NextHopType = "VirtualAppliance" NextHopIpAddress = "10.0.0.10" } $routeTableParams = @{ ResourceGroupName = "test-rg" Name = "route-table-nat-hub" } $routeTable = Get-AzRouteTable @routeTableParams $routeTable | Add-AzRouteConfig @routeConfigParams | Set-AzRouteTable
$vnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-hub" } $vnet = Get-AzVirtualNetwork @vnetParams $subnetParams = @{ VirtualNetwork = $vnet Name = "subnet-private" } $subnet = Get-AzVirtualNetworkSubnetConfig @subnetParams $subnet.RouteTable = $routeTable Set-AzVirtualNetwork -VirtualNetwork $vnet
$vnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-spoke-1" AddressPrefix = "10.1.0.0/16" Location = "southcentralus" } New-AzVirtualNetwork @vnetParams
$vnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-spoke-1" } $vnet = Get-AzVirtualNetwork @vnetParams $subnetParams = @{ VirtualNetwork = $vnet Name = "subnet-private" AddressPrefix = "10.1.0.0/24" } Add-AzVirtualNetworkSubnetConfig @subnetParams Set-AzVirtualNetwork -VirtualNetwork $vnet
# Create peering from hub to spoke one $hubVnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-hub" } $hubVnet = Get-AzVirtualNetwork @hubVnetParams $spokeVnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-spoke-1" } $spokeVnet = Get-AzVirtualNetwork @spokeVnetParams $hubToSpokeParams = @{ Name = "vnet-hub-to-vnet-spoke-1" VirtualNetwork = $hubVnet RemoteVirtualNetworkId = $spokeVnet.Id AllowForwardedTraffic = $true } Add-AzVirtualNetworkPeering @hubToSpokeParams # Create peering from spoke one to hub $spokeToHubParams = @{ Name = "vnet-spoke-1-to-vnet-hub" VirtualNetwork = $spokeVnet RemoteVirtualNetworkId = $hubVnet.Id AllowForwardedTraffic = $true } Add-AzVirtualNetworkPeering @spokeToHubParams
$routeConfigParams = @{ Name = "default-via-nat-spoke-1" AddressPrefix = "0.0.0.0/0" NextHopType = "VirtualAppliance" NextHopIpAddress = "10.0.0.10" } $routeTableParams = @{ ResourceGroupName = "test-rg" Name = "route-table-nat-spoke-1" } $routeTable = Get-AzRouteTable @routeTableParams $routeTable | Add-AzRouteConfig @routeConfigParams | Set-AzRouteTable
$vnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-spoke-1" } $vnet = Get-AzVirtualNetwork @vnetParams $subnetParams = @{ VirtualNetwork = $vnet Name = "subnet-private" } $subnet = Get-AzVirtualNetworkSubnetConfig @subnetParams $subnet.RouteTable = $routeTable Set-AzVirtualNetwork -VirtualNetwork $vnet
$nsgParams = @{ ResourceGroupName = "test-rg" Name = "nsg-spoke-1" Location = "southcentralus" } New-AzNetworkSecurityGroup @nsgParams
$nsgParams = @{ ResourceGroupName = "test-rg" Name = "nsg-spoke-1" } $nsg = Get-AzNetworkSecurityGroup @nsgParams $ruleParams = @{ Name = "allow-http" Priority = 1000 Direction = "Inbound" Access = "Allow" Protocol = "Tcp" SourceAddressPrefix = "*" SourcePortRange = "*" DestinationAddressPrefix = "*" DestinationPortRange = "80" } $nsg | Add-AzNetworkSecurityRuleConfig @ruleParams Set-AzNetworkSecurityGroup -NetworkSecurityGroup $nsg
$cred = Get-Credential
$vmConfigParams = @{ VMName = "vm-spoke-1" VMSize = "Standard_DS4_v2" } $vmConfig = New-AzVMConfig @vmConfigParams
$osParams = @{ VM = $vmConfig ComputerName = "vm-spoke-1" Credential = $cred } $vmConfig = Set-AzVMOperatingSystem @osParams -Windows $imageParams = @{ VM = $vmConfig PublisherName = "MicrosoftWindowsServer" Offer = "WindowsServer" Skus = "2022-Datacenter" Version = "latest" } $vmConfig = Set-AzVMSourceImage @imageParams
# Get the network interface object $nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-1" } $nic = Get-AzNetworkInterface @nicParams $vmConfigParams = @{ VM = $vmConfig Id = $nic.Id } $vmConfig = Add-AzVMNetworkInterface @vmConfigParams
az vm create \ --resource-group test-rg \ --name vm-spoke-1 \ --image Win2022Datacenter \ --size Standard_DS2_v2 \ --admin-username azureuser \ --nics nic-1
# Install IIS server role Install-WindowsFeature -name Web-Server -IncludeManagementTools # Remove default htm file Remove-Item C:\inetpub\wwwroot\iisstart.htm # Add a new htm file that displays server name Add-Content -Path "C:\inetpub\wwwroot\iisstart.htm" -Value $("Hello World from " + $env:computername)
Success Restart Needed Exit Code Feature Result ------- -------------- --------- -------------- True No Success {Common HTTP Features, Default Document, D...
$vmExtensionParams = @{ ResourceGroupName = "test-rg" VMName = "vm-spoke-1" Name = "CustomScriptExtension" Publisher = "Microsoft.Compute" Type = "CustomScriptExtension" TypeHandlerVersion = "1.10" Settings = @{ "commandToExecute" = "powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path 'C:\inetpub\wwwroot\default.htm' -Value vm-spoke-1" } } Set-AzVMExtension @vmExtensionParams
$vnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-spoke-2" AddressPrefix = "10.2.0.0/16" Location = "westus2" } New-AzVirtualNetwork @vnetParams
$vnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-spoke-2" } $vnet = Get-AzVirtualNetwork @vnetParams $subnetParams = @{ VirtualNetwork = $vnet Name = "subnet-private" AddressPrefix = "10.2.0.0/24" } Add-AzVirtualNetworkSubnetConfig @subnetParams Set-AzVirtualNetwork -VirtualNetwork $vnet
# Create peering from hub to spoke two $hubVnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-hub" } $hubVnet = Get-AzVirtualNetwork @hubVnetParams $spokeVnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-spoke-2" } $spokeVnet = Get-AzVirtualNetwork @spokeVnetParams $hubToSpokeParams = @{ Name = "vnet-hub-to-vnet-spoke-2" VirtualNetwork = $hubVnet RemoteVirtualNetworkId = $spokeVnet.Id AllowForwardedTraffic = $true } Add-AzVirtualNetworkPeering @hubToSpokeParams # Create peering from spoke two to hub $spokeToHubParams = @{ Name = "vnet-spoke-2-to-vnet-hub" VirtualNetwork = $spokeVnet RemoteVirtualNetworkId = $hubVnet.Id AllowForwardedTraffic = $true } Add-AzVirtualNetworkPeering @spokeToHubParams
$routeParams = @{ Name = "default-via-nat-spoke-2" AddressPrefix = "0.0.0.0/0" NextHopType = "VirtualAppliance" NextHopIpAddress = "10.0.0.10" } $routeTableParams = @{ ResourceGroupName = "test-rg" Name = "route-table-nat-spoke-2" } $routeTable = Get-AzRouteTable @routeTableParams $routeTable | Add-AzRouteConfig @routeParams | Set-AzRouteTable
$vnetParams = @{ ResourceGroupName = "test-rg" Name = "vnet-spoke-2" } $vnet = Get-AzVirtualNetwork @vnetParams $subnetParams = @{ VirtualNetwork = $vnet Name = "subnet-private" } $subnet = Get-AzVirtualNetworkSubnetConfig @subnetParams $subnet.RouteTable = $routeTable Set-AzVirtualNetwork -VirtualNetwork $vnet
$ruleParams = @{ Name = "allow-http" Priority = 1000 Direction = "Inbound" Access = "Allow" Protocol = "Tcp" SourceAddressPrefix = "*" SourcePortRange = "*" DestinationAddressPrefix = "*" DestinationPortRange = "80" } $nsg = Get-AzNetworkSecurityGroup -ResourceGroupName "test-rg" -Name "nsg-spoke-2" $nsg | Add-AzNetworkSecurityRuleConfig @ruleParams Set-AzNetworkSecurityGroup -NetworkSecurityGroup $nsg
$nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-2" SubnetId = (Get-AzVirtualNetwork -ResourceGroupName "test-rg" -Name "vnet-spoke-2").Subnets[0].Id NetworkSecurityGroupId = (Get-AzNetworkSecurityGroup -ResourceGroupName "test-rg" -Name "nsg-spoke-2").Id Location = "westus2" } New-AzNetworkInterface @nicParams
$vmConfigParams = @{ VMName = "vm-spoke-2" VMSize = "Standard_DS4_v2" } $vmConfig = New-AzVMConfig @vmConfigParams
$osParams = @{ VM = $vmConfig ComputerName = "vm-spoke-2" Credential = $cred } $vmConfig = Set-AzVMOperatingSystem @osParams -Windows $imageParams = @{ VM = $vmConfig PublisherName = "MicrosoftWindowsServer" Offer = "WindowsServer" Skus = "2022-Datacenter" Version = "latest" } $vmConfig = Set-AzVMSourceImage @imageParams
# Get the network interface object $nicParams = @{ ResourceGroupName = "test-rg" Name = "nic-2" } $nic = Get-AzNetworkInterface @nicParams $vmConfigParams = @{ VM = $vmConfig Id = $nic.Id } $vmConfig = Add-AzVMNetworkInterface @vmConfigParams
az vm create \ --resource-group test-rg \ --name vm-spoke-2 \ --image Win2022Datacenter \ --size Standard_DS2_v2 \ --admin-username azureuser \ --nics nic-2
# Install IIS server role Install-WindowsFeature -name Web-Server -IncludeManagementTools # Remove default htm file Remove-Item C:\inetpub\wwwroot\iisstart.htm # Add a new htm file that displays server name Add-Content -Path "C:\inetpub\wwwroot\iisstart.htm" -Value $("Hello World from " + $env:computername)
$vmExtensionParams = @{ ResourceGroupName = "test-rg" VMName = "vm-spoke-2" Name = "CustomScriptExtension" Publisher = "Microsoft.Compute" Type = "CustomScriptExtension" TypeHandlerVersion = "1.10" Settings = @{ "commandToExecute" = "powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path 'C:\inetpub\wwwroot\default.htm' -Value vm-spoke-2" } } Set-AzVMExtension @vmExtensionParams
az vm extension set \ --publisher Microsoft.Compute \ --version 1.8 \ --name CustomScriptExtension \ --vm-name vm-spoke-2 \ --resource-group test-rg \ --settings '{"commandToExecute":"powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\Default.htm\" -Value $($env:computername)"}'