1

I have a fairly simple PS script that was working perfectly, and now has suddenly started giving errors. I have narrowed the problem portion to a couple of Get-Content statements. Here's what the affected part of the script looks like:

$pathSource = "D:\FileDirectory"
Set-Location -Path $pathSource
Get-Content -Encoding UTF8 -Path FilesA*.txt | Out-File -Encoding ASCII FilesA_Digest.txt
Get-Content -Encoding UTF8 -Path FilesB*.txt | Out-File -Encoding ASCII FilesB_Digest.txt

This part of the script gathers up a collection of like-named files and concatenates them into a single text file for uploading to an FTP site. The Get-Content/Out-File was needed as the original files are encoded incorrectly for the FTP site. The script was working perfectly, running once each night for several weeks. Now, it gets the following error when the Get-Content statements are reached:

Get-Content : A parameter cannot be found that matches parameter name 'Encoding'.
At D:\FileDirectory\Script.ps1

Environment is Windows Server 2016. I've tried different variations on the Get-Content parameters, but nothing has worked. I know there is a bug that affects network-mapped drives, but that's not the case here -- all files are local.

Any ideas/suggestions?

npowroz
  • 11
  • 5
  • 2
    `-Path FilesA*.txt` would include the Out-File `FilesA_Digest.txt` on successive runs. –  Feb 03 '19 at 23:12
  • As an aside: applying `-Encoding ASCII` to (originally) UTF-8-encoded data may result in _loss of information_: any characters in the input that are outside the ASCII range will be transliterated to _literal_ `?` characters. (By contrast, If the original data contains _only_ ASCII-range characters, there's no need to transcode at all, given that UTF-8 is a _superset_ of ASCII.) – mklement0 Feb 03 '19 at 23:47
  • @LotPings -- that was a typo on my part, since I was using dummy filenames that don't actually match the original script. The original script doesn't suffer from that issue. – npowroz Feb 04 '19 at 00:18
  • @mklelement0 -- I realize that there may be a data loss issue, but the reality is that there won't be, since the source file doesn't contain any characters outside the standard ASCII set. – npowroz Feb 04 '19 at 00:22
  • @npowroz: I see, but that contradicts your claim "the original files are encoded incorrectly": If you can read them correctly with `-Encoding UTF8` _and_ they only contain ASCII-range characters, you don't need any transcoding at all. – mklement0 Feb 04 '19 at 00:49
  • @mklelement0: I was skipping over details that didn't matter. The reality is that the files were being created by Powershell encoded as "UCS-2 LE BOM". The receiving application at the end of the FTP connection bombs when it sees that, so by adding the -Encoding parameters the encoding problem gets fixed. – npowroz Feb 04 '19 at 05:45
  • @npowroz: If your files have a BOM, then what you pass to `-Encoding` when you call `Get-Content` is irrelevant, and passing `UTF8`, which doesn't match the _actual_ encoding, is confusing. (It sounds like the actual encoding is UTF-16LE (which PowerShell misleadingly calls `Unicode`), which is what I presume you meant by "UCS2 LE", which, strictly speaking is _not_ the same as UTF-16LE. UTF-16LE (with BOM) is what Windows PowerShell produces by default with `>` and `Out-File` (but _not_ with `Set-Content`)). – mklement0 Feb 05 '19 at 05:01
  • Restarting PowerShell fixed it for me... weird though. – NDM Jan 24 '23 at 07:04

4 Answers4

1

The only plausible explanation I can think of is that a custom Get-Content command that lacks an -Encoding parameter is shadowing (overriding) the standard Get-Content cmdlet in the PowerShell session that's executing your script.

To demonstrate:

# Define a custom Get-Content command (function) that accepts only 
# a (positional) -Path parameter, not also -Encoding.
function Get-Content { [CmdletBinding()] param([string] $Path) }

# Now try to use Get-Content -Encoding
Get-Content -Encoding Utf8 FilesA*.txt

You'll see the same error message as in your question.

Use Get-Command Get-Content -All to see all commands named Get-Content, with the effective command listed first.

Then examine where any custom commands may come from; e.g., your $PROFILE script may contain one.

To rule out $PROFILE as the culprit, start PowerShell without loading the profile script and examine Get-Content then:

powershell -noprofile  # Windows PowerShell
pwsh -noprofile        # PowerShell Core

A simple way to rule out custom overrides ad hoc is to call a command by its module-qualified name:

Microsoft.Powershell.Management\Get-Content ...

You can determine a built-in cmdlet's module name of origin as follows:

PS> (Get-Command Get-Content -All)[-1].ModuleName
Microsoft.PowerShell.Management

In a pinch you can also infer the originating module name from the URL of the help topic:

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • I've tried all of your suggestions and still get the same error, so now I'm really at a loss. I know I'm using the built-in Get-Content with no overrides, no customization, nothing special. This is truly weird. – npowroz Feb 04 '19 at 00:36
  • 1
    @npowroz: So if you run your `*.ps1` script from a PowerShell instance that you've started with `-noprofile` and that reports `Microsoft.PowerShell.Management` for `(Get-Command Get-Content).ModuleName` you still get the same error? – mklement0 Feb 04 '19 at 00:38
  • @npowroz: If you do `Format-Hex `, does it look like any invisible control characters are present in your file? – mklement0 Feb 04 '19 at 00:40
  • Doing "Get-Command Get-Content" returns "Version 3.1.0.0 / Source Microsoft.PowerShell.Management" after I started it with -noprofile. I've dumped it using Format-Hex, but I'm not seeing anything that sticks out at me. – npowroz Feb 04 '19 at 00:59
  • @npowroz: See if the issue is specific to a given machine with a given PowerShell / OS version. – mklement0 Feb 04 '19 at 01:11
  • I just tested it on a Windows Server 2008 instance, running whatever version of PowerShell comes with that (1.0 I think). Same error -- (to paraphrase) "Parameter -Encoding is invalid". The only thing that comes to mind is that some patch has broken things, but I have no idea if I'm even in the right universe. – npowroz Feb 04 '19 at 04:59
  • @npowroz: What is the _exact_ error message? Is it different from the one you cite in your question? – mklement0 Feb 04 '19 at 05:01
  • Nope, it's exactly the same as the one I cited in the original question. That's the reason why I paraphrased. Apologies if that created a red herring. And I know that it's not a profile issue on that machine as I have never run PowerShell on it. As well, the call to Get-Content was the long form "Microsoft.Powershell.Management\Get-Content -Encoding ..." – npowroz Feb 04 '19 at 05:29
  • @mklelement0: It just got weirder. I tested the Get-Content on a different server, another implementation of Server 2016. It worked perfectly, with no errors. Interestingly, that machine is a little out of date with its patches. I'm leaning more and more toward a bad patch that is breaking the Get-Content applet in Powershell. – npowroz Feb 04 '19 at 05:48
  • @npowroz: W2K8 indeed _originally_ came with PSv1, _which no one should be using anymore_ - you can't even find documentation for it anymore, so I can't tell if v1's `Get-Content` had an `-Encoding` parameter. Even if it didn't, it wouldn't explain how your _previously working_ script stopped working - unless you ran it on a _different_ machine. `$PSVersionTable.PSVersion` will tell you what version a given machine is running. – mklement0 Feb 05 '19 at 04:00
0

It seems an issue with the out command. Can you please try below code :

$pathSource = "D:\FileDirectory"
Set-Location -Path $pathSource
Get-Content -Encoding UTF8 -Path FilesA*.txt | Set-Content  -Encoding ASCII -path FilesA_Digest.txt
Get-Content -Encoding UTF8 -Path FilesB*.txt | Set-Content  -Encoding ASCII -path FilesB_Digest.txt
sarvesh shetty
  • 846
  • 8
  • 8
  • `Out-File` is _not_ the problem, given that the OP's error message clearly mentions `Get-Content` as the offending cmdlet: `Get-Content : A parameter cannot be found that matches parameter name 'Encoding'.` – mklement0 Feb 05 '19 at 03:53
0

Well, I don't know why it failed, but I can say that I have completely re-written the script and now it works. I have to note that, given the errors that were occurring, I also don't know why it is now working.

I am using the exact same calls to the Get-Content commandlet, with the -Encoding parameter and the pipe to Out-File with its own -Encoding parameter. I am doing the exact same actions as the previous version of the script. The only part that is significantly different is the portion that performs the FTP transfer of the processed files. I'm now using only PowerShell to perform the transfer rather than CuteFTP and it all seems to be working correctly.

Thanks to everyone who contributed.

Cheers Norm

npowroz
  • 11
  • 5
0

Not sure if it helps, but I was running into the same with:

$n = ni '[hi]' -value 'some text'
gc $n -Encoding Byte
$f = ls *hi*
$f.where{$_.name -eq '[hi]'}.Delete()

also looks like there's already a chain of SOs about this known bug see this answer

Gregor y
  • 1,762
  • 15
  • 22