I'm trying to develop a small script that sends the output of a tree of a certain directory, and I'm having problems with the presentation of the mail; The script already sends the info, but not in the way that I would like. My code is as follows:
# from to info
$MailFrom = ""
$MailTo = ""
# Credentials
$Username = "user"
$Password = "password"
# Server Info
$SmtpServer = "server"
$SmtpPort = "port"
# Menssage
$MessageSubject = "test"
$Message = New-Object System.Net.Mail.MailMessage $MailFrom,$MailTo
$Message.IsBodyHTML = $false
$Message.Subject = $MessageSubject
$Message.Body = tree /F directoryroute
# SMTP Client object
$Smtp = New-Object Net.Mail.SmtpClient($SmtpServer,$SmtpPort)
$Smtp.EnableSsl = $true
$Smtp.Credentials = New-Object System.Net.NetworkCredential($Username,$Password)
$Smtp.Send($Message)
So, the thing is that the mail shows the info like this:
When in fact, I want to see the following:
I am using power shell ISE and the tree is also different there:
What am I missing?
Thank you in advance!
CodePudding user response:
It sounds like you need to set the .BodyEncoding
property to a character encoding that can represent the box-drawing characters that the tree.com
utility uses for visualization, preferably UTF-8:
$Message.BodyEncoding = [Text.UTF8Encoding]::new()
Additionally, since the .Body
property is a single string ([string]
), whereas the lines output by tree.com
are captured in an array by PowerShell, you need to create a multi-line string representation yourself:[1]
$Message.Body = tree /F directoryroute | Out-String
If you neglect to do that, PowerShell implicitly stringifies the array, which means joining the array elements on a single line with spaces, which results in what you saw.
As for the PowerShell ISE:
It misinterprets output from external programs such as tree.com
, because it uses the system's ANSI code page by default for decoding, whereas most external programs use the OEM code page.
The ISE has other limitations, summarized in the bottom section of this answer, is no longer actively developed and notably cannot run the modern, cross-platform PowerShell edition, PowerShell (Core) 7 .
Consider migrating to Visual Studio Code with its PowerShell extension, which is an actively developed, cross-platform editor that offers the best PowerShell development experience.
In case you do want to make tree.com
work in the ISE, run the following:
[Console]::OutputEncoding =
Text.Encoding]::GetEncoding([cultureinfo]::CurrentCulture.TextInfo.OEMCodePage)
[1] While using Out-String
is convenient, it always appends a trailing newline to its output - see GitHub issue #14444. If you need to avoid that, use (tree /F directoryroute) -join [Environment]::NewLine
instead.