I was able to figure out how to run the Invoke-AzVMRunCommand to run a PowerShell script on a Windows VM to run azcopy.exe to download a file from blob storage to an azure windows VM, here is that question answered.
I've modified the function app to handle copying files to a Linux VM, here is my new Powershell Function app:
# Input bindings are passed in via param block.
param($QueueItem, $TriggerMetadata)
try {
$FileName = $QueueItem['FileName']
$PDB = $QueueItem['PDB']
$EmailAddress = $QueueItem['EmailAddress']
if ($PDB.Contains("LINUX")) {
$baseFolder = '/u01'
$vmName = 'MY_LINUX_VM_NAME'
$commandID = 'RunShellScript'
}
else {
$baseFolder = 'F:'
$vmName = 'MY_WINDOWS_VM_NAME'
$commandID = 'RunPowerShellScript'
}
$CopyToDumpScript = "$baseFolder/azcopy/CopyToDump.ps1"
$StorageAccount = 'https://STORAGEACCOUNT.blob.core.windows.net/CONTAINER/'
$BlobURI = "{0}{1}" -f $StorageAccount, $FileName
# Append arguments directly to the script path for positional argument passing
$script = "$CopyToDumpScript $PDB $FileName $BlobURI $EmailAddress"
# Create script file with arguments
Out-File -FilePath "ScriptToRun.ps1" -InputObject $script
$InvokeRunCmdOutput = Invoke-AzVMRunCommand `
-ResourceGroupName 'MY_RESOURCE_GROUP' `
-Name "$vmName" `
-CommandId "$commandID" `
-ScriptPath 'ScriptToRun.ps1'
$Output = $InvokeRunCmdOutput.Value[0].Message
Write-Host "InvokeCommandOutput = $Output"
Remove-Item -Path 'ScriptToRun.ps1'
# Queue to notify that file has been copied to VM
#Push-OutputBinding -Name Msg -Value $QueueItem
}
catch {
Write-Host $_.Exception.Message
}
Here is the script on the Linux VM "/u01/azcopy/CopyToDump.ps1"
#!/usr/bin/pwsh
param(
[string]$PDB,
[string]$FileName,
[string]$BlobURI,
[string]$EmailAddress
)
$SAS = 'SAS TOKEN - TRIED WITH AND WITHOUT'
$logFile = "/u01/azcopy/log.txt"
$downloadFlder = "/u01/azcopy/downloads"
$azcopy = "/u01/azcopy/azcopy"
Function Write-Log {
param(
[Parameter(Mandatory = $true)][string] $message,
[Parameter(Mandatory = $false)]
[ValidateSet("INFO", "WARN", "ERROR")]
[string] $level = "INFO"
)
$timestamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
Add-Content -Path $logFile -Value "$timestamp [$level] - $message"
}
$DownloadFile = "$downloadFlder/$FileName"
$Destination = "$dumpFolder/$folder"
try
{
Write-Log -level INFO -message "Downloading: $BlobURI"
# read somewhere that Linux requires single quotes around args
$blogArg = "'{0}?{1}'" -f $BlobURI, $SAS # tried this with and without SAS
$fileArg = "'{0}'" -f $DownloadFile
Write-Log -level INFO -message "Running: $azcopy copy $blogArg $fileArg --overwrite=ifsourcenewer --check-md5=FailIfDifferent --recursive"
& $azcopy copy $blogArg $fileArg --overwrite=ifsourcenewer --check-md5=FailIfDifferent --recursive
Write-Log -level INFO -message "Done!"
}
catch
{
Write-Log -level ERROR -message "Error running script"
Write-Log -level ERROR -message "$_.Message"
exit -1
}
I cannot seem to get any output from the azcopy cmd, I just get a return success in the function app and I see the messages in the log "Running:..." and "Done!" like a second after, which tends to mean this does nothing. I would expect it to throw some sort of error or warning but nothing
If I copy the command from the logfile verbatim - and run it on the cmdline, it runs with no issue. I'm assuming this is most likely due to user permissions, but wouldn't the azcopy throw an error or warning of some sort? Any idea as to what is going on?
Thanks