我似乎在这里用措辞不清楚的措辞来表达我的问题:
如何在Powershell中编写脚本代码,该脚本检查第三方imap帐户是否存在未读邮件。 记住的帐户使用具有用户/密码授权的TSL。
答案 0 :(得分:1)
IMAP不是一个复杂的协议,它是基于行的,并且相关命令的数量是有限的,特别是如果您只想检查收件箱中的未读邮件,则更是如此。
因此,在System.Net.Sockets.TcpClient
之上构建IMAP客户端非常简单。 SSL / TLS有点复杂,但还算不错。
与IMAP服务器的对话如下:
Client: A001 command argument argument Server: * response line 1 * response line 2 A001 OK response line 3
其中A001
是命令标签,用于标识命令。通常,它采用递增计数器的形式(a1
,a2
,a3
等),但实际上可以是任何东西。服务器在其响应的最后一行重复命令标签。
与GMail IMAP服务器的示例对话(显然,身份验证失败):
* OK Gimap ready for requests from 213.61.242.253 g189mb36880374lfe
a1 CAPABILITY
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH
a1 OK Thats all she wrote! g189mb36880374lfe
a2 LOGIN test test
a2 NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)
a3 LOGOUT
* BYE Logout Requested g189mb36880374lfe
a3 OK Quoth the raven, nevermore... g189mb36880374lfe
执行此操作的Powershell代码不太复杂:
using namespace System.IO;
using namespace System.Text;
using namespace System.Net.Sockets;
using namespace System.Net.Security;
using namespace System.Security.Cryptography.X509Certificates;
Set-StrictMode -Version 2.0
$DebugPreference = "Continue" # set to "SilentlyContinue" to hide Write-Debug output
$CRLF = "`r`n"
$server = "imap.gmail.com"
$port = 993
$username = "test"
$password = "test"
# connect to server
$client = [TcpClient]::new($server, $port)
$client.ReceiveTimeout = 2000 #milliseconds
# set up SSL stream, be lenient about the server's certificate
$acceptAnyCertificate = [RemoteCertificateValidationCallback] { $true }
$sslStream = [SslStream]::new($client.GetStream(), $false, $acceptAnyCertificate)
$sslStream.AuthenticateAsClient($server)
function StreamWrite {
param([Stream]$stream, [string]$command, [Encoding]$enc = [Encoding]::ASCII)
$data = $enc.GetBytes($command)
Write-Debug "> $($command.trim())"
$stream.Write($data, 0, $data.Length)
}
function StreamRead {
param([Stream]$stream, [int]$bufsize = 4*1KB, [Encoding]$enc = [Encoding]::ASCII)
$buffer = [byte[]]::new($bufsize)
$bytecount = $stream.Read($buffer, 0, $bufsize)
$response = $enc.GetString($buffer, 0, $bytecount)
Write-Debug "< $($response.trim())"
$response
}
# read server hello
$response = StreamRead $sslStream
StreamWrite $sslStream ("a1 CAPABILITY" + $CRLF)
$response = StreamRead $sslStream
# log in
StreamWrite $sslStream ("a2 LOGIN $username $password" + $CRLF)
$response = StreamRead $sslStream
# send mailbox commands...
# log out
StreamWrite $sslStream ("a3 LOGOUT" + $CRLF)
$response = StreamRead $sslStream
$sslStream.Close()
$client.Close()
您的邮箱命令可能是一个简单的select inbox
,服务器会向其回复一堆信息,包括看不见的电子邮件数量(an example can be seen on the Wikipedia):
C: a002 select inbox S: * 18 EXISTS S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) S: * 2 RECENT S: * OK [UNSEEN 17] Message 17 is the first unseen message S: * OK [UIDVALIDITY 3857529045] UIDs valid S: a002 OK [READ-WRITE] SELECT completed
您可能需要对邮件服务器进行一些试验,但是应该很容易弄清楚必要的细节。
如果您的服务器需要这样做,请阅读Connecting to smtp.live.com with the TcpClient class来了解如何执行STARTTLS
而不是SSL
。