Encode a string in UTF-8 - powershell

I want to encode a string into UTF8 in PowerShell.
This is what I tried:
$consumer_key ="xvz1evFS4wEEPTGEFPHBog"
$enc_consumer_key = System.Text.UTF8Encoding($consumer_key)
But I get an error:
System.Text.UTF8Encoding in not recognize as the name of cmdlet

Try this instead:
$enc = [System.Text.Encoding]::UTF8
$consumerkey ="xvz1evFS4wEEPTGEFPHBog"
$encconsumerkey= $enc.GetBytes($consumerkey)

Encode/Decode:
$enc = [System.Text.Encoding]::UTF8.GetBytes("â")
# 195 162
[System.Text.Encoding]::UTF8.GetString($enc)
# â
[System.Text.Encoding]::ASCII.GetString($enc)
# ??
[System.Text.Encoding]::Default.GetString($enc) # Windows-1252
# â
This is the best question I search that lead me to the above solution for text encoding/decoding characters in PowerShell. In my case I was trying to debug malformed UTF8 characters. Hope it helps someone in the future.
-Check that BOM

If you just want to write the string to file:
$consumer_key ="xvz1evFS4wEEPTGEFPHBog"
$consumer_key | Out-File c:\path\utf8file.txt -Encoding UTF8

Related

Powershell form to convert string to base64 and back and write to file

I have this function that I wrote that will Encode/Decode strings in Base64 format.
I understand the end goal of what I am asking for might not make sense but it is something I have to do.
I have a snp.txt file with the contents start notepad
I need to convert that string in the file to Base64 and it should look like this:
cwB0AGEAcgB0ACAAbgBvAHQAZQBwAGEAZAA=
Then immedietely turn around and decode it right back to what it was to look like:
start notepad
However when I do that using the example below, when it is decoded back it returns:
s t a r t n o t e p a d
I am not sure why the text has the spaces in it
function B64 {
[CmdletBinding(DefaultParameterSetName="encString")]
param(
[Parameter(Position=0, ParameterSetName="encString")]
[Alias("es")]
[string]$encString,
[Parameter(Position=0, ParameterSetName="decString")]
[Alias("ds")]
[string]$decString
)
if ($psCmdlet.ParameterSetName -eq "encString") {
$encoded = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($encString))
return $encoded
}
elseif ($psCmdlet.ParameterSetName -eq "decString") {
$decoded = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($decString))
return $decoded
}
}
This is where I call the functions to first encode the string and then decode it back again returning:
s t a r t n o t e p a d
$filePath = "C:\Users\User\Desktop\snp.txt"
$encData = Get-Content $filePath
$enc = B64 -encString $fp;$enc | Out-File -FilePath $fp
Sleep 1
$dec = B64 -ds $encData;$dec | Out-File -FilePath $fp
This happens because you're using different encodings to encode and decode your string. Either ascii for both or uncicode for both. Preferably you should use UTF8. The encoding of the file should also match with the encodings used on your function. –
Santiago Squarzon

Hebrew send to google spreadsheet from PowerShell Hebrew correctly

