PowerShell/VBScript - Extract Outlook Mails Based on Condition - powershell

Is there a way to obtain list of all sent & received emails having suffix not equal to #gmail.com via PowerShell or VBScript and possibly store it in seperate text files.
Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null
$olFolders = "Microsoft.Office.Interop.Outlook.olDefaultFolders" -as [type]
$outlook = new-object -comobject outlook.application
$namespace = $outlook.GetNameSpace("MAPI")
$folder = $namespace.getDefaultFolder($olFolders::olFolderSentMail)
$folder.items | Select-Object -Property Subject, SentOn, To
I was using the above PS to obtain sent mail, but not sure where to apply the condition.
Secondly, the subject is not appearing completely, it becomes ..... is there any way to obtain the full subject as well ?

I'm assuming you're running on a client computer not a server. If you've access to the exchange server there's powershell commandlets that are easy to use (New-MailboxExport).
$folder is a COM-Object
$folder.items property contains a collection of COM-Objects representing messages.
Since they're objects, you can use the object commands (Get-Help Object) to use their properties. You just need to dig a little more to apply your filter. Specifically one more level, to the properties of the items in $folder.items. Pipe $folder.items to Get-Member to get the full list of properties. $folder.items | gm. To, From, SentOn and Subject are all there.
$NonGmailMessages = $folder.items |
where-object { { $_.to -notcontains "gmail.com" } -and
{ $_.from -notcontains "gmail.com" } }
One way of handling collections like this is to do one massive filter like I just did. Or you can filter by stages.
$NonGmailMessages = $folder.items
$NonGmailMessages = $NonGmailMessages | where-object { { $_.to -notcontains "gmail.com" }
$NonGmailMessages = $NonGmailMessages | where-object { { $_.from -notcontains "gmail.com" }
Add further lines to further narrow your collection.
You can export this collection complete with all properties intact to a CSV:
$NonGmailMessages | Export-CSV -NoTypeInformation c:\temp\nonGmailMessages.csv
Or you can narrow the number of properties exported
$NonGmailMessages | Select-Object -Property From, To, SentOn, Subject | Export-CSV -NoTypeInformation c:\temp\nonGmailMessages.csv
-NoTypeInformation prevents the object type information from being listed at the start of the file. This will make it a more 'pure' CSV for use in PS or Excel or whatever. Plus the CSV IS a text based file format, as you wished.

Related

Get email addresses from all Folders of my mailbox through powershell

How to get Email Addresses from All Folders of my mailbox through PowerShell
Thanks to following URL, please find code for InBox
https://stackoverflow.com/questions/44068261/get-email-items-from-mailboxes-through-powershell
I change following line to include Email Address
Select-Object -Property Subject, ReceivedTime, Importance, SenderName, SenderEmailAddress
but need help to get All Folders
Function Get-OutlookInBox
{
<#
.Synopsis
This function returns InBox items from default Outlook profile
.Description
This function returns InBox items from default Outlook profile. It
uses the Outlook interop assembly to use the olFolderInBox enumeration.
It creates a custom object consisting of Subject, ReceivedTime, Importance,
SenderName for each InBox item.
*** Important *** depending on the size of your InBox items this function
may take several minutes to gather your InBox items. If you anticipate
doing multiple analysis of the data, you should consider storing the
results into a variable, and using that.
.Example
Get-OutlookInbox |
where { $_.ReceivedTime -gt [datetime]"5/5/11" -AND $_.ReceivedTime -lt `
[datetime]"5/10/11" } | sort importance
Displays Subject, ReceivedTime, Importance, SenderName for all InBox items that
are in InBox between 5/5/11 and 5/10/11 and sorts by importance of the email.
.Example
Get-OutlookInbox | Group-Object -Property SenderName | sort-Object Count
Displays Count, SenderName and grouping information for all InBox items. The most
frequently used contacts appear at bottom of list.
.Example
$InBox = Get-OutlookInbox
Stores Outlook InBox items into the $InBox variable for further
"offline" processing.
.Example
($InBox | Measure-Object).count
Displays the number of messages in InBox Items
.Example
$InBox | where { $_.subject -match '2011 Scripting Games' } |
sort ReceivedTime -Descending | select subject, ReceivedTime -last 5
Uses $InBox variable (previously created) and searches subject field
for the string '2011 Scripting Games' it then sorts by the date InBox.
This sort is descending which puts the oldest messages at bottom of list.
The Select-Object cmdlet is then used to choose only the subject and ReceivedTime
properties and then only the last five messages are displayed. These last
five messages are the five oldest messages that meet the string.
.Notes
NAME: Get-OutlookInbox
AUTHOR: ed wilson, msft
LASTEDIT: 05/13/2011 08:36:42
KEYWORDS: Microsoft Outlook, Office
HSG: HSG-05-26-2011
.Link
Http://www.ScriptingGuys.com/blog
#Requires -Version 2.0
#>
Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null
$olFolders = "Microsoft.Office.Interop.Outlook.olDefaultFolders" -as [type]
$outlook = new-object -comobject outlook.application
$namespace = $outlook.GetNameSpace("MAPI")
$folder = $namespace.getDefaultFolder($olFolders::olFolderInBox)
$folder.items |
Select-Object -Property Subject, ReceivedTime, Importance, SenderName, SenderEmailAddress
} #end function Get-OutlookInbox
I got help on InBox but need help to get all folders
Syntax for Get-MailboxFolder follow This link for more abou
Get-MailboxFolder
[[-Identity] <MailboxFolderIdParameter>]
[-Recurse]
[-DomainController <Fqdn>]
[-MailFolderOnly]
[-ResultSize <Unlimited>]
[<CommonParameters>]
Try this code apply your fields.
$DomainSuffix = Read-Host "Type the domain name suffix that you look for"
# Creating folder structure and file names for the exported CSV files
$A20 = "C:\INFO\E-mail address\Exchange Online\E-mail address with Domain suffix - $Domainsuffix"
if (!(Test-Path -path $A20))
{New-Item $A20 -type directory}
# Exchange Online infrastructure
# Define the variable for the different type of Exchange Online recipients
$AllRecipients = Get-Recipient -ResultSize unlimited| Where {$_.EmailAddresses -like "*#$DomainSuffix"}
$SoftDeleted = Get-Mailbox -SoftDeletedMailbox | Where {$_.EmailAddresses -like "*#$DomainSuffix"}
$UnifiedGroups = Get-UnifiedGroup | Where {$_.EmailAddresses -like "*#$DomainSuffix"}
if ($SoftDeleted -eq $null)
{
write-host "There are no Soft Deleted Exchange Online mailboxes that have an E-mail address with the domain name suffix - $DomainSuffix"
}
else
{
$SoftDeleted | Select DisplayName,EmailAddresses,RecipientType,RecipientTypeDetails | Export-CSV $A20\"Exchange Online Soft Deleted mailboxes that their E-mail address include the domain name suffix $DomainSuffix.CSV" –NoTypeInformation -Encoding utf8
}
if ($UnifiedGroups -eq $null)
{
write-host "There are no Exchange Online unified groups that have an E-mail address with the domain name suffix - $DomainSuffix"
}
Else
{
$UnifiedGroups | Select DisplayName,EmailAddresses,RecipientType,RecipientTypeDetails | Export-CSV $A20\"Exchange Online unified groups that their E-mail address include the domain name suffix $DomainSuffix.CSV" –NoTypeInformation -Encoding utf8
}
if ($AllRecipients -eq $null)
{
write-host "There are no Exchange Online Recipients that have an E-mail address with the domain name suffix - $DomainSuffix"
}
Else
{
$AllRecipients | Select DisplayName,EmailAddresses,RecipientType,RecipientTypeDetails | Export-CSV $A20\"Exchange Online recipients that their E-mail address include the domain name suffix $DomainSuffix.CSV" –NoTypeInformation -Encoding utf8
}
for reference follow this Site

Delete Method Outlook Item

I'm new in Posh and trying to understand this error message when I add select object:
Method call failed because [Selected.System.__ComObject] does not
contain a method named "Delete".
Here's my code which works fine without the | select-object:
$Outlook = New-Object -comobject “Outlook.Application”
$MAPI = $Outlook.getnamespace(“mapi”)
$folder = $MAPI.GetDefaultFolder(6)
$SubFolder = $folder.Items | Where-Object {$_.tasksubject -like “*Alert*”} | Select-Object TaskSubject
Foreach ($Folder in $SubFolder)
{
$SubFolder.delete()}
Can someone tell me why and where should I place it please? Thanks for your advices.
my code which works fine without the | select-object :
Indeed, the Select-Object call is your problem: It returns [pscustomobject] instances (which don't have a .Delete() method), whereas you need to act directly on the original Outlook folder items.
Since it doesn't look like the Select-Object call does anything useful in your case, you can simply omit it, and use ForEach-Object in the same pipeline to call the .Delete() method on each folder item (using simplified syntax):
$folder.Items |
Where-Object TaskSubject -like *Alert* |
ForEach-Object Delete

Get email items from mailboxes through powershell

I need to retrieve email items from outlook from various mailboxes.
I found the below script that works fine for my inbox. But how do i define other mailbox name in the script.
I have many mailboxes and each hour i need to retrieve items from the mailboxes, hence looking out for automation which help save efforts.
Function Get-OutlookInBox
{
<#
.Synopsis
This function returns InBox items from default Outlook profile
.Description
This function returns InBox items from default Outlook profile. It
uses the Outlook interop assembly to use the olFolderInBox enumeration.
It creates a custom object consisting of Subject, ReceivedTime, Importance,
SenderName for each InBox item.
*** Important *** depending on the size of your InBox items this function
may take several minutes to gather your InBox items. If you anticipate
doing multiple analysis of the data, you should consider storing the
results into a variable, and using that.
.Example
Get-OutlookInbox |
where { $_.ReceivedTime -gt [datetime]"5/5/11" -AND $_.ReceivedTime -lt `
[datetime]"5/10/11" } | sort importance
Displays Subject, ReceivedTime, Importance, SenderName for all InBox items that
are in InBox between 5/5/11 and 5/10/11 and sorts by importance of the email.
.Example
Get-OutlookInbox | Group-Object -Property SenderName | sort-Object Count
Displays Count, SenderName and grouping information for all InBox items. The most
frequently used contacts appear at bottom of list.
.Example
$InBox = Get-OutlookInbox
Stores Outlook InBox items into the $InBox variable for further
"offline" processing.
.Example
($InBox | Measure-Object).count
Displays the number of messages in InBox Items
.Example
$InBox | where { $_.subject -match '2011 Scripting Games' } |
sort ReceivedTime -Descending | select subject, ReceivedTime -last 5
Uses $InBox variable (previously created) and searches subject field
for the string '2011 Scripting Games' it then sorts by the date InBox.
This sort is descending which puts the oldest messages at bottom of list.
The Select-Object cmdlet is then used to choose only the subject and ReceivedTime
properties and then only the last five messages are displayed. These last
five messages are the five oldest messages that meet the string.
.Notes
NAME: Get-OutlookInbox
AUTHOR: ed wilson, msft
LASTEDIT: 05/13/2011 08:36:42
KEYWORDS: Microsoft Outlook, Office
HSG: HSG-05-26-2011
.Link
Http://www.ScriptingGuys.com/blog
#Requires -Version 2.0
#>
Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null
$olFolders = "Microsoft.Office.Interop.Outlook.olDefaultFolders" -as [type]
$outlook = new-object -comobject outlook.application
$namespace = $outlook.GetNameSpace("MAPI")
$folder = $namespace.getDefaultFolder($olFolders::olFolderInBox)
$folder.items |
Select-Object -Property Subject, ReceivedTime, Importance, SenderName
} #end function Get-OutlookInbox
you could try adding a param block to your script so you can run something like "Get-OutlookInbox -Mailbox ". It would look something like this:
param (
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
Position=1)]
[string[]]$Mailbox=$env::USERNAME
)
So just to break it down a little, the actual name of the parameter is "Mailbox" and it is set to a default value that returns the current user running the script. You can override it by specifying one when you run the function. This will also accept a value from pipeline, meaning you can have an array of strings called "$aliases" and then run it like this: $aliases | Get-OutlookInbox

