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:
⚠️ powershell_heavy
⚠️ missing_linux_example
Summary:
The documentation provides only Azure PowerShell script examples for managing Mobility service automatic updates, with no equivalent CLI or Linux-native instructions. All automation and scripting guidance is presented in PowerShell, which is primarily associated with Windows environments, and there are no Bash, Azure CLI, or cross-platform examples. This may disadvantage users managing Azure VMs from Linux or macOS systems.
Recommendations:
  • Provide equivalent Azure CLI (az) commands for all PowerShell script examples, as Azure CLI is cross-platform and widely used on Linux and macOS.
  • Include Bash script examples for automating tasks where appropriate, or at least reference how to perform the same actions in Bash.
  • Explicitly state that the PowerShell script can be run from Azure Cloud Shell, which is available in-browser and supports both Bash and PowerShell, to clarify cross-platform options.
  • Add a section or note addressing Linux/macOS users, outlining how they can perform the same tasks without relying on Windows-specific tools.
  • Where possible, use REST API examples or reference the REST API documentation for advanced automation scenarios, as these are platform-agnostic.
GitHub Create pull request

Scan History

Date Scan ID Status Bias Status
2025-09-16 00:00 #113 completed ✅ Clean
2025-09-15 00:00 #112 completed ✅ Clean
2025-09-14 00:00 #111 completed ✅ Clean
2025-09-13 00:00 #110 completed ✅ Clean
2025-09-12 00:00 #109 completed ✅ Clean
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

Flagged Code Snippets

