Azure / Azure/azure-cli

Customer feedback | az vm run-command invoke with RunPowerShellScript does not fail with Exit 1

Open
#29,750 2 comments 3 reactions 2 assignees Claimed by @zhoxing-ms View on GitHub
act-observability-squad Auto-Assign Azure CLI Team Compute question Similar-Issue
Dominant language
Python
Stars
4.6k
Forks
3.5k
Avg merge
3d 2h
Merged PRs (30d)
60

Description

This customer suggestion is being moved from MicrosoftDocs [4542](https://github.com/MicrosoftDocs/azure-docs-cli/issues/4542). Please route to VM engineering team.

### Reference command
az vm run-command invoke

### Customer request summary

1. Show the exit code from my script returned in the json if that's possible.
2. Allow the command to accept `--fail-on-non-zero`, to propogate the exit code of `az vm run-command-invoke` back to me
3. document some best practice for error handling around `az vm run-command invoke` with both bash and powershell.**

### Feedback

I'm using the following form to run a powershell script on a virtual machine in Azure.

```bash
az vm run-command invoke --command-id RunPowerShellScript --name win-vm -g my-resource-group \
--scripts @test/bad.ps1 --parameters "arg1=somefoo" "arg2=somebar"
```

The trouble is, the returned JSON doesn't tell me that my script has exited 1:

```powershell
param(
[string]$arg1,
[string]$arg2
)
Write-Host "[$Env:COMPUTERNAME] This is script should fail with parameters $arg1 and $arg2"
Exit 1
```

Yields:

```json
{
"value": [
{
"code": "ComponentStatus/StdOut/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "[win-vm] This is script should fail with parameters somefoo and somebar",
"time": null
},
{
"code": "ComponentStatus/StdErr/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "",
"time": null
}
]
}

```

When I throw an exception, I do get some error information in the second value object returned by the CLI:

```powershell
param(
[string]$arg1,
[string]$arg2
)
Write-Host "[$Env:COMPUTERNAME] This is script should fail with parameters $arg1 and $arg2"
# https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-exceptions?view=powershell-5.1#working-with-exceptions
# https://powershellexplained.com/2017-04-07-all-dotnet-exception-list/#systemargumentexception
Write-Error -Exception ([System.ArgumentException]::new("[$Env:COMPUTERNAME] I am not a happy script with parameters $arg1 and $arg2")) -ErrorAction Stop
Exit 1
```

Yields:

```json
{
"value": [
{
"code": "ComponentStatus/StdOut/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "[win-vm] This is script should fail with parameters somefoo and somebar",
"time": null
},
{
"code": "ComponentStatus/StdErr/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\1.1.18\\Downloads\\script0.ps1 : [win-vm] I am not a \nhappy script with parameters somefoo and somebar\nAt C:\\Packages\\Plugins\\Microsoft.CPlat.Core.RunCommandWindows\\1.1.18\\Downloads\\script0.ps1:8 char:1\n+ Write-Error -Exception ([System.ArgumentException]::new(\"[$Env:COMPUT ...\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n + CategoryInfo : NotSpecified: (:) [Write-Error], ArgumentException\n + FullyQualifiedErrorId : System.ArgumentException,script0.ps1\n ",
"time": null
}
]
}

```

---

**I think I'm asking for a few things:

💡 It would be nice if I could see the exit code from my script returned in the json if that's possible.
💡 What would be super duper is if I could pass `--fail-on-non-zero`, to propogate the exit code of `az vm run-command-invoke` back to me
📚 I think it would be helpful to document some best practice for error handling around `az vm run-command invoke` with both bash and powershell.**

I am sure I can cobble something together like checking `result.value[1].message.length === 0 && result.value[1].code ==="ComponentStatus/StdOut/succeeded"` but it feels fragile.

Here's what I feel I can safely assume:

```bash
results="bad.json"
az vm run-command invoke --command-id RunPowerShellScript --name win-vm -g win-rg --scripts @test/bad.ps1 --parameters "arg1=somefoo" "arg2=somebar" > $results
#!/bin/bash
results=$1
if [ ! -f "$results" ]; then
echo "##[error] could not find $results"
exit 1
fi

stdout_output=$(cat $results | jq -r '.value[0].message')
stdout_result=$(cat $results | jq -r '.value[0].code')
if [ "$stdout_result" = "ComponentStatus/StdOut/failed" ]; then
echo "##[error] could not read stdout"
elif [ "$stdout_result" = "ComponentStatus/StdOut/succeeded" ]; then
if [[ -n $stdout_output ]]; then
echo $stdout_output
fi
fi

stderr_output=$(cat $results | jq -r '.value[1].message')
stderr_result=$(cat $results | jq -r '.value[1].code')
if [ "$stderr_result" = "ComponentStatus/StdErr/failed" ]; then
echo "##[error] could not read stderr"
elif [ "$stderr_result" = "ComponentStatus/StdErr/succeeded" ]; then
if [[ -n $stderr_output ]]; then
echo "##[error]$stderr_output"
fi
fi
```

### Page URL

https://learn.microsoft.com/en-us/cli/azure/vm/run-command?view=azure-cli-latest

### Content source URL

https://github.com/MicrosoftDocs/azure-docs-cli/blob/main/latest/docs-ref-autogen/vm/run-command.yml

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.