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
⚠️
powershell_heavy
⚠️
windows_tools
⚠️
missing_linux_example
Summary:
The documentation exhibits a Windows bias in several ways: it consistently refers to 'Windows file servers' as the only supported on-premises server type for Azure File Sync, provides PowerShell examples and output before or instead of cross-platform alternatives, and uses Windows-centric terminology and tools (e.g., PowerShell cmdlets, Windows DNS output). While Azure CLI and Bash examples are included for some tasks, certain operations (such as disabling the Storage Sync Service public endpoint) are only possible via PowerShell, with the documentation explicitly stating that Azure CLI does not support the operation. There is also a lack of Linux-specific guidance or examples for on-premises scenarios, and output samples are often shown only for Windows environments.
Recommendations:
- Clarify in the introduction that Azure File Sync currently only supports Windows file servers, but provide explicit guidance for Linux users seeking similar functionality or alternatives.
- Where PowerShell is used, always provide equivalent Azure CLI/Bash examples and outputs, or clearly state when a feature is not available cross-platform.
- When showing command output (e.g., nslookup), include both Windows and Linux/macOS output formats to help users on all platforms.
- If certain features are Windows-only (such as the File Sync agent), make this explicit and suggest alternative Azure Files access patterns for Linux environments.
- Consider providing a table summarizing which operations are supported on which platforms (Windows, Linux, macOS, Portal, PowerShell, CLI) for transparency.
- Where possible, advocate for parity in Azure CLI support for operations currently limited to PowerShell, and link to relevant Azure feedback channels.
Create pull request
Flagged Code Snippets
# Disable private endpoint network policies
$subnet.PrivateEndpointNetworkPolicies = "Disabled"
$virtualNetwork = $virtualNetwork | `
Set-AzVirtualNetwork -ErrorAction Stop
# Create a private link service connection to the storage account.
$privateEndpointConnection = New-AzPrivateLinkServiceConnection `
-Name "$storageSyncServiceName-Connection" `
-PrivateLinkServiceId $storageSyncService.ResourceId `
-GroupId "Afs" `
-ErrorAction Stop
# Create a new private endpoint.
$privateEndpoint = New-AzPrivateEndpoint `
-ResourceGroupName $storageSyncServiceResourceGroupName `
-Name "$storageSyncServiceName-PrivateEndpoint" `
-Location $virtualNetwork.Location `
-Subnet $subnet `
-PrivateLinkServiceConnection $privateEndpointConnection `
-ErrorAction Stop
# Get the desired Storage Sync Service suffix (afs.azure.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
$azureEnvironment = Get-AzContext | `
Select-Object -ExpandProperty Environment | `
Select-Object -ExpandProperty Name
switch($azureEnvironment) {
"AzureCloud" {
$storageSyncSuffix = "afs.azure.net"
}
"AzureUSGovernment" {
$storageSyncSuffix = "afs.azure.us"
}
"AzureChinaCloud" {
$storageSyncSuffix = "afs.azure.cn"
}
default {
Write-Error
-Message "The Azure environment $_ is not currently supported by Azure File Sync." `
-ErrorAction Stop
}
}
# For public cloud, this will generate the following DNS suffix:
# privatelink.afs.azure.net
$dnsZoneName = "privatelink.$storageSyncSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
$dnsZone = Get-AzPrivateDnsZone | `
Where-Object { $_.Name -eq $dnsZoneName } | `
Where-Object {
$privateDnsLink = Get-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $_.ResourceGroupName `
-ZoneName $_.Name `
-ErrorAction SilentlyContinue
$privateDnsLink.VirtualNetworkId -eq $virtualNetwork.Id
}
if ($null -eq $dnsZone) {
# No matching DNS zone attached to virtual network, so create new one.
$dnsZone = New-AzPrivateDnsZone `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $dnsZoneName `
-ErrorAction Stop
$privateDnsLink = New-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $virtualNetworkResourceGroupName `
-ZoneName $dnsZoneName `
-Name "$virtualNetworkName-DnsLink" `
-VirtualNetworkId $virtualNetwork.Id `
-ErrorAction Stop
}
$privateEndpointIpFqdnMappings = $privateEndpoint | `
Select-Object -ExpandProperty NetworkInterfaces | `
Select-Object -ExpandProperty Id | `
ForEach-Object { Get-AzNetworkInterface -ResourceId $_ } | `
Select-Object -ExpandProperty IpConfigurations | `
ForEach-Object {
$privateIpAddress = $_.PrivateIpAddress;
$_ | `
Select-Object -ExpandProperty PrivateLinkConnectionProperties | `
Select-Object -ExpandProperty Fqdns | `
Select-Object `
@{
Name = "PrivateIpAddress";
Expression = { $privateIpAddress }
}, `
@{
Name = "FQDN";
Expression = { $_ }
}
}
foreach($ipFqdn in $privateEndpointIpFqdnMappings) {
$privateDnsRecordConfig = New-AzPrivateDnsRecordConfig `
-IPv4Address $ipFqdn.PrivateIpAddress
$dnsEntry = $ipFqdn.FQDN.Substring(0,
$ipFqdn.FQDN.IndexOf(".", $ipFqdn.FQDN.IndexOf(".") + 1))
New-AzPrivateDnsRecordSet `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $dnsEntry `
-RecordType A `
-ZoneName $dnsZoneName `
-Ttl 600 `
-PrivateDnsRecords $privateDnsRecordConfig `
-ErrorAction Stop | `
Out-Null
}
$storageAccountHostName = [System.Uri]::new($storageAccount.PrimaryEndpoints.file) | `
Select-Object -ExpandProperty Host
Resolve-DnsName -Name $storageAccountHostName
Name Type TTL Section NameHost
---- ---- --- ------- --------
storageaccount.file.core.windows CNAME 60 Answer storageaccount.privatelink.file.core.windows.net
.net
Name : storageaccount.privatelink.file.core.windows.net
QueryType : A
TTL : 600
Section : Answer
IP4Address : 192.168.0.5
$storageSyncServiceResourceGroupName = "<storage-sync-service-resource-group>"
$storageSyncServiceName = "<storage-sync-service>"
Set-AzStorageSyncService `
-ResourceGroupName $storageSyncServiceResourceGroupName `
-Name $storageSyncServiceName `
-IncomingTrafficPolicy AllowVirtualNetworksOnly
$privateEndpointResourceGroupName = "<your-private-endpoint-resource-group>"
$privateEndpointName = "<your-private-endpoint-name>"
Get-AzPrivateEndpoint `
-ResourceGroupName $privateEndpointResourceGroupName `
-Name $privateEndpointName `
-ErrorAction Stop | `
Select-Object -ExpandProperty NetworkInterfaces | `
Select-Object -ExpandProperty Id | `
ForEach-Object { Get-AzNetworkInterface -ResourceId $_ } | `
Select-Object -ExpandProperty IpConfigurations | `
Select-Object -ExpandProperty PrivateLinkConnectionProperties | `
Select-Object -ExpandProperty Fqdns | `
ForEach-Object { Resolve-DnsName -Name $_ } | `
Format-List
$storageSyncServiceResourceGroupName = "<storage-sync-service-resource-group>"
$storageSyncServiceName = "<storage-sync-service>"
$storageSyncService = Get-AzStorageSyncService `
-ResourceGroupName $storageSyncServiceResourceGroupName `
-Name $storageSyncServiceName `
-ErrorAction SilentlyContinue
if ($null -eq $storageSyncService) {
$errorMessage = "Storage Sync Service $storageSyncServiceName not found "
$errorMessage += "in resource group $storageSyncServiceResourceGroupName."
Write-Error -Message $errorMessage -ErrorAction Stop
}