Describe the bug
az vm get-instance-view doesn’t accept multiple ids
To Reproduce
Single id works:
az vm list --query "[0:1].id" -o tsv | az vm get-instance-view --ids @- --query instanceView.statuses[1] --output table
Two and more won’t work:
az vm list --query "[0:2].id" -o tsv | az vm get-instance-view --ids @- --query instanceView.statuses[1] --output table
Expected behavior
Command should work with multiple ids passed
Environment summary
Install Method (e.g. pip, interactive script, apt-get, Docker, MSI, edge build) / CLI version (az --version) / OS version / Shell Type (e.g. bash, cmd.exe, Bash on Windows)
MSI / azure-cli (2.0.42) / Windows server 2016 / cmd / Python (Windows) 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)]
Additional context
Add any other context about the problem here.
Nothing
The following command works:
az vm list --query "[0:2].id" -o tsv | az vm get-instance-view --ids @- \
--query [].instanceView.statuses[1] --output table
Notice the modified query.
vm get-instance-view returns a json object representing the vm instance (if one vm name/id is passed as an argument) but a list of objects if more than one vm (resource id) is passed as an argument.
To determine whether an issue is a cli issue or JMESPATH issue, it can help to try the command without any queries first and then use the default output.
Please let me know if you have any other questions.
Notice the modified query.
I don’t think the query was the issue in my case.
It fails before it gets to query part, IMO.
Without query I got very same error for 2 ids:
az vm list --query "[0:2].id" -o tsv | az vm get-instance-view --ids @-
_Operation failed with status: 'Bad Request'. Details: 400 Client Error: Bad Request for url: https://management.azure.com/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-a%0A?$expand=instanceView&api-version=2017-12-01_
Note, VM name is adfs-a, not adfs-a%0A
And no error for one:
az vm list --query "[0].id" -o tsv | az vm get-instance-view --ids @-
_{
"availabilitySet": {
"id": "/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/availabilitySets/ADFS",
"resourceGroup": "ADFS"
},
...
}_
BTW: Could you show how pass two or more ids instead of “@-“, please?
az vm get-instance-view --ids @-
What version of the cli are you using? Could you try updating to the latest and rerunning this command?
If updating the CLI isn't possible. I have some questions:
Thanks.
Also to pass the two ids, if you are using a linux-based shell, you can do any of the following:
Get ids, store in shell variable, use this shell variable to get vm instances.
VM_IDS=$(az vm list --query "[0].id" -o tsv) \
az vm get-instance-view --ids $VM_IDS
Get ids, assign to shell variable, if successful, use these ids to get the instances:
VM_IDS=$(az vm list --query "[0].id" -o tsv) && az vm get-instance-view --ids $VM_IDS
Get ids and pass the result to get-instance-view:
az vm get-instance-view --ids $(az vm list --query "[0].id" -o tsv)
I think we got it!
Thanks a lot for your tip! 👍
Long story short:
az vm list --query "[0:2].id" -o tsv
_/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-a
/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-b_
Notice, the results are separated by "crlf ", not "space"!
I'd use
| tr '\n' ' '
to handle it on linux, but I've no clue how it's done on Windows...
As a result VM name in next request gets changed from “adfs-a” to “adfs-a%0A”.
You can see it on my prev. post.
The latter doesn’t exist obviously, thus all that juzz.
I’m azure-cli (2.0.42), I assume that’s the latest one?
Could you show how pass two or more ids instead of “@-“, please?
az vm get-instance-view -ids
ids separated by space works fine, but cannot separate by Line feed (0x0A)
I guess, not a big deal to fix it (for poor souls who have to use Windows to manage Azure)
What do we do next?
BTW: Try to simulate it on linux with
az vm list --query "[0:2].id" -o tsv | tr ' ' '\n' | az vm get-instance-view --ids @-
No problem! :)
Yes, I just tested this scenario on a windows machine and it seems that the newline / carriage return is the issue. The command you asked me to simulate ran successfully on a linux-based machine. The CLI should recognize the carriage-return/linefeed as whitespace, so this is likely a bug. We will work on a fix for it.
I can try to get back to you with an automatic work around tomorrow. But for now your best bet is manually converting the carriage return to line space using a text editor.
adewaleo,
I can try to get back to you with an automatic work around tomorrow.
Thanks again! 👍
I’m not in any rush with it.
I’m sure you have more important thing to do too.
But for now your best bet is manually converting the carriage return to line space using a text editor.
Ugh... I’ve tried slightly different approach.
I’ve got GNU sed from here:
http://gnuwin32.sourceforge.net/packages/sed.htm
And run right into another bug, probably:
The steps to reproduce are:
# get VMs list separated by “space” into ids.txt
az vm list --query "[0:3].id" -o tsv | sed ":a;N;$!ba;s/\n/ /g" > ids.txt
# piping the list returns first VM from it only
type ids.txt | az vm get-instance-view --ids @- > result.txt
# same list inline returns all VMs
az vm get-instance-view --ids /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-a /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-a0 /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-b > result-1.txt
I wonder why most of the examples suggest “inline-ing”:
az vm get-instance-view --ids $(az vm list --query "[0].id" -o tsv)
instead of piping:
az vm list --query "[0].id" -o tsv | az vm get-instance-view --ids -@
The former works for Linux only, while there latter should be good for everybody, right?
I wonder why most of the examples suggest “inline-ing”:
az vm get-instance-view --ids $(az vm list --query "[0].id" -o tsv)
instead of piping:
az vm list --query "[0].id" -o tsv | az vm get-instance-view --ids -@
The former works for Linux only, while there latter should be good for everybody, right?
Either way works. I imagine it's more of a matter of style. However, inlining could be useful in instances where multiple arguments are the results of multiple commands. Moreover, I am not sure why the command above worked where supplying @- somehow read from the piped stdin.
Either way works. I imagine it's more of a matter of style. However, inlining could be useful in instances where multiple arguments are the results of multiple commands.
Yep, definitely agree with the latter, tho long commands are a bit more difficult to understand.
Moreover, I am not sure why the command above worked where supplying @- somehow read from the piped stdin.
@- have to to read parameters from stdin, that’s the only way it can work, IMO.
BTW: Tried to google smth. like
az cli +"@-", but it keeps dropping last term, don’t know how convince it not to!
So it turns out that "@-" is a CLI feature. Generally --param @filename, passes the contents of filename as the value of --param. The CLI treats @- specially, as reading from stdin.
We will most likely document the use of @- as a param value in our docs or upcoming blog post, but the @ symbol's use in the cli is documented in a few example such as VM create's example "Create a Debian VM with SSH key authentication and a public DNS entry..."
Finally, it also turns out that resource IDS passed through --ids can be json objects (containing an id field) and/or id strings from tsv output.
So for example, one could run the following:
Regular way:
$ az vm list --query [0:2].id -o tsv | az vm get-instance-view --ids @- --query "[].{name:name,id:id}" -otsv
Passing json list of ids:
$ az vm list --query "[0:2].{id:id}" | az vm get-instance-view --ids @- --query "[].{name:name,id:id}" -otsv
Passing json list of full data (containing vm ids):
$ az vm list --query [0:2] | az vm get-instance-view --ids @- --query "[].{name:name,id:id}" -otsv
Mix json output with tsv output:
$ VM3_ID=$(az vm show -n tosin-vm-3 --query "id" -o tsv)
$ echo $VM3_ID
/subscriptions/0000000000000.../resourceGroups/ova-test/providers/Microsoft.Compute/virtualMachines/tosin-vm-3
$ az vm list --query [0:2] | az vm get-instance-view --ids @- $VM3_ID --query "[].{name:name,id:id}" -otsv
I assume “Regular way” will be fixed in next public release, right?
Thanks a lot for the workaround with “Passing json list of ids”! :)
And Happy Thanksgiving!
I assume “Regular way” will be fixed in next public release, right?
Thanks a lot for the workaround with “Passing json list of ids”! :)
And Happy Thanksgiving!
Yes, "the regular way", will be fixed in the next public release; the pr for the fix has been merged.
Thanks! Have a Happy Thanksgiving as well!