Saturday, November 12, 2011

Check Gmail inbox via Windows 7 PowerShell

Gmail offers comfortable way to get the unread messages. I decided to play with it and at the same time to show some of the Windows PowerShell possibilities. Check out the part 2 here

Google provides a simple way to fetch inbox messages like an rss-feed. The idea is simple: Google provides the url that can be accessed by authorized user. Here it is:
You can try it right now if you are authorized in Gmail account, otherwise you may type your credentials in popup window, or paste this url in web-browser's address field with yours account login and password: (does not work in IE)
And you will see rss-feed with unread messages (if there are any unread).
This rss has the following nodes structure:
<feed> - root node for rss feed
.<title> - feed title
.<tagline> - tagline
.<fullcount> - new messages count
.<link> - link to Google mail
.<modified> - feed modified date
.<entry> - root node for a single inbox message
..<title> - message title
..<summary> - message summary
..<link> - link to Gmail account
..<modified> - message modified date
..<issued> - message issued date
..<id> - message id
..<author> - sender
...<name> - sender name
...<email> - sender email
Sure, you can use this url in your rss-reader, but I find this way rather boring.
Let's fetch, parse and display this rss using Windows 7 PowerShell.
Hit the run button and type "powershell" into the search field. Here it is. Now let's do some code. I decided to use webclient to load rss-feed:
$webclient = new-object System.Net.WebClient
And now we need to pass to the webclient Gmail account login and password in order to access the rss-feed:
$webclient.Credentials = new-object System.Net.NetworkCredential ("login", "password")
Now download the rss as xml:
[xml]$xml= $webclient.DownloadString("")
The rss is loaded, now we need to display it in proper form. I decided to display only sender name and message title as custom table:
$format= @{Expression={$_.title};Label="Title"},@{Expression={$};Label="Author"}
This format string defines, that only two xml nodes (title and author) will be displayed as table columns, and the column names will be “Title” and “Author”. And now let's display the table:
$xml.feed.entry | format-table $format
Let's sum up the whole script. It will be like this:
$webclient = new-object System.Net.WebClient
$webclient.Credentials = new-object System.Net.NetworkCredential ("login", "password")
[xml]$xml= $webclient.DownloadString("")
$format= @{Expression={$_.title};Label="Title"},@{Expression={$};Label="Author"}
$xml.feed.entry | format-table $format
You can either type this line by line in PowerShell or copy-paste the script.
Here is what I get using test Gmail account:

Let's make the usage of the script more comfy: create new text file, paste script into it and rename the file for example as "checkgmail.ps1".
Now go to PowerShell and navigate to the script containing folder. In my case it was "d:\work\test" so I typed "cd d:\work\test\" and then ".\checkgmail.ps1" to execute script.
At this point, if you run PowerShell script first time in your life :), you will probably see the message that your script can not be loaded.
This is default security setting in PowerShell. To enable script execution type the following command in your PowerShell console:
set-executionPolicy RemoteSigned
This command allows you to run local scripts while remote scripts still will require digital signing. One more thing you might find useful is to pass your credentials as command line arguments. Let's change the line with credentials initialization as following:
$webclient.Credentials = new-object System.Net.NetworkCredential ($args[0], $args[1])
Save the script and run it. This time with 2 arguments:
.\checkgmail.ps1 login password
It is all for now. I hope you enjoyed this article. Feel free to comment or ask any questions. Good luck.


  1. Hello,

    Very usefull script, thanks
    How can I use this script to compare the id(in a file check.txt) checking if it is a new email and then send a sms through
    And after that outputs $format to the file >> check.txt

    Warm regards

    1. If i understand the question correctly you want to:
      1) get id from file check.txt
      2) compare it to $
      3) if the comparision is false (or true?) - add, for example, $xml.feed.entry.summary as a parameter to url

      You can try to do it this way:

      $id = Get-Content C:\check.txt
      if ($id -eq $ /* compare id from file and mail id */
      $webClient = New-Object net.webclient

      This is quick and dirty solution and i didn't tested it, but i hope it will give you some sort of idea, how to solve the problem. :)

    2. Hey Thanks alot, this was really helpful.
      Does this script work only on windows 7 Powershell, will it work on Windows XP Powershell??

      I have one more question, Is there any way to read the content of an e-mail here?

      Thanks alot!

    3. I don't know if this works on XP, but you can give it a try :)

      Nope, in this case you can't read the e-mail body.

  2. Hey,

    Hey Denis,

    Thanks for this intro on how to manage gmail from PS.
    I am looking to go further, but I think I will need your help ;)

    What I am looking to do is the following:
    - create a directory with time stamp
    - filter emails with object = "specific text"
    - get the content of the emails filtered and pipe it in word file with a separator between emails (line) and author name and date described at the top of the content of the email. It would be awesome if it could also download the attached file with a time stamp name.

    I know how to do step 1.
    However I don t know how to play around with content of the emails and pipe it out on other app.

    Is it possible to get this ?

    1. You can't get email body using google rss. In this situation, you have to connect to the mail box via pop or smtp and fetch messages. In theory it is possible using powershell, since you can execute c# code there and load assemblies. For example, you can try to use 3rd party imap library, load it in powershell and try to fetch messages. I promise i'll try it later and tell you the results :)

    2. Hey, Benoit
      I hope i've answered your question here

  3. Shouldn't work with 2-Factor authentication