Another solution is to use a Custom Extension Script.
Using a custom extension script allows you to copy file to the VM even if the VM does not have a public ip (private network). So you don't need to configure winRm or anything.
I've used custom extension scripts in the past for post-deployment like installing an app on a VM or a Scale Set. Basically you upload files to blob storage and the custom extension script will download these file on the VM.
I've created a test-container on my blob storage account and uploaded two files:
deploy.ps1: the script executed on the VM. test.txt: a text file with "Hello world from VM"
Here is the code of the deploy.ps1 file:
Param( [string] [Parameter(Mandatory=$true)] $filename, [string] [Parameter(Mandatory=$true)] $destinationPath ) # Getting the full path of the downloaded file $filePath = $PSScriptRoot + "\" + $filename Write-Host "Checking the destination folder..." -Verbose if(!(Test-Path $destinationPath -Verbose)){ Write-Host "Creating the destination folder..." -Verbose New-Item -ItemType directory -Path $destinationPath -Force -Verbose } Copy-Item $filePath -Destination $destinationPath -Force -Verbose
Here is the code to add a custom script extension to a virtual machine.
Login-AzureRMAccount $resourceGroupName = "resourcegroupname" $storageAccountName = "storageaccountname" $containerName = "test-container" $location = "Australia East" $vmName = "TestVM" $extensionName = "copy-file-to-vm" $filename = "test.txt" $deploymentScript = "deploy.ps1" $destintionPath = "C:\MyTempFolder\" $storageAccountKeys = (Get-AzureRmStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageAccountName).Value $storageAccountKey = $storageAccountKeys[0] Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $extensionName -Location $location -TypeHandlerVersion "1.9" -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ContainerName $containerName -FileName $deploymentScript, $filename -Run $deploymentScript -Argument "$filename $destintionPath" -ForceRerun "1"
You can remove the extension after the file has been copied:
Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $extensionName -Force
In my scenario, I have a logic app that is triggered every time a new file is added to a container. The logic app call a runbook (required an azure automation account) that add the custom script extension then delete it.