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
powershell_heavy
missing_linux_example
windows_tools
windows_first
Summary
The documentation demonstrates a strong Windows bias by exclusively providing a PowerShell script for automating billing role migration, instructing users to select PowerShell in Azure Cloud Shell, and omitting any Bash or cross-platform scripting alternatives. The instructions and screenshots prioritize PowerShell usage, and there is no mention of how to accomplish the task using Linux-native tools or shell environments.
Recommendations
  • Provide equivalent Bash (or Azure CLI) script examples for Linux and macOS users.
  • Update instructions to include both PowerShell and Bash options in Azure Cloud Shell, with guidance for each.
  • Clarify that the process can be completed on any platform, and specify any platform-specific prerequisites or differences.
  • Include screenshots and step-by-step instructions for both PowerShell and Bash workflows.
  • Reference cross-platform tools (e.g., Azure CLI, REST API via curl/jq) where possible, not just Windows-centric tools.
GitHub Create Pull Request

Scan History

Date Scan Status Result
2026-01-13 06:17 #107 completed Biased Biased
2026-01-12 00:00 #99 completed Biased Biased
2026-01-11 06:20 #98 completed Biased Biased
2026-01-10 00:00 #92 completed Biased Biased
2026-01-06 22:28 #78 completed Clean Clean
2025-12-29 18:00 #48 cancelled Biased Biased
2025-12-16 00:00 #8 completed Clean Clean
2025-12-15 00:00 #7 completed Clean Clean
2025-12-14 05:05 #6 completed Clean Clean

Flagged Code Snippets

## Define source target mapping for
##	1. Tenant
##	2. Billing Account
##	3. Billing Profile
##	4. Invoice Sections
##(source) MCA-E details
$tenantId = "" 
$billingAccount=""
$billingProfile = ""
##(destination) MCA-E details
$targetBillingProfile = ""
$targetTenantId = ""
$targetbillingAccount=""
## Invoice section mapping in hash table
$hash = @{
"" = ""; #invoice section 1
"" = ""; #invoice section 2
}
## Connect to Azure account using device authentication using tenantId
Connect-AzAccount -UseDeviceAuthentication -TenantId $tenantId
Set-AzContext -TenantId $tenantId
## Acquire access token for the current user
$var = Get-AzAccessToken
$auth = 'Bearer ' + $var.Token
#### Get Billing Account Role Assignments from source MCA-E
#define parameters for REST API call
$params = @{
    Uri         = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/"+ $billingAccount +"/billingRoleAssignments?api-version=2019-10-01-preview"
    Headers     = @{ 'Authorization' = $auth }
    Method      = 'GET'
    ContentType = 'application/json'
}
#### Call API with parameters defined above
$ret = Invoke-RestMethod @params 
####Initialize array lists 
$ArrayListBARoles = [System.Collections.Generic.List[string]]::new();
$ArrayListBPRoles = [System.Collections.Generic.List[string]]::new();
$ArrayListISRoles = [System.Collections.Generic.List[string]]::new();
#### Add each billing account role and principal id to array list 
#### Push down the billing account role assignments to billing profile role assignments (replacing 5 series with 4 series)
foreach($j in $ret.value){                                                     
	$BANameArrayArray= $j.name -replace "500000", "500000" #-split '_'                                           
	foreach($i in $BANameArrayArray){
	 $ArrayListBARoles.Add($i)
	 }
 }
#### Get Billing Role assignments for billing profile
$paramsBPRoleAssignments = @{
	Uri         = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/"+$billingAccount +"/billingProfiles/" +$billingProfile +"/billingRoleAssignments?api-version=2019-10-01-preview"
    Headers     = @{ 'Authorization' = $auth }
    Method      = 'GET'
    ContentType = 'application/json'
		}
