How to determine if your Runcommand script failed

Joseph Calev

Today, we’re going to cover what can be a maddening issue in just determining whether your script failed.

Let’s start with a very simple operation. Open a Powershell window and run the following:

PS C:\> this is an error

this: The term 'this' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

This shouldn’t be rocket science here. It’s very clear that “this is an error” is, in fact, an error. So, with this universal fact determined, let’s run it on an Azure VM.

Set-AzVmRunCommand -ResourceGroupName $rg -VMName $vm -Location $loc -RunCommandName "MyRuncommand" -SourceScript "this is an error"

And now let’s see the result.

Get-AzVMRunCommand -ResourceGroupName $rg -VMName $vm -RunCommandName "MyRuncommand" -Expand "instanceView" | select-object *

AsyncExecution : False
ErrorBlobUri :
Id : {removed}
InstanceViewEndTime : 16.06.2023 22:55:11
InstanceViewError : this : The term 'this' is not recognized as the name of a cmdlet, function, script file, or operable program. Check
the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandHandlerWindows\2.0.5\Downloads\Script_MyRuncommand_0.ps1:1 char:1
+ this is an error
+ ~~~~
+ CategoryInfo : ObjectNotFound: (this:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

InstanceViewExecutionMessage :
InstanceViewExecutionState : Succeeded
InstanceViewExitCode : 0
InstanceViewOutput :
InstanceViewStartTime : 16.06.2023 22:55:08
InstanceViewStatuses :
Location : westus2
Name : MyRuncommand
OutputBlobUri :
Parameter :
ProtectedParameter :
ProvisioningState : Succeeded
RunAsPassword :
RunAsUser :
SourceCommandId :
SourceScript : this is an error
SourceScriptUri :
Tag : Microsoft.Azure.PowerShell.Cmdlets.Compute.Models.Api20210701.ResourceTags
TimeoutInSecond : 0
Type : Microsoft.Compute/virtualMachines/runCommands

Note that you need to pass in -expand “instanceView” to see the actual error. Without this, you’ll receive the following.

AsyncExecution : False
ErrorBlobUri :
Id : {removed}
InstanceViewEndTime :
InstanceViewError :
InstanceViewExecutionMessage :
InstanceViewExecutionState :
InstanceViewExitCode :
InstanceViewOutput :
InstanceViewStartTime :
InstanceViewStatuses :
Location : westus2
Name : MyRuncommand
OutputBlobUri :
Parameter :
ProtectedParameter :
ProvisioningState : Succeeded
RunAsPassword :
RunAsUser :
SourceCommandId :
SourceScript : this is an error
SourceScriptUri :
Tag : Microsoft.Azure.PowerShell.Cmdlets.Compute.Models.Api20210701.ResourceTags
TimeoutInSecond : 0
Type : Microsoft.Compute/virtualMachines/runCommands

This leads one to believe everything worked, when it didnt’t.

So, the first lesson of Runcommand error viewing is: always check the instanceView!

Of course, most of us are keen enough to not write scripts like this. Instead, we’re probably going to detect problems and throw, so let’s try that.

Set-AzVmRunCommand -ResourceGroupName $rg -VMName $vm -Location $loc -RunCommandName "Myruncommand" -SourceScript "throw 'blah'"

Get-AzVMRunCommand -ResourceGroupName $rg -VMName $vm -RunCommandName "MyRuncommand" -Expand "instanceView" | select-object *

AsyncExecution : False
ErrorBlobUri :
Id : {removed}
InstanceViewEndTime : 16.06.2023 23:02:52
InstanceViewError : blah
At C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandHandlerWindows\2.0.5\Downloads\Script_MyRuncommand_1.ps1:1 char:1
+ throw 'blah'
+ ~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (blah:String) [], RuntimeException
+ FullyQualifiedErrorId : blah

InstanceViewExecutionMessage :
InstanceViewExecutionState : Failed
InstanceViewExitCode : 1
InstanceViewOutput :
InstanceViewStartTime : 16.06.2023 23:02:51
InstanceViewStatuses :
Location : westus2
Name : MyRuncommand
OutputBlobUri :
Parameter :
ProtectedParameter :
ProvisioningState : Succeeded
RunAsPassword :
RunAsUser :
SourceCommandId :
SourceScript : throw 'blah'
SourceScriptUri :
Tag : Microsoft.Azure.PowerShell.Cmdlets.Compute.Models.Api20210701.ResourceTags
TimeoutInSecond : 0
Type : Microsoft.Compute/virtualMachines/runCommands

So, again we can see the error in the instanceView, but something else has changed. the instanceViewExitCode is now 1 and instanceViewExecutionState is failed! But in the previous case it was 0 and success, even though we still had an error. The issue is in terminating vs non-terminating errors in Powershell.

The following are other options to return an error.

Set-AzVmRunCommand -ResourceGroupName $rg -VMName $vm -Location $loc -RunCommandName "Myruncommand" -SourceScript "write-error 'blah' -ErrorAction Stop"

This results in the following.

InstanceViewError : C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandHandlerWindows\2.0.5\Downloads\Script_MyRuncommand_2.ps1 : blah
At C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandHandlerWindows\2.0.5\Downloads\Script_MyRuncommand_2.ps1:1 char:1
+ write-error 'blah' -ErrorAction Stop
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Script_MyRuncommand_2.ps1

InstanceViewExecutionMessage :
InstanceViewExecutionState : Failed
InstanceViewExitCode : 1

You can also change the exit code with

Set-AzVmRunCommand -ResourceGroupName $rg -VMName $vm -Location $loc -RunCommandName "Myruncommand" -SourceScript "exit 42"

Note that in this case there is no value for Error.

InstanceViewError :
InstanceViewExecutionMessage :
InstanceViewExecutionState : Failed
InstanceViewExitCode : 42

So, I hope this provides some guidance on checking for RunCommand failures in your automation.

 

0 comments

Discussion is closed.

Feedback usabilla icon