Thursday, January 26, 2012

Powershell (v2) - Read Gmail (More Proof of Concept than Anything)

After reading through some forums and seeing someone have trouble with their gmail, but, no client to control the data I got curious.  My research suggested there were lost of posts on how to use Powershell to send through gmail, but, not necessarily to read.  A quick hunt for some C# led me to this ASP.NET snippet:
ASP.net Read Email
After scanning the code quickly I figured this could be ported into Powershell with little effort.  Although I had some initial issues due to a misconfiguration (I put an smtp address in one spot where I needed  pop address) it worked when I was done...to some extent.  I still had trouble filtering out email strings, so, I hit the Technet board.  As always mjolinor was the man with a regex to help me track down precisely what I needed:
Harvesting "from" addresses from my gmail account
Using what is listed below, I can pull email.  But, what I don't fully understand is how, when I get email, it is often different, and, in no obvious order.  Since this was really a proof of concept type post I haven't had much time to research the POP RFC.  Nonetheless, I thought I would throw it out there for more talented souls than myself to save them the work.  So, the next time you're lost on a desert island with perfect wifi, a laptop and an instance of Powershell...you can still check your email.  How cool is that?
Clear-Host

try {
Write-Output "Creating new TcpClient."
$tcpClient = New-Object -TypeName System.Net.Sockets.TcpClient

# Connect to gmail
$tcpClient.Connect("pop.gmail.com", 995)

if($tcpClient.Connected) {
Write-Output "You are connected to the host. Attempting to get SSL stream."

# Create new SSL Stream for tcpClient
Write-Output "Getting SSL stream."
[System.Net.Security.SslStream] $sslStream = $tcpClient.GetStream()

# Authenticating as client
Write-Output "Authenticating as client."
$sslStream.AuthenticateAsClient("pop.gmail.com");

if($sslStream.IsAuthenticated) {
Write-Output "You have authenticated. Attempting to login."
# Asssigned the writer to stream
[System.IO.StreamWriter] $sw = $sslstream

# Assigned reader to stream
[System.IO.StreamReader] $reader = $sslstream

# refer POP rfc command, there very few around 6-9 command
$sw.WriteLine('USER myemail@gmail.com')

# sent to server
$sw.Flush()

# send pass
$sw.WriteLine('PASS JollyRodgersH@dACabin');
$sw.Flush()

# this will retrive your first email
$sw.WriteLine("RETR 1")
$sw.Flush()

$sw.WriteLine("Quit ");
$sw.Flush();

[String] $str = [String]::Empty
[String] $strTemp = [String]::Empty

while (($strTemp = $reader.ReadLine()) -ne $null) {
# find the . character in line
if($strTemp -eq '.') {
break;
}

if ($strTemp.IndexOf('-ERR') -ne -1) {
break;
}

$str += $strTemp;
}

# Return raw data
Write-Output "`nOutput email"
$str -match 'From:(.+?)?<(.+?)?>.' | Out-Null
} else {
Write-Error "You were not authenticated. Quitting."
}

} else {
Write-Error "You are not connected to the host. Quitting"
}
}

catch {
$_
}

finally {
Write-Output "Script complete. Here are your from addresses."
$Matches[2]
}

0 comments:

Post a Comment