1

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.

2
  • You say the file is being written here: "C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.3\Status", and the error is in that log file, then why not just read it from there? Get-Content -Path 'UncToFilename', or are you saying you don't want to read the full file, just errors it spits out? You are not showing what your ErrorAction and /or Try/Catch looks like either and thus not enough info to work with. Commented Feb 14, 2020 at 21:30
  • regardless what ErrorAction and Try/Catch block is, if remote scripts fails inside, it does not throw an error on the machine it is called from. We run .ps1 script saved on many remote VMs locally every several hours, would very inefficient to run another script to read log file on remote machine plus needs additional filtering to read only the ones which has failed. And the worst is, the invoke script succeeds so we even do not know when the script fails. Commented Feb 15, 2020 at 13:02

2 Answers 2

3

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
} 
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.