Export CSV field formatting

I have the following script which identifies an account number based on the file name, and adds the list of accounts to a CSV file next to the date it was created.
$ReconFolder = "C:\Users\tenba1\Documents\QlikView\Account Recons"
Get-ChildItem $ReconFolder -Filter *.xls | Where-Object {$_.BaseName -match '^Recon_\d{16,20}_\d+$'} | ForEach-Object{
$id,$date = $_.BaseName.Split('_')[1..2]
New-Object PSObject -Property #{
"Account Number" = $id
"Date Requested" = $date.Insert(4,'/').Insert(7,'/')
}
} | sort-object DateCreated -Descending | Export-Csv $ReconFolder\itemList.CSV - NoTypeInformation
There are 2 problems with it:
The sorting isn't working for some reason. I can get around this by re-importing the file, sorting, then exporting again, but would like to do it properly.
The Account Number can be between 16 and 20 digits - when sending this to CSV the format should be text. Currently an account number like this 10201314050019817277 ends up in the file like this: 10201314050019800000.
The sorting isn't working because the pipeline contains your PSObject which doesn't contain DateCreated, to include this add it to your object:
New-Object PSObject -Property #{
"Account Number" = $id
"Date Requested" = $date.Insert(4,'/').Insert(7,'/')
"DateCreated" = $_.CreationTime
}
With regards to the formatting of the number, check the csv in a text editor, I suspect that you are viewing the data in Excel and that the csv contains the correct data.

