Home > OS >  Send tree from a directory via SMTP through powershell
Send tree from a directory via SMTP through powershell

Time:08-09

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: picture 1

When in fact, I want to see the following: Picture 2

I am using power shell ISE and the tree is also different there: Picture 3

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.

  • Related