Once we run command "Invoke-AzVMRunCommand" to execute a PS script on a remote VM, it always succeeds even it actually fails. I know remote VM has the log file there:
"C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.3\Status"
The problem:
But how to retrieve the error on a local powershell, try-catch etc. does not show it. What is a proper error handling using "Invoke-AzVMRunCommand", ideally getting results in .txt, something like:
| Out-File -Filepath xxx.txt
thank you.
As this is one of the top results I got when looking for this question, I thought I would add some extra information on how to get the output of jobs when using the -AsJob parameter with Invoke-AzVMRunCommand (often used for parallelism or status tracking.)
When you use -AsJob with Invoke-AzVMRunCommand, it creates a PowerShell job object to track the status of the task. You can then use Get-Job to retrieve the job information. However, the 'output' of the task does not appear in those results. You need to pass the job's object over to the Receive-Job cmdlet to get the output information. This cmdlet returns more information and has a 'Values' property which contains at least two (by my observation) items. The index of [0] which contains the standard output stream message, and the index of [1] which contains the standard error output stream message.
So all together, it would look something like this:
$VM = Get-AzVM -Name 'SomeVM'
Invoke-AzVMRunCommand -AsJob -VM $VM -CommandId 'RunPowerShellScript' -ScriptPath ".\MyScript.ps1"
#Use whatever method you want for waiting - a loop to check the job status or a delay (when using -AsJob, Invoke-AzRunCommand is asynchronous)
#Recevives the standard output stream for all jobs
(Get-Job -IncludeChildJob | Receive-Job -Keep).Value[0].Message
#Recevives the standard error stream for all jobs
(Get-Job -IncludeChildJob | Receive-Job -Keep).Value[1].Message
You could specify the job name or ID if you want a particular job.
Note that once you perform 'Receive-Job' on a job object, its results are cleared from memory so store them in a variable if you wish to re-use them.
Also note that 'Invoke-AzVMRunCommand' works similarly to 'Invoke-Command' - however with Invoke-Command, the 'Output' property does contain some of the output information from the task. You can use Receive-Job to get the individual output streams as well.
Edit: the behaviour seems odd but if you run Receive-Job even once for a specific job it seems to clear the results for all jobs. I have added the -Keep switch in in the example for this.