How to create subset of data based on multiple matching field values in Powershell?

I have a powershell script that pulls emails using EWS managed API, reads their subject, from address, to address, and internetmessageheaders. Within the email read loop it loads all this information into a datatable.
I need to grab all the above information for each message and populate an array or datatable based on the from address. Then I'll check for relay information and send the whole list based on from address to a target address.
I can't seem to wrap my head around how to build the from address lists. I've tried turning the datatable data into a hashtable and then using a sort|get-unique to get a list of the unique from addresses but have not been able to use this information to correctly build the from address array. I've tried looping through using a select-string $_ -allmatches but haven't gotten anywhere.
Here is part of my code, It creates the datatable and populates it using information from each email.
$msgTable = New-Object system.Data.DataTable “Messages”
$col1 = New-Object system.Data.DataColumn Subject,([string])
$col2 = New-Object system.Data.DataColumn From,([string])
$col3 = New-Object system.Data.DataColumn To,([string])
$col4 = New-Object system.Data.DataColumn Relay,([string])
$msgTable.columns.add($col1)
$msgTable.columns.add($col2)
$msgTable.columns.add($col3)
$msgTable.columns.add($col4)
$frItemResult = $PublicFolder.FindItems($sfCollection,$view)
# Loop through view results and mark read
$frItemResult | ForEach-object{
if($_.HasAttachments ) {
$_.Load()
"Report Subject: $($_.Subject)"
# Loop through attachments, extract info
$_.Attachments | ForEach-object {
if($_.Name -notmatch "ATT00001"){
$_.Load($attPropset)
$row = $msgTable.NewRow();$row.Subject = $($_.item.Subject); $row.From = ($_.item.From.address); $row.To = $($_.item.ToRecipients.address); $row.Relay = "$($_.Item.InternetMessageHeaders | Where-Object {$_.name -like "*received*"})";$msgTable.Rows.Add($row)
Here is what $msgTable looks like after data is populated.
Subject From To Relay
------- ---- -- -----
Message1 user1#company.com recipient1#yahoo.com Received-SPF=pass (domain of ...
Message2 user2#company.com recipient2#comcast.net Received=from imta27.mailguys...
Message2 user2#company.com recipient3#yahoo.com Received-SPF=pass (domain of ...
Message3 user3#company.com recipient4#sbcglobal.net Received-SPF=pass (domain of ...
I need to be able to grep out all the information for user2#company.com to another variable and do the same for any number of other repeating or non-repeating from addresses.
I'll then take each of the from address variables and send it to the target recipient.
Any help is greatly appreciated.
Try using Group-Object, you can then run a foreach loop against each grouping:
$Grouping = $msgTable | Group-Object -Property From
foreach ($Group in $Grouping)
{
Write-Host $Group.Name -ForegroundColor "Green"
$Group.Group | ft -Auto
}
Cool exercise! This is how I would approach it...
...I need to be able to grep out all the information for
user2#company.com to another variable
$patternMatches = $msgTable | select-string -pattern 'user2#company.com'
...and do the same for any number of other repeating or non-repeating
from addresses.
$uniqueEmails = $msgTable | Select-Object From -Unique
foreach ($email in $uniqueEmails) {
$patternMatches = $msgTable | Select-Object -property * | select-string -pattern $email
}
I know this isn't exactly right, but it should push you into the right direction.