Reputation: 157
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.
Upvotes: 1
Views: 3892
Reputation: 16
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.
Upvotes: 0
Reputation: 157
Eventually after long testing, I end up with this solution, which throws an error from remote script execution and logs it in .txt file:
$result = Invoke-AzVMRunCommand -ErrorAction Stop -ResourceGroupName "MyRg" -Name "MyVM" -CommandId 'RunPowerShellScript' -ScriptPath MyScript.ps1
Remove-Item -path script.ps1
if ($result.value.Message -like '*error*')
{
Write-Output "Failed. An error occurred: `n $($result.value.Message)" | Out-File -Filepath C:\OutputLog.txt -Append
throw $($result.value.Message)
}
else
{
Write-Output "Success" | Out-File -Filepath C:\OutputLog.txt -Append
}
Upvotes: 3