param( [Parameter(Mandatory=$true)] [String] $VaultResourceId, [Parameter(Mandatory=$true)] [ValidateSet("Enabled",'Disabled')] [Alias("Enabled or Disabled")] [String] $AutoUpdateAction, [Parameter(Mandatory=$false)] [String] $AutomationAccountArmId ) $SiteRecoveryRunbookName = "Modify-AutoUpdateForVaultForPartner" $TaskId = [guid]::NewGuid().ToString() $SubscriptionId = "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e" $AsrApiVersion = "2021-12-01" $ArmEndPoint = "https://management.azure.com" $AadAuthority = "https://login.windows.net/" $AadAudience = "https://management.core.windows.net/" $AzureEnvironment = "AzureCloud" $Timeout = "160" $AuthenticationType = "SystemAssignedIdentity" function Throw-TerminatingErrorMessage { Param ( [Parameter(Mandatory=$true)] [String] $Message ) throw ("Message: {0}, TaskId: {1}.") -f $Message, $TaskId } function Write-Tracing { Param ( [Parameter(Mandatory=$true)] [ValidateSet("Informational", "Warning", "ErrorLevel", "Succeeded", IgnoreCase = $true)] [String] $Level, [Parameter(Mandatory=$true)] [String] $Message, [Switch] $DisplayMessageToUser ) Write-Output $Message } function Write-InformationTracing { Param ( [Parameter(Mandatory=$true)] [String] $Message ) Write-Tracing -Message $Message -Level Informational -DisplayMessageToUser } function ValidateInput() { try { if(!$VaultResourceId.StartsWith("/subscriptions", [System.StringComparison]::OrdinalIgnoreCase)) { $ErrorMessage = "The vault resource id should start with /subscriptions." throw $ErrorMessage } $Tokens = $VaultResourceId.SubString(1).Split("/") if(!($Tokens.Count % 2 -eq 0)) { $ErrorMessage = ("Odd Number of tokens: {0}." -f $Tokens.Count) throw $ErrorMessage } if(!($Tokens.Count/2 -eq 4)) { $ErrorMessage = ("Invalid number of resource in vault ARM id expected:4, actual:{0}." -f ($Tokens.Count/2)) throw $ErrorMessage } if($AutoUpdateAction -ieq "Enabled" -and [string]::IsNullOrEmpty($AutomationAccountArmId)) { $ErrorMessage = ("The automation account ARM id should not be null or empty when AutoUpdateAction is enabled.") throw $ErrorMessage } } catch { $ErrorMessage = ("ValidateInput failed with [Exception: {0}]." -f $_.Exception) Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser Throw-TerminatingErrorMessage -Message $ErrorMessage } } function Initialize-SubscriptionId() { try { $Tokens = $VaultResourceId.SubString(1).Split("/") $Count = 0 $ArmResources = @{} while($Count -lt $Tokens.Count) { $ArmResources[$Tokens[$Count]] = $Tokens[$Count+1] $Count = $Count + 2 } return $ArmResources["subscriptions"] } catch { Write-Tracing -Level ErrorLevel -Message ("Initialize-SubscriptionId: failed with [Exception: {0}]." -f $_.Exception) -DisplayMessageToUser throw } } function Invoke-InternalRestMethod($Uri, $Headers, [ref]$Result) { $RetryCount = 0 $MaxRetry = 3 do { try { $ResultObject = Invoke-RestMethod -Uri $Uri -Headers $Headers ($Result.Value) += ($ResultObject) break } catch { Write-InformationTracing ("Retry Count: {0}, Exception: {1}." -f $RetryCount, $_.Exception) $RetryCount++ if(!($RetryCount -le $MaxRetry)) { throw } Start-Sleep -Milliseconds 2000 } }while($true) } function Invoke-InternalWebRequest($Uri, $Headers, $Method, $Body, $ContentType, [ref]$Result) { $RetryCount = 0 $MaxRetry = 3 do { try { $ResultObject = Invoke-WebRequest -Uri $UpdateUrl -Headers $Header -Method 'PATCH' ` -Body $InputJson -ContentType "application/json" -UseBasicParsing ($Result.Value) += ($ResultObject) break } catch { Write-InformationTracing ("Retry Count: {0}, Exception: {1}." -f $RetryCount, $_.Exception) $RetryCount++ if(!($RetryCount -le $MaxRetry)) { throw } Start-Sleep -Milliseconds 2000 } }while($true) } function Get-Header([ref]$Header, $AadAudience){ try { $Header.Value['Content-Type'] = 'application\json' Write-InformationTracing ("The Authentication Type is system Assigned Identity based.") $endpoint = $env:IDENTITY_ENDPOINT $endpoint $Headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $Headers.Add("X-IDENTITY-HEADER", $env:IDENTITY_HEADER) $Headers.Add("Metadata", "True") $authenticationResult = Invoke-RestMethod -Method Get -Headers $Headers -Uri ($endpoint +'?resource=' +$AadAudience) $accessToken = $authenticationResult.access_token $Header.Value['Authorization'] = "Bearer " + $accessToken $Header.Value["x-ms-client-request-id"] = $TaskId + "/" + (New-Guid).ToString() + "-" + (Get-Date).ToString("u") } catch { $ErrorMessage = ("Get-BearerToken: failed with [Exception: {0}]." -f $_.Exception) Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser Throw-TerminatingErrorMessage -Message $ErrorMessage } } function Get-ProtectionContainerToBeModified([ref] $ContainerMappingList) { try { Write-InformationTracing ("Get protection container mappings : {0}." -f $VaultResourceId) $ContainerMappingListUrl = $ArmEndPoint + $VaultResourceId + "/replicationProtectionContainerMappings" + "?api-version=" + $AsrApiVersion Write-InformationTracing ("Getting the bearer token and the header.") Get-Header ([ref]$Header) $AadAudience $Result = @() Invoke-InternalRestMethod -Uri $ContainerMappingListUrl -Headers $header -Result ([ref]$Result) $ContainerMappings = $Result[0] Write-InformationTracing ("Total retrieved container mappings: {0}." -f $ContainerMappings.Value.Count) foreach($Mapping in $ContainerMappings.Value) { if(($Mapping.properties.providerSpecificDetails -eq $null) -or ($Mapping.properties.providerSpecificDetails.instanceType -ine "A2A")) { Write-InformationTracing ("Mapping properties: {0}." -f ($Mapping.properties)) Write-InformationTracing ("Ignoring container mapping: {0} as the provider does not match." -f ($Mapping.Id)) continue; } if($Mapping.Properties.State -ine "Paired") { Write-InformationTracing ("Ignoring container mapping: {0} as the state is not paired." -f ($Mapping.Id)) continue; } Write-InformationTracing ("Provider specific details {0}." -f ($Mapping.properties.providerSpecificDetails)) $MappingAutoUpdateStatus = $Mapping.properties.providerSpecificDetails.agentAutoUpdateStatus $MappingAutomationAccountArmId = $Mapping.properties.providerSpecificDetails.automationAccountArmId $MappingHealthErrorCount = $Mapping.properties.HealthErrorDetails.Count if($AutoUpdateAction -ieq "Enabled" -and ($MappingAutoUpdateStatus -ieq "Enabled") -and ($MappingAutomationAccountArmId -ieq $AutomationAccountArmId) -and ($MappingHealthErrorCount -eq 0)) { Write-InformationTracing ("Provider specific details {0}." -f ($Mapping.properties)) Write-InformationTracing ("Ignoring container mapping: {0} as the auto update is already enabled and is healthy." -f ($Mapping.Id)) continue; } ($ContainerMappingList.Value).Add($Mapping.id) } } catch { $ErrorMessage = ("Get-ProtectionContainerToBeModified: failed with [Exception: {0}]." -f $_.Exception) Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser Throw-TerminatingErrorMessage -Message $ErrorMessage } } $OperationStartTime = Get-Date $ContainerMappingList = New-Object System.Collections.Generic.List[System.String] $JobsInProgressList = @() $JobsCompletedSuccessList = @() $JobsCompletedFailedList = @() $JobsFailedToStart = 0 $JobsTimedOut = 0 $Header = @{} $AzureRMProfile = Get-Module -ListAvailable -Name AzureRM.Profile | Select Name, Version, Path $AzureRmProfileModulePath = Split-Path -Parent $AzureRMProfile.Path Add-Type -Path (Join-Path $AzureRmProfileModulePath "Microsoft.IdentityModel.Clients.ActiveDirectory.dll") $Inputs = ("Tracing inputs VaultResourceId: {0}, Timeout: {1}, AutoUpdateAction: {2}, AutomationAccountArmId: {3}." -f $VaultResourceId, $Timeout, $AutoUpdateAction, $AutomationAccountArmId) Write-Tracing -Message $Inputs -Level Informational -DisplayMessageToUser $CloudConfig = ("Tracing cloud configuration ArmEndPoint: {0}, AadAuthority: {1}, AadAudience: {2}." -f $ArmEndPoint, $AadAuthority, $AadAudience) Write-Tracing -Message $CloudConfig -Level Informational -DisplayMessageToUser ValidateInput $SubscriptionId = Initialize-SubscriptionId Get-ProtectionContainerToBeModified ([ref]$ContainerMappingList) $Input = @{ "properties"= @{ "providerSpecificInput"= @{ "instanceType" = "A2A" "agentAutoUpdateStatus" = $AutoUpdateAction "automationAccountArmId" = $AutomationAccountArmId "automationAccountAuthenticationType" = $AuthenticationType } } } $InputJson = $Input | ConvertTo-Json if ($ContainerMappingList.Count -eq 0) { Write-Tracing -Level Succeeded -Message ("Exiting as there are no container mappings to be modified.") -DisplayMessageToUser exit } Write-InformationTracing ("Container mappings to be updated has been retrieved with count: {0}." -f $ContainerMappingList.Count) try { Write-InformationTracing ("Start the modify container mapping jobs.") ForEach($Mapping in $ContainerMappingList) { try { $UpdateUrl = $ArmEndPoint + $Mapping + "?api-version=" + $AsrApiVersion Get-Header ([ref]$Header) $AadAudience $Result = @() Invoke-InternalWebRequest -Uri $UpdateUrl -Headers $Header -Method 'PATCH' ` -Body $InputJson -ContentType "application/json" -Result ([ref]$Result) $Result = $Result[0] $JobAsyncUrl = $Result.Headers['Azure-AsyncOperation'] Write-InformationTracing ("The modify container mapping job invoked with async url: {0}." -f $JobAsyncUrl) $JobsInProgressList += $JobAsyncUrl; # Rate controlling the set calls to maximum 60 calls per minute. # ASR throttling for set calls is 200 in 1 minute. Start-Sleep -Milliseconds 1000 } catch{ Write-InformationTracing ("The modify container mappings job creation failed for: {0}." -f $Ru) Write-InformationTracing $_ $JobsFailedToStart++ } } Write-InformationTracing ("Total modify container mappings has been initiated: {0}." -f $JobsInProgressList.Count) } catch { $ErrorMessage = ("Modify container mapping jobs failed with [Exception: {0}]." -f $_.Exception) Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser Throw-TerminatingErrorMessage -Message $ErrorMessage } try { while($JobsInProgressList.Count -ne 0) { Sleep -Seconds 30 $JobsInProgressListInternal = @() ForEach($JobAsyncUrl in $JobsInProgressList) { try { Get-Header ([ref]$Header) $AadAudience $Result = Invoke-RestMethod -Uri $JobAsyncUrl -Headers $header $JobState = $Result.Status if($JobState -ieq "InProgress") { $JobsInProgressListInternal += $JobAsyncUrl } elseif($JobState -ieq "Succeeded" -or ` $JobState -ieq "PartiallySucceeded" -or ` $JobState -ieq "CompletedWithInformation") { Write-InformationTracing ("Jobs succeeded with state: {0}." -f $JobState) $JobsCompletedSuccessList += $JobAsyncUrl } else { Write-InformationTracing ("Jobs failed with state: {0}." -f $JobState) $JobsCompletedFailedList += $JobAsyncUrl } } catch { Write-InformationTracing ("The get job failed with: {0}. Ignoring the exception and retrying the next job." -f $_.Exception) # The job on which the tracking failed, will be considered in progress and tried again later. $JobsInProgressListInternal += $JobAsyncUrl } # Rate controlling the get calls to maximum 120 calls each minute. # ASR throttling for get calls is 10000 in 60 minutes. Start-Sleep -Milliseconds 500 } Write-InformationTracing ("Jobs remaining {0}." -f $JobsInProgressListInternal.Count) $CurrentTime = Get-Date if($CurrentTime -gt $OperationStartTime.AddMinutes($Timeout)) { Write-InformationTracing ("Tracing modify cloud pairing jobs has timed out.") $JobsTimedOut = $JobsInProgressListInternal.Count $JobsInProgressListInternal = @() } $JobsInProgressList = $JobsInProgressListInternal } } catch { $ErrorMessage = ("Tracking modify cloud pairing jobs failed with [Exception: {0}]." -f $_.Exception) Write-Tracing -Level ErrorLevel -Message $ErrorMessage -DisplayMessageToUser Throw-TerminatingErrorMessage -Message $ErrorMessage } Write-InformationTracing ("Tracking modify cloud pairing jobs completed.") Write-InformationTracing ("Modify cloud pairing jobs success: {0}." -f $JobsCompletedSuccessList.Count) Write-InformationTracing ("Modify cloud pairing jobs failed: {0}." -f $JobsCompletedFailedList.Count) Write-InformationTracing ("Modify cloud pairing jobs failed to start: {0}." -f $JobsFailedToStart) Write-InformationTracing ("Modify cloud pairing jobs timedout: {0}." -f $JobsTimedOut) if($JobsTimedOut -gt 0) { $ErrorMessage = "One or more modify cloud pairing jobs has timedout." Write-Tracing -Level ErrorLevel -Message ($ErrorMessage) Throw-TerminatingErrorMessage -Message $ErrorMessage } elseif($JobsCompletedSuccessList.Count -ne $ContainerMappingList.Count) { $ErrorMessage = "One or more modify cloud pairing jobs failed." Write-Tracing -Level ErrorLevel -Message ($ErrorMessage) Throw-TerminatingErrorMessage -Message $ErrorMessage } Write-Tracing -Level Succeeded -Message ("Modify cloud pairing completed.") -DisplayMessageToUser