Please help.
In console look hebrew correct but in spreadsheet is not correctenter image description here
$import = New-Object System.Collections.ArrayList($null)
$import.Add( #("route_id"))
$import.Add( #( 'אבא אבן 1 הרצליה' )) | Out-NULL
try {
$Response = Set-GSheetData -accessToken $accessToken -rangeA1 "A1:X$($import.Count)" -sheetName "23-07-21" -spreadSheetID $SpreadsheetID -values $import -Verbose
$Response | ConvertTo-Json
} catch {
$err = $_.Exception
$err | Select-Object -Property *
"Response: "
$err.Response
}
Hebrew might not be supported in Sheets, you would need to install a font. You can try with this one
https://fonts.google.com/noto/specimen/Noto+Sans+Hebrew?query=hebrew
Update
After testing using the Rest API, it works, so the issue might be related on how the PowerShell process hebrew characters.
I've found some information on how to process hebrew characters in the Windows Powershell
[Console]::OutputEncoding = [Text.Encoding]::GetEncoding(1255)
Make sure the console is outputting the right characters and the POST a request to Google Sheets
It's bug in the psmodule. Author must specify encoding UTF8.
https://github.com/umn-microsoft-automation/UMN-Google/pull/50

Writing output of Class to text file adds blank lines

I created a class to gather some data in a script, although not sure if this is the appropriate use of this. When I output class to text file it adds 2 blank lines each time it writes to the file. Is there a way to remove this?
[int] $numOut = 0
[int] $numIn = 0
[int] $numNone = 0
[int] $numCPE = 0
[int] $numSQR = 0
[int] $numEGX = 0
[int] $numCQA = 0
various parts of code do a self addition like this, these are the only types of manipulation to these variables
$script:numOut += 1
$cLength = $randString.Length #this is a random string
$numSQR = $numCPE + $cLength #add CPE + length of random strin
$total = $numOut + $numIn + $numNone + $numCPE + $numSQR + $numEGX + $numCQA
class Logging {
[string]$DateTime
[string]$User
[string]$numOut
[string]$numIn
[string]$numNone
[string]$numCPE
[string]$numSQR
[string]$numEGX
[string]$numCQA
[string]$total
}
$Logging = [Logging]::new()
$Logging.DateTime = Get-Date
$Logging.User = $env:username
$logging.NumOut = $numOut
$logging.NumIn = $numIn
$logging.NumNone = $numNone
$logging.NumCPE = $numCPE
$logging.NumSQR = $numSQR
$logging.NumEGX = $numEGX
$logging.NumCQA = $numCQA
$logging.Total = $total
write-output $logging | Format-Table -AutoSize -HideTableHeaders >> $CWD\log.txt
It writes to the file like this:
arealhobo 10/24/2020 19:47:24 1 0 1 1 1 0 1
arealhobo 10/24/2020 19:50:37 1 0 1 1 1 0 1
arealhobo 10/24/2020 19:53:15 1 0 1 1 1 0 1
You can replace the newlines first:
(write-output $logging | Format-Table -AutoSize -HideTableHeaders | Out-string) -replace "\n","" >> $CWD\log.txt
You could also implement a method to handle outputting to a file. Here's an example.
class Logging {
[string]$DateTime
[string]$User
[string]$numOut
[string]$numIn
[string]$numNone
[string]$numCPE
[string]$numSQR
[string]$numEGX
[string]$numCQA
[string]$total
Log($file){
$this | Export-Csv -Path $file -Delimiter "`t" -Append -NoTypeInformation
}
}
$Logging = [Logging]::new()
$Logging.DateTime = Get-Date
$Logging.User = $env:username
$logging.NumOut = $numOut
$logging.NumIn = $numIn
$logging.NumNone = $numNone
$logging.NumCPE = $numCPE
$logging.NumSQR = $numSQR
$logging.NumEGX = $numEGX
$logging.NumCQA = $numCQA
$logging.Total = $total
Now you can simply call $logging.log("path\to\logfile") specifying where to write.
$Logging.log("c:\Some\Path\logging.log")
Note: The scenario described below may not match the OP's. The answer may still be of interest if you find that file content prints as follows to the consoler after having used >> to append to a preexisting file in Windows PowerShell; note what appears to be extra spacing and extra empty lines:
To avoid your problem, which most likely stems from an unintended mix of different character encodings in the output file produced by >>, you have two options:
If you do know the character encoding used for the preexisting content in the output file, use Out-File -Append and match that encoding via the -Encoding parameter:
# Using UTF-8 in this example.
$logging | Format-Table -AutoSize -HideTableHeaders |
Out-File -Append -Encoding Utf8 $CWD\log.txt
Note that > / >> are in effect like calling Out-File / Out-File -Append, except that you don't get to control the character encoding.
In the unlikely event that you don't know the preexisting character encoding, you can use Add-Content, which matches it automatically - unlike >> / Out-File -Append - but that requires extra work:
An additional Out-String -Stream call is needed beforehand, to provide the formatting that >> (and > / Out-File) implicitly provide; without it, Add-Content (and Set-Content) apply simple .ToString() stringification of the output objects, and in the case of the objects output by Format-* cmdlets that results in useless representations, namely their type names only (e.g., Microsoft.PowerShell.Commands.Internal.Format.FormatStartData):
# Add-Content, unlike >>, matches the character encoding of the existing file.
# Since Add-Content, unlike > / >> / Out-File, uses simple .ToString()
# stringification you first need a call to `Out-String`, which provides
# the same formatting that > / >> / Out-File implicitly does.
$logging | Format-Table -AutoSize -HideTableHeaders |
Out-String -Stream | Add-Content $CWD\log.txt
Read on for background information.
Assuming you're using Windows PowerShell rather than PowerShell [Core] v6+[1]:
The most likely cause (the explanation doesn't fully match the output in your question, but I suspect that is a posting artifact):
You had a preexisting log.txt file with a single-byte character encoding[2], most likely either the legacy encoding based on your system's active ANSI code page or a UTF-8 encoded file (with or without a BOM).
When you appended content with >>, PowerShell blindly used its default character encoding for > / >>, which in Windows PowerShell[1] is "Unicode" (UTF-16LE), which is a double-byte encoding[2] - in effect (but not technically) these redirection operators are aliases for Out-File [-Append].
The result is that the newly appended text is misinterpreted when the file is later read, because the UTF-16LE characters are read byte by byte instead of being interpreted as the two-byte sequences that they are.
Since characters in the ASCII range have a NUL byte as the 2nd byte in their 2-byte representation, reading the file byte byte sees an extra NUL ("`0") character after every original character.
On Windows[3], this has two effects when you print the file's content to the console with Get-Content:
What appears to be a space character is inserted between ASCII-range character so that, say, foo prints as f o o - in reality, these are the extra NUL characters.
An extra, (apparently) empty line is inserted after every line, which is a side effect of PowerShell accepting different newline styles interchangeably (CRLF, LF, CR):
Due to the extra NULs, the original CRLF sequence ("`r`n") is read as "`r`0`n`0", which causes PowerShell to treat "`r" and "`n" individually as newlines (line breaks), resulting in the extra line.
Note that the extra line effectively contains a single NUL, and that the subsequent line then starts with a NUL (the trailing one from the "`n"), so among the misinterpreted lines all but the first one appear to start with a space.
[1] PowerShell [Core] v6+ now consistently defaults to BOM-less UTF-8 across all cmdlets. While >> (Out-File -Append) still don't match an existing encoding, the prevalence of UTF-8 files makes this less of a problem. See this answer for more information about character encoding in PowerShell.
[2] Strictly speaking, UTF-8 and UTF-16 are variable-length encodings, because not every byte in UTF-8 is necessarily its own character (that only applies to chars. in the ASCII range), and, similarly, certain (exotic) characters require two 2-byte sequences in UTF-16. However, it is fair to say that UTF-8 / UTF-16 are single/double-byte-based.
[3] On Unix-like platforms (Linux, macOS) you may not even notice the problem when printing to the terminal, because their terminal emulators typically ignore NULs, and, due to LF ("`n") alone being used as newlines, no extra lines appear. Yet, the extra NULs are still present.

Powershell escape for variables that contain passwords

So I am using a variable that contains a password and just recently found out that some of the passwords are containing special characters. I have no control over what the password is so I have to deal with whatever I am getting. I know the back tick '`' character is what is used to escape characters. The whole reason for this post is that I am finding passwords is text files and replacing the found password with a pattern of 'xxxxxxxxx'.
Currently the code I am using is this:
$pass = "DR$123asd##!"
Because the $pass variable contains the '$' character the $123asd is seen as a variable that has no value
$pass
so all you get is:
DR##!
If I change the pass variable like this
$pass = 'DR$123asd##!'
$pass
DR$123asd##!
Then the '$' character is ignored and the string is complete, but If I run the code:
$output | foreach-object { $_ -replace "$pass", 'xxxxxxxx' }
This is my password DR$123asd##!, It is a great password!
The password doesn't get replaced and I'm, not sure why.
-replace is a regular expression operator, and the $ sigil is indeed a special character in regex.
You can escape all regex meta-characters in a literal string with [regex]::Escape():
$output | foreach-object { $_ -replace [regex]::Escape("$pass"), 'xxxxxxxx' }

Encoding not working when email send by Powershell

Im sending a testemail via powershell like
$messageParameters = #{
Subject = "Email Tool"
Body = Get-Content "C:\body.txt" | out-string
From = "Info <info#xy.de>"
To = "Me <me#xy.de>"
SmtpServer = "mail.xy.de"
Encoding = New-Object System.Text.UTF8Encoding
}
send-mailmessage #messageParameters -BodyAsHtml
everything is working find except the encoding.
if i don't use encoding some characters are send as ??
and if i use it, what i actually want to do, than i get this Ä Ö Ü
but it should be ä ö ü and not this above.
If i don't send the mail as HTML it works.
How can i send the mail with the right encoding AND as html ?
I believe the problem is that your text-file is getting jumbled when you are reading it into a variable as non-utf8.
I would try getting the text file as UTF-8 and keeping the Encoding line.
Body = Get-Content "C:\body.txt" -Encoding UTF8 | Out-String
EDIT: Added Out-String per Dwza.