Sad Tux - Windows bias detected
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

Detected Bias Types
windows_first
powershell_heavy
windows_tools
missing_linux_example
Summary
The documentation demonstrates a Windows bias in several areas: (1) Windows Server virtual machines are used exclusively for test workloads, with no Linux VM alternatives or examples; (2) IIS (a Windows-only web server) is installed for testing, with no mention of Linux-based web servers (e.g., Apache, Nginx); (3) All test and verification steps (such as browsing with Microsoft Edge and using PowerShell scripts) are Windows-centric, with no Linux equivalents; (4) PowerShell and Windows tools are referenced heavily, and Linux alternatives are not provided or are only mentioned in passing.
Recommendations
  • Provide parallel Linux-based examples for test workloads, such as deploying Ubuntu or other Linux VMs in the spokes, and using Apache or Nginx for web server testing.
  • Include Linux command-line instructions (e.g., using curl or wget) for testing outbound connectivity and inter-spoke routing, alongside the Microsoft Edge/Windows instructions.
  • Offer Bash shell scripts or Azure CLI examples for configuration and testing, not just PowerShell.
  • When demonstrating installation of web servers or other software, show both Windows (IIS) and Linux (Apache/Nginx) options.
  • Explicitly mention that either Windows or Linux can be used for test VMs, and provide guidance for both.
  • Balance the order of presentation so that Linux and Windows are given equal prominence, or alternate which OS is presented first in examples.
GitHub Create Pull Request

Scan History

Date Scan Status Result
2026-01-14 00:00 #250 in_progress Biased Biased
2026-01-13 00:00 #246 completed Biased Biased
2026-01-11 00:00 #240 completed Biased Biased
2026-01-10 00:00 #237 completed Biased Biased
2026-01-09 00:34 #234 completed Biased Biased
2026-01-08 00:53 #231 completed Biased Biased
2026-01-06 18:15 #225 cancelled Clean Clean
2025-08-17 00:01 #83 cancelled Clean Clean
2025-07-13 21:37 #48 completed Clean Clean
2025-07-12 23:44 #41 cancelled Biased Biased
2025-07-09 13:09 #3 cancelled Clean Clean
2025-07-08 04:23 #2 cancelled Biased Biased

Flagged Code Snippets

$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
# 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
$vmParams = @{
    VM = $vmConfig
    ResourceGroupName = "test-rg"
    Location = "southcentralus"
    }
New-AzVM @vmParams
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
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)"}'
$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
$vmParams = @{
    VM = $vmConfig
    ResourceGroupName = "test-rg"
    Location = "eastus2"
    SshKeyName = "ssh-key"
    }
New-AzVM @vmParams -GenerateSshKey
$nsgParams = @{
    ResourceGroupName = "test-rg"
    Name = "nsg-spoke-1"
    Location = "southcentralus"
}
New-AzNetworkSecurityGroup @nsgParams
$cred = Get-Credential
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)"}'
$nsgParams = @{
    ResourceGroupName = "test-rg"
    Name = "nsg-nva"
    Location = "eastus2"
}
New-AzNetworkSecurityGroup @nsgParams
$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
$routeTableParams = @{
    ResourceGroupName = "test-rg"
    Name = "route-table-nat-hub"
    Location = "eastus2"
}
New-AzRouteTable @routeTableParams
$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
$nsgParams = @{
    ResourceGroupName = "test-rg"
    Name = "nsg-spoke-2"
    Location = "westus2"
}
New-AzNetworkSecurityGroup @nsgParams
$vmParams = @{
    VM = $vmConfig
    ResourceGroupName = "test-rg"
    Location = "westus2"
    }
New-AzVM @vmParams
az vm create \
    --resource-group test-rg \
    --name vm-spoke-2 \
    --image Win2022Datacenter \
    --size Standard_DS2_v2 \
    --admin-username azureuser \
    --nics nic-2
$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
$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 = @{
    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
$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
# 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
$routeTableParams = @{
    ResourceGroupName = "test-rg"
    Name = "route-table-nat-spoke-1"
    Location = "southcentralus"
}
New-AzRouteTable @routeTableParams
$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"
}
$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
$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
$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
# 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
$routeTableParams = @{
    ResourceGroupName = "test-rg"
    Name = "route-table-nat-spoke-2"
    Location = "westus2"
}
New-AzRouteTable @routeTableParams
$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
    # 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-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
$rgParams = @{
    Name = "test-rg"
    Force = $true
}
Remove-AzResourceGroup @rgParams