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