1

I have a Powershell script that I run remotely. I'm trying to add a value to the register. But letters with special accents are replaced with something else.

When I run it locally on the machine the letters are correctly added in the register.

When I remotely write the output to console and check the logs, I can see it works.

As a test I run these commands directly after each other:

write-host("Issuer: " + $Issuer)

Set-Itemproperty -path 'HKLM:\SYSTEM\Test' -Name 'Issuer' -value $Issuer

Result:

Result

The write-host returns the correct letters. The register change keeps changing it to the wrong characters. I guess it has to do something with the user that remotely runs the script not having the right default charset. So I would like to define this in the script.

I have tried following without result:

  • Adding chcp 65001 to the script.
  • Running it with a CMD.EXE command: cmd.exe /c "REG ADD HKLM\System\Test /v ""Issuer"" /t REG_SZ /d ""$Issuer"" /F"
  • Adding chcp 65001 to the CMD command.
  • Tried running CMD with "cmd.exe [Text.Utf8Encoding] /c" , but can't find much info supporting this.
  • ...

I had the same problem when sending a mail via Powershell. Here the characters in the mail were replaced with "?". This I could solve by adding " -Encoding ([System.Text.Encoding]::UTF8)" to the command. But I can't find a way to do this for Set-Itemproperty.

Edit: I found this answer to be somewhat helpful: Using UTF-8 Encoding (CHCP 65001) in Command Prompt / Windows Powershell (Windows 10)

When I go to "Change System Locale" and I check the beta option "Use Unicode UTF-8 for worldwide language support", everything works. So I narrowed down where the problem lies. I just don't want to enable this beta option for all our machines since I read that it might inflict with other applications.

Strange thing is. When I output the $OutputEncoding I have following output:

Normal 
(not working)
-------------
IsSingleByte      : True
BodyName          : us-ascii
EncodingName      : US-ASCII
HeaderName        : us-ascii
WebName           : us-ascii
WindowsCodePage   : 1252
IsBrowserDisplay  : False
IsBrowserSave     : False
IsMailNewsDisplay : True
IsMailNewsSave    : True
EncoderFallback   : System.Text.EncoderReplacementFallback
DecoderFallback   : System.Text.DecoderReplacementFallback
IsReadOnly        : True
CodePage          : 20127


With following line in the script: $OutputEncoding = [Console]::OutputEncoding = New-Object System.Text.Utf8Encoding
(not working)
-------------
BodyName          : utf-8
EncodingName      : Unicode (UTF-8)
HeaderName        : utf-8
WebName           : utf-8
WindowsCodePage   : 1200
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
IsSingleByte      : False
EncoderFallback   : System.Text.EncoderReplacementFallback
DecoderFallback   : System.Text.DecoderReplacementFallback
IsReadOnly        : True
CodePage          : 65001

With System wide UTF Change  (via intl.cpl > Administrative > Change System locale > Checkbox
(working)
---------------------------
IsSingleByte      : True
BodyName          : us-ascii
EncodingName      : US-ASCII
HeaderName        : us-ascii
WebName           : us-ascii
WindowsCodePage   : 1252
IsBrowserDisplay  : False
IsBrowserSave     : False
IsMailNewsDisplay : True
IsMailNewsSave    : True
EncoderFallback   : System.Text.EncoderReplacementFallback
DecoderFallback   : System.Text.DecoderReplacementFallback
IsReadOnly        : True
CodePage          : 20127

As you can see the $OutputEncoding hasn't changed when enabling the system wide option. What did it change? Can I change it via powershell before making my registry change and change it back after?

heartfailure
  • 76
  • 1
  • 5
  • Question: you did save your script in UTF-8 did you? – Theo Sep 14 '21 at 09:53
  • How do I save a PS1 script in UTF-8? When saving a text file I know this is an option. – heartfailure Sep 14 '21 at 10:25
  • What editor are you using? PowerShell ISE (as of version 3.0 I believe) by default saves in UTF-8 (with BOM encoding). Visual Studio Code saves files using UTF8 (without a BOM) by default. Others may default to ANSI encoding (Windows-1252). If not sure, open the file in notepad++ where you can also change the encoding of the file. – Theo Sep 14 '21 at 10:35
  • Oh thx. Notepad++ tells me it is UTF-8-BOM. But like I said. I don't have problems with special characters in the script. Only when creating the register item. – heartfailure Sep 14 '21 at 10:46
  • Is that regedit.exe you are using to view what is written in the registry value? All string values will be a Unicode or ANSI string depending on whether you use the Unicode (RegSetValueExW) or ANSI (RegSetValueExA) functions and my belief is that PowerShell uses the Unicode function.. – Theo Sep 14 '21 at 10:55
  • Yes. To view what is inside the registry I use regedit.exe. The characters show up fine with accents when I execute the script locally from an other account. So Powershell i perfectly capable of writing it correctly to the register. I just need to find a way to pass the charset along. – heartfailure Sep 14 '21 at 11:34
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/237091/discussion-between-heartfailure-and-theo). – heartfailure Sep 14 '21 at 11:52
  • Sorry, I don't do chat. You can test if PowerShell screwed up the accent or not by reading that value back. What do you get with `Get-ItemPropertyValue -Path 'HKLM:\SYSTEM\Test' -Name 'Issuer'` ? – Theo Sep 14 '21 at 13:59
  • I have updated my original post with more info. – heartfailure Sep 15 '21 at 08:12

1 Answers1

0

Alright. Since I tried all possible locale and encoding options, but didn't find one that worked, I implemented a workaround.

In order to add something to the register I create and import a REG file. The benefit here is that the Powershell command "Add-Content" does support the -Encoding parameter. It looks like this:

New-Item "$serverPath\$user.reg"
Set-Content "$serverPath\$user.reg" 'Windows Registry Editor Version 5.00'
Add-Content "$serverPath\$user.reg" ''
Add-Content "$serverPath\$user.reg" '[HKEY_LOCAL_MACHINE\SYSTEM\Test]' 
Add-Content "$serverPath\$user.reg" """Issuer""=""$Issuer""" -Encoding OEM
reg import "$serverPath\$user.reg"
heartfailure
  • 76
  • 1
  • 5