How to Use AzCopy

A manufacturing company I worked with backed up its file server by dragging folders into a browser window. It worked for the first 20 GB. Then a 400 GB engineering share timed out three nights in a row, nobody knew which files had made it, and the person who ran the job kept a SAS token in a shared spreadsheet.

We replaced the whole routine with a single command-line tool and a scheduled script. Learning how to use AzCopy took the team about an hour, and the nightly job has run without drama since. AzCopy is a free Microsoft command-line utility that moves data to, from, and between Azure storage accounts.

This guide shows you how to install AzCopy, sign in safely, upload, download, sync, and automate transfers. You will also learn the permissions, performance settings, and troubleshooting steps that keep transfers fast, cheap, and secure.

What AzCopy Is and When to Use It

AzCopy v10 is the currently supported version. It runs on supported versions of Windows, Linux, and macOS. It can copy data from a local machine to Azure, from Azure back to a local machine, and from one storage account to another. It works with Azure Blob Storage and Azure Files, and with Data Lake Storage accounts.

Choose AzCopy when you want a scriptable, resumable, high-speed transfer. A few cases where another tool fits better:

  • Occasional manual uploads: Azure Storage Explorer gives you a graphical interface. It uses AzCopy under the hood for its transfers.
  • Large migrations: Microsoft recommends Azure Storage Mover for high-scale migrations over 1 TB. See the comparison of Azure Storage Mover vs. AzCopy and the overview of Azure Storage Mover.
  • Offline bulk transfer: When your internet link is too slow, a physical device such as Azure Data Box can be faster.

AzCopy does not support transfers where the source or destination is changing while the copy runs. Schedule jobs when the data is quiet, or copy from a snapshot.

Pro Tip: In my experience, teams pick AzCopy for the speed and keep it for the scripting. Once a transfer is a text file you can review, you can put it in source control and audit it.

Install AzCopy and Prepare Your Storage

Linux users can install AzCopy with a package manager. On other systems, you download a portable binary and unzip it. On Windows, many admins use winget:

winget install Microsoft.Azure.AZCopy.10
azcopy --version

The first command installs AzCopy v10, and the second prints the installed version. If you downloaded the zip instead, add its folder to your system path so you can type azcopy from any directory. For a full walkthrough, see the guide to install AzCopy.

Now create a lab environment. A resource group is a logical container that groups related Azure resources. See how to create a resource group in Azure if you want the portal steps.

az group create \
--name rg-azcopy-lab \
--location eastus \
--tags owner=it-team purpose=azcopy-demo

This creates rg-azcopy-lab in East US. The tags record the owner and purpose, so cost reviews are easier later. Read more about Azure tags.

az storage account create \
--name <storage-account-name> \
--resource-group rg-azcopy-lab \
--location eastus \
--sku Standard_LRS \
--kind StorageV2 \
--allow-blob-public-access false \
--min-tls-version TLS1_2

This creates a general-purpose storage account. --allow-blob-public-access false blocks anonymous access, and --min-tls-version TLS1_2 rejects older encryption. Standard_LRS keeps three copies in one datacenter, which is fine for a lab but weak for important data. See the walkthrough to create Azure Blob Storage for more options.

az storage container create \
--name backups \
--account-name <storage-account-name> \
--auth-mode login

This creates a container named backups. The --auth-mode login option uses your Microsoft Entra ID sign-in instead of an account key.

Pro Tip: I always create a separate container per workload, such as backups and exports. It lets me scope permissions and lifecycle rules to each job.

Authorize AzCopy the Safe Way

Being the owner of a storage account does not give you data permissions automatically. You must authorize AzCopy with either Microsoft Entra ID or a shared access signature (SAS) token.

Option 1: Microsoft Entra ID (Recommended)

With Entra ID, you sign in once and AzCopy reuses the credential. You do not append a SAS token to every command. Your identity needs a data role on the storage account:

  • Downloads need Storage Blob Data Reader.
  • Uploads need Storage Blob Data Contributor or Storage Blob Data Owner.

Role assignments can take up to five minutes to propagate. Learn the basics of Azure RBAC, which grants permissions through roles instead of broad admin rights.

az role assignment create \
--assignee <entra-group-object-id> \
--role "Storage Blob Data Contributor" \
--scope /subscriptions/<subscription-id>/resourceGroups/rg-azcopy-lab/providers/Microsoft.Storage/storageAccounts/<storage-account-name>

This gives an Entra group upload and download rights, scoped to a single storage account. Use groups so you can add and remove people without editing role assignments.

Then sign in:

azcopy login --tenant-id "<tenant-id>"
azcopy login status

azcopy login opens a browser sign-in and stores an encrypted token using your operating system’s secret store. If your Linux system has no keyring, the command cannot save the token. The --tenant-id option helps when your account belongs to more than one directory. azcopy login status confirms who you are signed in as.

Already signed in with Azure CLI? AzCopy can reuse that session. Set AZCOPY_AUTO_LOGIN_TYPE=AZCLI and AZCOPY_TENANT_ID.

Option 2: SAS Token (Short Jobs Only)

A SAS token is a signed string you append to the storage URL. It works, but it expires, is hard to rotate, and grants direct access if it leaks. Follow the guide to generate a SAS token for Azure Storage if you need one, and give it the shortest expiry and fewest permissions possible. Never paste SAS tokens or storage account keys into scripts, spreadsheets, or chat.

Pro Tip: I once found a never-expiring SAS URL in a team wiki. We rotated the storage key to kill it, and three production jobs broke at once. That is why I now start every project with Entra ID and role assignments.

How to Use AzCopy: Core Commands

The general format is azcopy [command] [arguments] --[flag-name]=[flag-value]. Quote your paths. Use single quotes in all shells except cmd.exe, where you should use double quotes.

Upload Files and Folders

azcopy copy '/data/engineering' 'https://<storage-account-name>.blob.core.windows.net/backups' --recursive

This uploads the engineering folder and everything in it to the backups container. --recursive includes subfolders. Without it, AzCopy copies only files at the top level.

To upload only a folder’s contents without the folder itself, use a wildcard:

azcopy copy '/data/engineering/*' 'https://<storage-account-name>.blob.core.windows.net/backups/engineering' --recursive

For a basic portal and code-based comparison, see how to upload and download files in Azure Blob Storage.

Download Files and Folders

azcopy copy 'https://<storage-account-name>.blob.core.windows.net/backups/engineering' '/restore' --recursive

This downloads the folder to a local directory called /restore. For single files, see how to download a file from Azure Blob Storage.

Copy Between Storage Accounts

azcopy copy 'https://<source-account>.blob.core.windows.net/backups' 'https://<destination-account>.blob.core.windows.net/backups-copy' --recursive

This is a server-to-server copy. Data moves directly between storage servers, so it does not pass through your computer. You can raise AZCOPY_CONCURRENCY_VALUE above 1000 for these jobs because your machine does little of the work.

Filter What You Copy

azcopy copy '/data/reports' 'https://<storage-account-name>.blob.core.windows.net/backups/reports' --recursive --include-pattern '*.pdf;*.xlsx'

--include-pattern copies only matching file names. --exclude-pattern skips them. These options match file names, not paths. To limit by folder, use --include-path. To copy files changed after a certain time, use --include-after with an ISO 8601 dat