update
This commit is contained in:
359
POP3/Source/FetchMail.ps1
Normal file
359
POP3/Source/FetchMail.ps1
Normal file
@ -0,0 +1,359 @@
|
||||
<#---------------------------------------------------------------------------
|
||||
Using POP3 in PowerShell
|
||||
|
||||
Dominik Deak <deak.software@gmail.com>, DEAK Software
|
||||
|
||||
This sample code demonstrates how to take advantage of .NET libraries in
|
||||
PowerShell to facilitate email communications without using an actual
|
||||
email client.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
Before using the demo code, the following tools and libraries are
|
||||
required:
|
||||
|
||||
* PowerShell 6: <https://github.com/PowerShell/PowerShell/releases>
|
||||
* OpenPOP.NET (SourceForge): <https://sourceforge.net/projects/hpop/files/>
|
||||
* OpenPOP.NET (NuGet): <https://www.nuget.org/packages/OpenPop.NET/>
|
||||
|
||||
Instructions:
|
||||
|
||||
1. Download the OpenPOP.NET library, either from SourceForge, or NuGet.
|
||||
|
||||
2. Extract OpenPop.dll binary file from the .zip package into the
|
||||
.\Binaries subdirectory.
|
||||
|
||||
3. Supply the incoming email server configuration below, including the
|
||||
credentials needed for authentication.
|
||||
|
||||
Supporting Resources:
|
||||
|
||||
* Article: <https://deaksoftware.com.au/articles/using_pop3_in_powershell/>
|
||||
* GitHub: <https://github.com/DEAKSoftware/Using-POP3-in-PowerShell/>
|
||||
|
||||
Legal and Copyright:
|
||||
|
||||
Released under the MIT License. Copyright 2018, DEAK Software.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
---------------------------------------------------------------------------#>
|
||||
|
||||
Write-Host "Using POP3 in PowerShell - Dominik Deak <deak.software@gmail.com>, DEAK Software" -ForegroundColor Yellow
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
Configuration data.
|
||||
---------------------------------------------------------------------------#>
|
||||
# Path configurations
|
||||
$openPopLibraryURL = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath( "..\Binaries\OpenPop.dll" )
|
||||
$tempBaseURL = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath( "..\Temp\" ) # Or use system temp dir via [System.IO.Path]::GetTempPath()
|
||||
$testMessageURL = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath( "..\Examples\Test-Message.eml" )
|
||||
|
||||
# Incoming email configuration used for fetching messages
|
||||
$incomingUsername = "QRCODE-59251"
|
||||
$incomingPassword = "F1ch0rg@PM$"
|
||||
$incomingServer = "10.101.10.2"
|
||||
$incomingPortPOP3 = 110 # Normally 110 (not secure), or 995 (SSL)
|
||||
$incomingEnableSSL = $false
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
Construct an POP3 client for the specified host name and credentials.
|
||||
---------------------------------------------------------------------------#>
|
||||
function makePOP3Client
|
||||
{
|
||||
Param
|
||||
(
|
||||
[string] $server,
|
||||
[int] $port,
|
||||
[bool] $enableSSL,
|
||||
[string] $username,
|
||||
[string] $password
|
||||
)
|
||||
|
||||
$pop3Client = New-Object OpenPop.Pop3.Pop3Client
|
||||
|
||||
$pop3Client.connect( $server, $port, $enableSSL )
|
||||
|
||||
if (!$pop3Client.connected)
|
||||
{
|
||||
throw "Unable to create POP3 client. Connection failed with server $server"
|
||||
}
|
||||
|
||||
$pop3Client.authenticate( $username, $password )
|
||||
|
||||
return $pop3Client
|
||||
}
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
Fetch $count messages from the POP3 server and list them in the console.
|
||||
---------------------------------------------------------------------------#>
|
||||
function fetchAndListMessages
|
||||
{
|
||||
Param
|
||||
(
|
||||
[OpenPop.Pop3.Pop3Client] $pop3Client,
|
||||
[int] $count
|
||||
)
|
||||
|
||||
$messageCount = $pop3Client.getMessageCount()
|
||||
|
||||
Write-Host "Messages available:" $messageCount
|
||||
|
||||
$messagesEnd = [math]::max( $messageCount - $count, 0 )
|
||||
|
||||
Write-Host "Fetching messages" $messageCount "to" ($messagesEnd + 1) "..."
|
||||
|
||||
for ( $messageIndex = $messageCount; $messageIndex -gt $messagesEnd; $messageIndex-- )
|
||||
{
|
||||
$incomingMessage = $pop3Client.getMessage( $messageIndex )
|
||||
|
||||
Write-Host "Message $messageIndex`:"
|
||||
Write-Host "`tFrom:" $incomingMessage.headers.from
|
||||
Write-Host "`tSubject:" $incomingMessage.headers.subject
|
||||
Write-Host "`tDate:" $incomingMessage.headers.dateSent
|
||||
}
|
||||
}
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
Save a single OpenPop.Mime.Message message class to the specified URL.
|
||||
---------------------------------------------------------------------------#>
|
||||
function saveMessage
|
||||
{
|
||||
Param
|
||||
(
|
||||
[OpenPop.Mime.Message] $incomingMessage,
|
||||
[string] $outURL
|
||||
)
|
||||
|
||||
New-Item -Path $outURL -ItemType "File" -Force | Out-Null
|
||||
|
||||
$outStream = New-Object IO.FileStream $outURL, "Create"
|
||||
|
||||
$incomingMessage.save( $outStream )
|
||||
|
||||
$outStream.close()
|
||||
}
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
Fetch $count messages from the POP3 server and save them to the specified
|
||||
$tempURL.
|
||||
---------------------------------------------------------------------------#>
|
||||
function fetchAndSaveMessages
|
||||
{
|
||||
Param
|
||||
(
|
||||
[OpenPop.Pop3.Pop3Client] $pop3Client,
|
||||
[int] $count,
|
||||
[string] $tempURL
|
||||
)
|
||||
|
||||
$messageCount = $pop3Client.getMessageCount()
|
||||
|
||||
Write-Host "Messages available:" $messageCount
|
||||
|
||||
$messagesEnd = [math]::max( $messageCount - $count, 0 )
|
||||
|
||||
Write-Host "Saving messages" $messageCount "to" ($messagesEnd + 1) "..."
|
||||
|
||||
for ( $messageIndex = $messageCount; $messageIndex -gt $messagesEnd; $messageIndex-- )
|
||||
{
|
||||
$uid = $pop3Client.getMessageUid( $messageIndex )
|
||||
|
||||
$emailURL = Join-Path -Path $tempURL -ChildPath ($uid + ".eml")
|
||||
|
||||
Write-Host "Saving message $messageIndex to:" $emailURL
|
||||
|
||||
$incomingMessage = $pop3Client.getMessage( $messageIndex )
|
||||
|
||||
saveMessage $incomingMessage $emailURL
|
||||
|
||||
DeleteMessage $incomingMessage $pop3Client
|
||||
}
|
||||
}
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
|
||||
---------------------------------------------------------------------------#>
|
||||
function DeleteMessage
|
||||
{
|
||||
Param
|
||||
(
|
||||
[OpenPop.Mime.Message] $incomingMessage,
|
||||
[OpenPop.Pop3.Pop3Client] $pop3Client
|
||||
#[string] $outURL
|
||||
)
|
||||
Write-Host "Delete message $messageIndex "
|
||||
$messageDelete = $pop3Client.DeleteMessage($messageIndex)
|
||||
|
||||
}
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
Save an attachment to the specified URL.
|
||||
---------------------------------------------------------------------------#>
|
||||
function saveAttachment
|
||||
{
|
||||
Param
|
||||
(
|
||||
[System.Net.Mail.Attachment] $attachment,
|
||||
[string] $outURL
|
||||
)
|
||||
|
||||
New-Item -Path $outURL -ItemType "File" -Force | Out-Null
|
||||
|
||||
$outStream = New-Object IO.FileStream $outURL, "Create"
|
||||
|
||||
$attachment.contentStream.copyTo( $outStream )
|
||||
|
||||
$outStream.close()
|
||||
}
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
Fetch $count messages from the POP3 server and save their attachments to
|
||||
the specified $tempURL.
|
||||
---------------------------------------------------------------------------#>
|
||||
function fetchAndSaveAttachments
|
||||
{
|
||||
Param
|
||||
(
|
||||
[OpenPop.Pop3.Pop3Client] $pop3Client,
|
||||
[int] $count,
|
||||
[string] $tempURL
|
||||
)
|
||||
|
||||
$messageCount = $pop3Client.getMessageCount()
|
||||
|
||||
Write-Host "Messages available:" $messageCount
|
||||
|
||||
$messagesEnd = [math]::max( $messageCount - $count, 0 )
|
||||
|
||||
Write-Host "Saving attachments for messages" $messageCount "to" ($messagesEnd + 1) "..."
|
||||
|
||||
for ( $messageIndex = $messageCount; $messageIndex -gt $messagesEnd; $messageIndex-- )
|
||||
{
|
||||
$uid = $pop3Client.getMessageUid( $messageIndex )
|
||||
|
||||
$incomingMessage = $pop3Client.getMessage( $messageIndex ).toMailMessage()
|
||||
|
||||
Write-Host "Processing message $messageIndex..."
|
||||
|
||||
foreach ( $attachment in $incomingMessage.attachments )
|
||||
{
|
||||
$attachmentURL = Join-Path -Path $tempURL -ChildPath $uid | Join-Path -ChildPath $attachment.name
|
||||
|
||||
Write-Host "`tSaving attachment to:" $attachmentURL
|
||||
|
||||
saveAttachment $attachment $attachmentURL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
Load a single OpenPop.Mime.Message message from the specified URL.
|
||||
---------------------------------------------------------------------------#>
|
||||
function loadMessage
|
||||
{
|
||||
Param ( [string] $inURL )
|
||||
|
||||
$inStream = New-Object IO.FileStream $inURL, "Open"
|
||||
|
||||
$message = [OpenPop.Mime.Message]::load( $inStream )
|
||||
|
||||
$inStream.close()
|
||||
|
||||
return $message
|
||||
}
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
Load the message from the specified URL, convert it to a
|
||||
System.Net.Mail.MailMessage object, then display its contents in the
|
||||
console.
|
||||
|
||||
Note: The System.Net.Mail.MailMessage object can be sent via SMTP using
|
||||
the System.Net.Mail.SmtpClient class. See .NET Frameworks documentation
|
||||
for details.
|
||||
---------------------------------------------------------------------------#>
|
||||
function loadAndListMessage
|
||||
{
|
||||
Param ( [string] $inURL )
|
||||
|
||||
Write-Host "`Loading message from:" $inURL
|
||||
|
||||
$message = (loadMessage $inURL).toMailMessage()
|
||||
|
||||
Write-Host "`tFrom:" $message.from
|
||||
Write-Host "`tTo:" $message.to
|
||||
|
||||
if ($message.cc)
|
||||
{
|
||||
Write-Host "`tCC:" $message.cc
|
||||
}
|
||||
|
||||
if ($message.bcc)
|
||||
{
|
||||
Write-Host "`tBCC:" $message.bcc
|
||||
}
|
||||
|
||||
if ($message.replyToList)
|
||||
{
|
||||
Write-Host "`tReply To:" $message.replyToList
|
||||
}
|
||||
|
||||
if ($message.subject)
|
||||
{
|
||||
Write-Host "`tSubject:" $message.subject
|
||||
}
|
||||
|
||||
if ($message.body)
|
||||
{
|
||||
Write-Host "`tBody:" $message.body
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<#---------------------------------------------------------------------------
|
||||
Run the demo.
|
||||
---------------------------------------------------------------------------#>
|
||||
[Reflection.Assembly]::LoadFile( $openPopLibraryURL )
|
||||
|
||||
try {
|
||||
Write-Host "Connecting to POP3 server: $incomingServer`:$incomingPortPOP3"
|
||||
|
||||
$pop3Client = makePOP3Client `
|
||||
$incomingServer $incomingPortPOP3 $incomingEnableSSL `
|
||||
$incomingUsername $incomingPassword
|
||||
|
||||
Remove-Variable -Name incomingPassword
|
||||
|
||||
fetchAndListMessages $pop3Client 10
|
||||
fetchAndSaveMessages $pop3Client 10 $tempBaseURL
|
||||
fetchAndSaveAttachments $pop3Client 10 $tempBaseURL
|
||||
loadAndListMessage $testMessageURL
|
||||
|
||||
Write-Host "Disconnecting from POP3 server: $incomingServer`:$incomingPortPOP3"
|
||||
|
||||
if ($pop3Client.connected)
|
||||
{
|
||||
$pop3Client.disconnect()
|
||||
}
|
||||
|
||||
$pop3Client.dispose()
|
||||
|
||||
Remove-Variable -Name pop3Client
|
||||
}
|
||||
|
||||
catch { Write-Error "Caught exception:`n`t$PSItem" }
|
Reference in New Issue
Block a user