{"id":54533,"date":"2009-01-26T21:00:00","date_gmt":"2009-01-26T21:00:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2009\/01\/26\/hey-scripting-guy-how-do-i-use-windows-powershell-to-work-with-junk-e-mail-in-office-outlook\/"},"modified":"2009-01-26T21:00:00","modified_gmt":"2009-01-26T21:00:00","slug":"hey-scripting-guy-how-do-i-use-windows-powershell-to-work-with-junk-e-mail-in-office-outlook","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-do-i-use-windows-powershell-to-work-with-junk-e-mail-in-office-outlook\/","title":{"rendered":"Hey, Scripting Guy! How Do I Use Windows PowerShell to Work with Junk E-Mail in Office Outlook?"},"content":{"rendered":"<h2><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"> <\/h2>\n<p>Hey, Scripting Guy! I need to find out how many e-mail messages are in my Junk folder. I found <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/oct06\/hey1024.mspx\" target=\"_blank\">a script<\/a> that does this with VBScript, but I need to be able to do it in Windows PowerShell. I do not want to delete the junk e-mail, because there are times when it is not junk. But because Office Outlook automatically moves e-mail to the Junk folder, users are often not aware they could have a considerable number of messages marked as junk. Can you help me?<\/p>\n<p>&#8211; EC<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\"><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\"><\/p>\n<p>Hi EC,<\/p>\n<p>It is Monday morning, and I have just finished answering all the <b>scripter@microsoft.com<\/b> e-mail messages (about 65 e-mail messages just this morning) and nearly a dozen of them were dealing with Office Outlook. Yours caught my eye. You know, I am glad you have been trolling around in the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/all.mspx\" target=\"_blank\">&#8220;Hey, Scripting Guy!&#8221; archives<\/a>. It makes me feel that what I write will not end up in the bottom of virtual parrot cages. The good thing about scripting Office Outlook is that the object model is basically the same whether you are using Windows PowerShell or VBScript. This means that ideas you find in VBScript can be easily translated to Windows PowerShell, and vice versa.<\/p>\n<table class=\"dataTable\" id=\"EDD\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td class=\"\">\n<p>This week we are looking at scripting Office Outlook. Interestingly enough, the Office Outlook object model is not as rich as you might suspect. Certainly Office Word and Office Excel have far more capability for automation than Office Outlook. This having been said, a basic familiarity with Office Outlook automation can lend rich results for the enterprising network administrator, consultant, or power user. <\/p>\n<p>If you are interested in VBScript examples of working with Office Outlook, start with the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/all.mspx\" target=\"_blank\">&#8220;Hey, Scripting Guy!&#8221; archive<\/a>, and then move on to the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/officetips\/archive.mspx\" target=\"_blank\">Office Space archive<\/a>. Finally, you would probably like to see some examples of scripts for automating Office Outlook. You are in luck here because we have dozens of well-written scripts in the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/all.mspx\" target=\"_blank\">Community-Submitted Scripts Center<\/a>. Read on, this is going to be a cool week. If you need help with Windows PowerShell, you can find download links and getting started information in the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\" target=\"_blank\">Windows PowerShell technology hub<\/a>.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>If you want to find out how many e-mail messages you have in the Junk folder of Office Outlook, you can use the <b>CountItemsInJunkFolder.ps1<\/b> script. (Amazing that such a cool script has such a short name. Like I said, it is Monday morning. I&#8217;m on my second pot of English Breakfast tea. Don&#8217;t worry though; I wrote the script last Friday.)<\/p>\n<p><b>CountItemsInJunkFolder.ps1<\/b><\/p>\n<pre class=\"codeSample\">[Reflection.Assembly]::LoadWithPartialname(\"Microsoft.Office.Interop.Outlook\") |\nout-null\n$olFolders = \"Microsoft.Office.Interop.Outlook.OlDefaultFolders\" -as [type]\n$outlook = new-object -comobject outlook.application\n$namespace = $outlook.GetNameSpace(\"MAPI\")\n$folder = $namespace.getDefaultFolder($olFolders::olFolderJunk)\n$folder.items.count\n<\/pre>\n<p>The&nbsp;first thing we want to do is to load the <b>Microsoft.Office.Interop.Outlook<\/b> assembly. (Dude, why do we want to do that? I mean, it is Monday after all.) We do not really <i>need to<\/i> load the <b>Microsoft.Office.Interop.Outlook<\/b> assembly, but doing so will give us a nice advantage, and it is simply cool that we can do such a thing. In VBScript, one of the hardest things to find was what was called enumeration values. These things are the magic numbers. You would find them casually sneaking around near the beginning of various VBScripts. Many of the e-mail messages we receive include some variation of the question, &#8220;Where did you find that number?&#8221; Enumeration values are constants that are created by the developers who wrote the application. In other programming languages, you would set a reference to a particular library, and voila you have access to the enumeration constants. Knowing these constant values is often the key to understanding the code samples we see on MSDN. VBScript does not have access to these enumerations, so a common practice\u2014indeed a best practice\u2014is to create a constant with the name of the enumeration and set its value to the value you discovered via MSDN. The problem with this approach is that at times it can be a major pain (or sometimes even a 5-star general pain) to identify the numeric equivalent of an enumeration. Here is an example from the VBScript you referred to in your e-mail of setting the Office Outlook Junk folder enumeration:<\/p>\n<pre class=\"codeSample\">Const olFolderJunk = 23<\/pre>\n<p>Did you ever wonder why we Microsoft Scripting Guys created such stupid looking constant names? I mean, jeez, if we go to the trouble of creating a constant, couldn&#8217;t we at least give it something easy to type like <b>JunkFolder<\/b> or simply <b>Junk<\/b>? The reason we use these constant names is they are the actual enumeration names. This is good news. You can search MSDN for <b>olFolderJunk<\/b> and come up with the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb208072.aspx\" target=\"_blank\">olDefaultFolders enumeration<\/a> (number one hit on Live.com). You might not have known that was the enumeration name, but it is easily discoverable via a quick MSDN search.<\/p>\n<p>To load the <b>Microsoft.Office.Interop.Outlook<\/b> interop assembly, we need to use the static <b>LoadWithPartialName<\/b> method from the <b>Reflection.Assembly<\/b> .NET Framework class. Static methods are methods that are always available and are called in Windows PowerShell by using double colons instead of the normal period. When loading the <b>Microsoft.Office.Interop.Outlook<\/b> assembly, it produces feedback that tells you the assembly has been loaded. This is seen here:<\/p>\n<pre class=\"codeSample\">PS C:\\&gt; [Reflection.Assembly]::LoadWithPartialname(\"Microsoft.Office.Interop.Out\nlook\")\nGAC    Version        Location\n---    -------        --------\nTrue   v1.1.4322      C:\\Windows\\assembly\\GAC\\Microsoft.Office.Interop.Outlo...\n<\/pre>\n<p>To avoid that distraction, we pipeline the results to the <b>Out-Null<\/b> cmdlet:<\/p>\n<pre class=\"codeSample\">[Reflection.Assembly]::LoadWithPartialname(\"Microsoft.Office.Interop.Outlook\") |\nout-null\n<\/pre>\n<p>After we have loaded the assembly, we have access to the enumerations. We can even peruse the enumeration names by using the static method <b>GetNames<\/b> from the [enum] .NET Framework&nbsp;class:<\/p>\n<pre class=\"codeSample\">PS C:\\&gt; [enum]::GetNames(\"Microsoft.Office.Interop.Outlook.OlDefaultFolders\")\nolFolderDeletedItems\nolFolderOutbox\nolFolderSentMail\nolFolderInbox\nolFolderCalendar\nolFolderContacts\nolFolderJournal\nolFolderNotes\nolFolderTasks\nolFolderDrafts\nolPublicFoldersAllPublicFolders\nolFolderConflicts\nolFolderSyncIssues\nolFolderLocalFailures\nolFolderServerFailures\nolFolderJunk\nolFolderRssFeeds\nolFolderToDo\nolFolderManagedEmail\n<\/pre>\n<p>We want to have access to the enumerations. To do this, we use the as operator to cast the string &#8220;Microsoft.Office.Interop.Outlook.OlDefaultFolders&#8221; into a type. This is a very powerful technique and is seen here:<\/p>\n<pre class=\"codeSample\">$olFolders = \"Microsoft.Office.Interop.Outlook.OlDefaultFolders\" -as [type] <\/pre>\n<p>We did not need to do all that work, but by doing so we are taking advantage of one of the great aspects of Windows PowerShell. In many cases, when you are unable to find out the value of an enumeration, remembering these techniques can save many hours of frustration.<\/p>\n<p>Now we want to create an instance of the <b>Outlook.Application<\/b> object. This is the main object we use when automating Office Outlook. There is documentation on MSDN for each version of Office Outlook. I am using <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb176630.aspx\" target=\"_blank\">documentation for Office Outlook 2007<\/a> because it absolutely rocks and works so much better on my laptop than previous versions. For this script, there are no differences between the Office Outlook 2007 object model and previous versions. But as a best practice and to avoid frustration, you should always consult the version of the documentation that applies to your specific version of Office Outlook. <\/p>\n<p>The <b>Outlook.Application<\/b> object is a COM object, and we use the <b>comobject<\/b> parameter with the <b>New-Object<\/b> cmdlet. We store the returned instance of the object in the <b>$outlook<\/b> variable:<\/p>\n<pre class=\"codeSample\">$outlook = new-object -comobject outlook.application<\/pre>\n<p>We can use the <b>GetNameSpace<\/b> object after we have created an instance of the application object. The <b>GetNameSpace<\/b> takes a single argument, which is the name of the namespace to connect to. There is only one allowed value for this\u2014MAPI. This is <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb219904.aspx\" target=\"_blank\">documented on MSDN<\/a>. The command is shown here:<\/p>\n<pre class=\"codeSample\">$namespace = $outlook.GetNameSpace(\"MAPI\")<\/pre>\n<p>After we have created our <b>Namespace<\/b> object, we use the <b>GetDefaultFolder<\/b> method to connect to the Junk folder in Office Outlook. The <b>Namespace<\/b> object is <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb219955.aspx\" target=\"_blank\">documented on MSDN<\/a>. We store the returned folder object in the <b>$folder<\/b> variable:<\/p>\n<pre class=\"codeSample\">$folder = $namespace.getDefaultFolder($olFolders::olFolderJunk)<\/pre>\n<p>We now need to count the number of items that are in the Junk folder. To do this, we use the <b>count<\/b> property: <\/p>\n<pre class=\"codeSample\">$folder.items.count<\/pre>\n<p>The output from the script will simply display the number of items in the Junk folder. We did not even bother to add any verbiage to the output, but you can easily do that if you wish.<\/p>\n<p>Well, EC, that is it for today&#8217;s script. Sorry for the lack of pretty pictures today. I did think about using a picture of a parrot fish I took while I was scuba diving in Aruba, but like I said it is Monday and it is cold here in Charlotte, North Carolina, USA. I am going to go grab a bowl of chili the Scripting Wife made and play around some more with scripting Office Outlook. See you tomorrow. Stay warm.<\/p>\n<p>&nbsp;<\/p>\n<p><b>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I need to find out how many e-mail messages are in my Junk folder. I found a script that does this with VBScript, but I need to be able to do it in Windows PowerShell. I do not want to delete the junk e-mail, because there are times when it is not [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[212,49,3,45],"class_list":["post-54533","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-microsoft-outlook","tag-office","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I need to find out how many e-mail messages are in my Junk folder. I found a script that does this with VBScript, but I need to be able to do it in Windows PowerShell. I do not want to delete the junk e-mail, because there are times when it is not [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=54533"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54533\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=54533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=54533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=54533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}