1
votes

Function in my PowerShell script is as follows:

function replace-file-content([string] $path, [string] $replace, [string] $replacewith) {
    (Get-Content $path) |
      Foreach-Object -replace{$replace,$replacewith}|
        Out-File $path

}

Error I am getting is:

ForEach-Object : Cannot bind parameter 'Process'. Cannot convert the "-replace" value of type "System.String" to type "System.Management.Automation.ScriptBlock".

1
Foreach-Object {$_ -replace $replace,$replacewith}TessellatingHeckler

1 Answers

2
votes

Foreach-Object -replace{$replace,$replacewith}

Since Foreach-Object is a cmdlet, the tokens that follow it are parsed in argument mode, meaning that they are either interpreted:

  • as parameter names, if they start with -

  • as positional arguments otherwise.

While -replace is an operator in expression mode, passed to ForEach-Object it is instead interpreted as a parameter name.

However, ForEach-Object has no parameter named -replace, which explains the error you saw (in PSv2; in PSv5.1+ (and possibly earlier), it is a different error that is, regrettably, less obvious).

What you meant to do was to use -replace inside a script block ({ ... }) - a reusable piece of PowerShell code executed on demand - which itself forms a new parsing context; you can pass such a script block to ForEach-Object positionally, in which case it implicitly binds to the
-Process parameter, or explicitly with parameter name -Process; that script block specifies the code to execute for each input object.

Inside the script block, you must use automatic variable $_ to refer to the input object at hand:

# Same as: Foreach-Object -Process { $_ -replace $replace, $replacewith }
Foreach-Object { $_ -replace $replace, $replacewith }

A statement starting with $ is parsed in expression mode, in which you can then use operators such as -replace, as shown above.