Выгружаем список писем из Outlook через PowerShell

SMTP. Тонкости

  1. Exchange Server подставляет в Receive: в качестве имени хоста - хост, переданный из HELO. Поэтому возможна подмена, когда Receive:srv.batabank.ru[123.123.123.123]. Где srv.batabank.ru не является PTR для ip
  2. Return-Path - поле в Internet Header в который принимающий сервер подставляет P1

Парсинг email адресов

'pavel.nagaev@itvideo.pro'.Split('@')[0]
([mailaddress] 'pavel.nagaev@itvideo.pro').User
'pavel.nagaev@itvideo.pro' -replace '@itvideo.pro',''    # ,'' при замене на пустое значение, запятую и пустое значение можно не указывать.

Отправка сообщений

Недостаток этого способа в том, что нельзя манипулировать заголовками письма, например нельзя добавить X-headers, а также smtp header берётся из NETBIOS имени компьютера.(см.ниже)

$parameters = @{
  From                       = 'from@bar.com'
  To                         = 'to@bar.com'
  Subject                    = 'Email Subject'
  Attachments                = @('C:\files\samplefile1.txt', 'C:\files\samplefile2.txt')
  BCC                        = 'bcc@bar.com'
  Body                       = 'Email body'
  BodyAsHTML                 = $False
  CC                         = 'cc@bar.com'
  Credential                 = Get-Credential
  DeliveryNotificationOption = 'onSuccess'
  Encoding                   = 'UTF8'
  Port                       = '25'
  Priority                   = 'High'
  SmtpServer                 = 'smtp.com'
  UseSSL                     = $True
}
Send-MailMessage @parameters

Класс MailMessage может манипулировать Internet Headers

   $Message.Headers.Add("X-My-Test-Header","SomeData")
if ($SendMail)
{
Show-ProgressBar -PercentComplete 95 -Status 'Sending mail message..' -Stage 4
 
  $smtpMail = New-Object Net.Mail.SmtpClient($MailServer) 
 
  $smtpMessage = New-Object System.Net.Mail.MailMessage $MailFrom, $MailTo
 
  if(Test-Path -Path $HtmlReportFullPath) {
    $smtpAttachment = New-Object Net.Mail.Attachment($HtmlReportFullPath, 'text/plain')
    $smtpMessage.Attachments.Add($smtpAttachment)
  }
 
  $smtpMessage.Subject = 'Exchange Environment Report'
  $smtpMessage.Body = $Output   
  $smtpMessage.IsBodyHtml = $true
 
  $smtpMail.Send($smtpMessage)
 
  Return 0
}

Если в коде будет

# P1 address

  $Message.From = New-Object System.Net.Mail.MailAddress ‘p1sender@domain.com’,’P1 Sender’

# P2 address

  $Message.Sender = New-Object System.Net.Mail.MailAddress ‘p2sender@domain.com’,’P2 Sender’

То в письме в поле отправителя

   P2 Sender <p2sender@domain.com> on behalf of P1 Sender <p1sender@domain.com>

В Internet header

 Sender: P2 Sender <p2sender@domain.com>
 From: P1 Sender <p1sender@domain.com>

В SMTP логе

 MAIL FROM:<p2sender@domain.com>,

Если пользователь в домене, то отправка у Send-MailMessage происходит от имени текущего пользователя. Чтобы отправлять анонимно, необходимо

$User = “anonymous”
$PWord = ConvertTo-SecureString –String “anonymous” –AsPlainText -Force
$Creds = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $user, $pword
Send-MailMessage -To recipient@domain.com -From sender@domain.com -Subject “Subject” -Body “Body” -SmtpServer “server” -Credentials $creds

FQDN with SmtpClient in Powershell

При отправке командлет использует в качестве Hostname NETBIOS имя компьютера. Чтобы отправлять от своего имени, необходимо в файл

#Для ISE
notepad C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe.config
#Для PowerShell
notepad C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe.config    

В раздел <configuration> добавить отдельной секцией строки

<system.net>
    <mailSettings>
      <smtp deliveryMethod="network">
        <network clientDomain="mail.example.com" />
      </smtp>
    </mailSettings>
</system.net>

Отправка с помощью Telnet

http://base64.ru

$subject = "Где купить розовую резиновую свинку?"
$subject ="=?utf-8?B?"+([Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($subject)))+"?="        
 
[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("текст"))
From: =?utf-8?B?0JLQvtCy0LAg0KHQuNC90LjQuSDQktC10YDQsdC70Y7QtA==?=<infoP2@batabank.ru>

В начало добавить =?utf-8?B?, а в конец ?=

$smtpServer = "myserver.mydomain.ru"
$port = 25
 
# Данные аутентификации
$username = "test@mydomain.ru"
$password = "your_password"
 
# Данные письма
$from = "sender@example.com"
$to = "recipient@mydomain.ru"
$subject = "Test Email"
$body = "This is a test email sent via Telnet commands."
 
# Кодирование имени пользователя и пароля в Base64
$encodedUsername = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($username))
#$encodedPassword = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($password))
$encodedPassword = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(""))
 
# Открытие подключения к SMTP-серверу через telnet
$tcpClient = New-Object System.Net.Sockets.TcpClient
$tcpClient.Connect($smtpServer, $port)
$stream = $tcpClient.GetStream()
$writer = New-Object System.IO.StreamWriter($stream)
$reader = New-Object System.IO.StreamReader($stream)
 
# Функция для чтения ответа от сервера
function Read-Response {
    $response = $reader.ReadLine()
    Write-Host "Server Response: $response"
    return $response
}
 
# Функция для отправки команды
function Send-Command {
    param ([string]$command)
    $writer.WriteLine($command)
    $writer.Flush()
    Write-Host "Sent: $command"
    Read-Response
}
 
# SMTP-диалог
Read-Response # Приветствие сервера
Send-Command "EHLO localhost"
Send-Command "AUTH LOGIN"
Send-Command $encodedUsername
Send-Command $encodedPassword
Send-Command "MAIL FROM:<$from>"
Send-Command "RCPT TO:<$to>"
Send-Command "DATA"
Send-Command "Subject: $subject`r`nFrom: <$from>`r`nTo: <$to>`r`n`r`n$body`r`n."
Send-Command "QUIT"
 
# Закрытие соединения
$writer.Close()
$reader.Close()
$stream.Close()
$tcpClient.Close()