1

i get this error when im trying to start the docker-compose with the "" command docker-compose -f localdevhelpers/docker-compose.yml -f mediaservice/docker-compose.yml up

% : You cannot call a method on a null-valued expression.
At line:1 char:1
+ % docker-compose -f localdevhelpers/docker-compose.yml  -f mediaservi ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:PSObject) [ForEach-Object], PSArgumentException
    + FullyQualifiedErrorId : InvokeMethodOnNull,Microsoft.PowerShell.Commands.ForEachObjectCommand


any ideas ?

1 Answers1

0

tl;dr

  • Your problem boils down to a simple confusion between the &, the call operator and % the built-in alias of the ForEach-Object cmdlet.

  • However, the resulting error message is confusing and therefore worth explaining - see below.

  • Additionally, guidance on how to discover the meanings of symbols used in PowerShell is provided.


Instead of %, use &, the call operator to execute a command, such as the external docker-compose program; however, given that you specified the program's name unquoted (and given that it doesn't contain special characters that would require quoting and that it isn't expressed via a variable reference), you do not even need & in this case:

# Note: & is optional in this case.
& docker-compose -f localdevhelpers/docker-compose.yml -f mediaservice/docker-compose.yml up

As for what you tried:

% is a built-in alias of the ForEach-Object cmdlet, whose purpose isn't to invoke commands, but to operate on (typically) multiple inputs from the pipeline.

The reason for the - obscure - error message ("cannot call a method on a null-valued expression"):

ForEach-Object is often used with one or more script blocks ({ ... }) to operate on - e.g. 1..3 | ForEach-Object { 1 + $_ }

However, it also supports simplified syntax, whose syntax requirements your call accidentally met, which then led to the - obscure - runtime error:

  • Syntax form % foo bar ... (ForEach-Object foo bar ...) causes foo to be interpreted as the name of a .NET method, with bar and any subsequent arguments being considered the arguments to pass to that method.

  • The specified method is called on each input object, but - in the absence of pipeline input - there is no input object, so ForEach-Object sees $null in lieu of an actual input object. Because methods cannot be invoked on $null, the error message you saw was reported.


Inspecting commands and operators:

You could have used Get-Help or Get-Command to determine what % refers to:

# `Get-Help %` or even `% -?` would print help.
PS> Get-Command %

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           % -> ForEach-Object                                           

This works, because % is a command (an alias).

Among commands, it is unusual in that it is a symbol rather than a word-based name; another exception is ?, which is a built-in alias of the Where-Object cmdlet (because ? is a wildcard metacharacter, you actually have to use Get-Command ``? or Get-Help ``?).

Other symbols are not commands - they're usually operators, which you cannot discover with Get-Command, and only barely with Get-Help (you'll get a lot of results, most of which aren't relevant).

Instead, consult the conceptual about_Operators help topic for help on operators.

This gap in discoverability between commands and operators is unfortunate - GitHub issue #11339 suggests extending Get-Help to support lookup by operator symbols too. In the meantime, the Show-OperatorHelp custom function can provide this functionality (an MIT-licensed Gist; see this answer for a discussion).


Overview of symbol-relevant help topics and information:

  • about_Operators documents all operators.

  • about_Script_Blocks documents script blocks and their literal form, { ... }

  • about_Arrays documents arrays and their quasi-literal form, @(...) - though note that @(...) is technically an operator and is therefore also covered in about_Operators

  • about_Hash_Tables documents hash tables (hashtables) and their literal form, @{ .. .}

  • about_Splatting discusses argument splatting, i.e. the ability to pass a set of arguments (parameter values) via a variable containing a hashtable or array, which must be referenced via @ rather than $ (e.g, @params).

  • about_Quoting_Rules documents quoting, i.e. '...' and "..." strings and their here-string variants, @'<newline>...<newline>'@ and @"<newline>...<newline>"@

  • about_Special_Characters documents PowerShell's escape sequences, whose syntax is based on PowerShell's escape character, `, the so-called backtick

  • about_Comment_Based_Help - indirectly - documents PowerShell's comment syntax, # for to-the-end-of-the-line comments, and <# ... #> for block comments (which can be used both in-line and may span multiple lines).

  • A symbol not covered by the topics above is ; the statement separator (which is only needed if you place multiple statements on a given line).

  • To discover all commands that start with a symbol (non-word character), use the following:

    Get-Command -Type All | Where Name -Match '^\W'
    
mklement0
  • 382,024
  • 64
  • 607
  • 775