Supplying an input file via '@' gives an error: The splatting operator '@' cannot be used to reference variables in an expression
Asked Answered
T

3

15

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

I'm getting an error when running my command

az vm run-command invoke  --command-id RunPowerShellScript --name win-vm -g my-resource-group --scripts @script.ps1

Error:

The splatting operator '@' cannot be used to reference variables in an expression. '@script' can be used only as an argument to a command. To reference variables in an expression use '$script'.

Putting it in quotes only passes in the contents in the quotes, not the contents of the script.

Tgroup answered 18/1, 2020 at 23:7 Comment(3)
How does this work with a variable, e.g. $file="script.ps1"? @$file Just literally prints "@$File"Tgroup
Nevermind, figured it out, just don't include any quotes, i.e. @$File works.Tgroup
tl;dr: While @$File happens to work, it shouldn't be relied upon, given that it breaks if @ is followed by a literal value, as in your question. Use `@$File / `@script.ps1 or "@$File" / '@script.ps1'. Alternatively, to pass everything through as-is, without the ability to reference PowerShell variables, use --%, the stop-parsing symbol operatorDithyrambic
K
36

If you install a package with @ you should install the package with CMD

Kirghiz answered 29/1, 2022 at 9:45 Comment(2)
Well, this works well for npm or yarn libraries but you need to include more information about how or why it works or alternatively provide some source of information. Please do not post a solution without any reason as to why it works.Lithosphere
@r.ansarirad Thanks for the tip. works great. please keep posting any clue regardless of what people say. Help in any measure is always appriciated.Wideman
D
13

Note:

  • This answer shows how to escape / quote the @ char. properly in the context of PowerShell's usual parsing rules.

  • If your command line only contains verbatim arguments - i.e., only literal tokens, not PowerShell variable references (e.g, $file) or expressions (e.g., ($dir + '\script.ps1')) - you can alternatively place --%, the stop-parsing token, before the pass-through arguments, as shown in programmer365's answer; note that cmd.exe-style variable references such as %FOO% are still expanded, however, and that the stop-parsing token has many limitations and pitfalls - see this answer.


@ is a metacharacter in PowerShell (a character with syntactic meaning[1]), so in order to pass it verbatim through to az you must either quote the whole argument or `-escape the @ individually:

With a literal script filename:

# Either: `-escape the @
az ... --scripts `@script.ps1

#`# Or: quote the whole argument
# Use '...' for a literal argument.
az ... --scripts '@script.ps1'

With the script filename stored in a variable, $file:

# Either: `-escape the @
az ... --scripts `@$file

#`# Or: quote the whole argument
# Use "..." for an argument with variable references, i.e. an expandable string
az ... --scripts "@$file"

Note: You could get away with just @$file in the variable case, but given that that doesn't work with any char. other than $ following the @, it's better to get into the habit of always quoting / escaping a verbatim @.


[1] @ has several syntactic uses, and the specific use depends on what character comes next. In your case, the @ in @script.ps1 was interpreted as the splatting operator with a variable named script, with the .ps1 part interpreted as an attempt to access a property named ps1 on that variable - hence the error message.

Dithyrambic answered 19/1, 2020 at 5:25 Comment(0)
H
0

You can use this:

az --% vm run-command invoke  --command-id RunPowerShellScript --name win-vm -g my-resource-group --scripts @script.ps1

In PowerShell the special Stop Parsing symbol --% is a signal to PowerShell to stop interpreting any remaining characters on the line. This can be used to call a non-PowerShell utility and pass along some quoted parameters exactly as is.

Hecatomb answered 19/1, 2020 at 15:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.