$retBPRoles = Invoke-RestMethod @paramsBPRoleAssignments 
####add each role to arraylist
foreach($k in $retBPRoles.value){                                                     
	$BPNameArrayArray= $k.name #-split '_'                                           
	foreach($l in $BPNameArrayArray){
	$ArrayListBPRoles.Add($l)
	}
}
#### Get Invoice sections for billing profile
$invoiceSections = Get-AzInvoiceSection -BillingAccountName $billingAccount -BillingProfile $billingProfile
for ($ii=0; $ii -lt $ArrayListBARoles.count;  $ii=$ii+1){ 
	$paramsBARoleCreation = @{
		Uri = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/"+$targetbillingAccount+"/createBillingRoleAssignment?api-version=2020-12-15-privatepreview"
		Headers     = @{ 'Authorization' = $auth }
		Method      = 'POST'
		ContentType = 'application/json'
		}
	$BodyBARoleCreation = @{
		principalTenantId = $tenantId
		roleDefinitionId = "/providers/Microsoft.Billing/billingAccounts/" +$targetbillingAccount +"/" +($ArrayListBARoles[$ii] -SPLIT '_')[0]
		principalId=($ArrayListBARoles[$ii] -SPLIT '_')[1]
		}
	$retBARoles = Invoke-RestMethod @paramsBARoleCreation -body @($BodyBARoleCreation | ConvertTo-Json)
}
#BILLING PROFILE	
for ($ii=0; $ii -lt $ArrayListBPRoles.count;  $ii=$ii+1){
	$paramsBPRoleCreation = @{
		Uri = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/" +$targetbillingAccount +"/billingProfiles/"+ $targetBillingProfile +"/createBillingRoleAssignment?api-version=2020-12-15-privatepreview"
		Headers     = @{ 'Authorization' = $auth }
		Method      = 'POST'
		ContentType = 'application/json'
	}
	$BodyBPRoleCreation = @{
		principalTenantId = $tenantId
		roleDefinitionId = "/providers/Microsoft.Billing/billingAccounts/" +$targetbillingAccount +"/billingProfiles/"+ $targetBillingProfile +"/" +($ArrayListBPRoles[$ii] -SPLIT '_')[0]
		principalId=($ArrayListBPRoles[$ii] -SPLIT '_')[1]
    }
	$retBPRoles = Invoke-RestMethod @paramsBPRoleCreation -body @($BodyBPRoleCreation | ConvertTo-Json)
}
#INVOICE SECTIONS
$targetinvoiceSection=""
#Get Roles for each invoice section
foreach ($m in $invoiceSections){
	if ($hash.ContainsKey($m.Name)){
		$targetinvoiceSection=$hash[$m.Name]
		'targetinvoiceSection'
		$targetinvoiceSection
		
	$paramsISRoleAssignments = @{
		Uri = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/" +$billingAccount +"/billingProfiles/" + $billingProfile +"/invoiceSections/" +$m.Name+ "/billingRoleAssignments?api-version=2019-10-01-preview"			
		Headers     = @{ 'Authorization' = $auth }
		Method      = 'GET'
		ContentType = 'application/json'
	}
	$retISRoles = Invoke-RestMethod @paramsISRoleAssignments 
	$ISNameArrayArray=$null
	$ArrayListISRoles = [System.Collections.Generic.List[string]]::new();
	foreach($n in $retISRoles.value){  
		$ISNameArrayArray= $n.name #-split '_'                                           
			foreach($o in $ISNameArrayArray){
				$ArrayListISRoles.Add($o)
			}
	}
		for ($ii=0; $ii -lt $ArrayListISRoles.count;  $ii=$ii+1){
			$paramsISRoleCreation = @{
				Uri = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/" +$targetbillingAccount+ "/billingProfiles/"+ $targetBillingProfile +"/invoiceSections/"+ $targetinvoiceSection +"/createBillingRoleAssignment?api-version=2020-12-15-privatepreview"
				Headers     = @{ 'Authorization' = $auth }
				Method      = 'POST'
				ContentType = 'application/json'
			}
			$BodyISRoleCreation = @{
				principalTenantId = $tenantId
				roleDefinitionId = "/providers/Microsoft.Billing/billingAccounts/" +$targetbillingAccount +"/billingProfiles/"+ $targetBillingProfile +"/invoiceSections/"+ $targetinvoiceSection+ "/" +($ArrayListISRoles[$ii] -SPLIT '_')[0]
				#userEmailAddress = ($graph.UserPrincipalName -Replace '_', '@' -split '#EXT#@' )[0]
				principalId=($ArrayListISRoles[$ii] -SPLIT '_')[1]
			}
			$resISRolesCreation= Invoke-RestMethod @paramsISRoleCreation -body @($BodyISRoleCreation | ConvertTo-Json)
		}
		}
}