Data mining outlook e-mail bodies - powershell

A while ago I went through and starting using the script guys get-outlookInbox which worked great with Data mining Subjects, however, I'm now trying to basically do the same thing but by trying to do this with bodies.
Originally I was importing the custom script from the script guys: https://blogs.technet.microsoft.com/heyscriptingguy/2011/05/26/use-powershell-to-data-mine-your-outlook-inbox/
Using the line
$inbox | Where-Object { $_.subject -match 'x'} | Where-Object { ($_.ReceivedTime -gt "06 11 2017") -and ($_.ReceivedTime -lt "10 10 2018") } | Group-Object -Property senderName -NoElement | Sort-Object count
I've tried changing $_.subject to $_.body however it seems that the original script doesn't pull body contents, i'm somewhat stuck here and was hoping someone might be able to point me in the right direction

The reason why it is not available is because the original script does not select the body. In order to get the body of the message you will need to change the original script to include the body.
Change:
Get-OutlookInbox.ps1
Change the line from:
$folder.items | Select-Object -Property Subject, ReceivedTime, Importance, SenderName
To:
$folder.items | Select-Object -Property Subject, ReceivedTime, Importance, SenderName, body

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

Microsoft Graph issue - Filtering output

I'm exporting both custom and standard attributes of all users in Azure AD. I'm having difficulty wrapping my head around customizing the output when exporting.
For example, I'm seeking to export all users that are members, not Guests, with the below attributes:
$URI = "https://graph.microsoft.com/beta/users?`$select=displayName,userPrincipalName, mail, department, jobTitle, extension_1fe7973b28e74213b897d62528e614c7_extensionAttribute14, extension_1fe7973b28e74213b897d62528e614c7_extensionAttribute15, accountEnabled, signInActivity, UserType, id&`$expand=manager(`$select=displayName,userPrincipalName)&`$top=999"
I've tried adding to the URI above to include $filter=userType eq 'Guest'
I've tried adjusting my report object to
$ReportLine = [PSCustomObject] #{
UserType = $filter=$User.UserType -eq "Member"}
I've also tried modifying my write output code with no success:
Write-Host "All done. " $Report.Count "accounts processed - output available in c:\Temp\ReportUserSignin.csv."
$Report | Sort DisplayName | Out-GridView
$Report | ?{$_.UserType -eq "Guest"}| Sort {$_.LastSignIn -as [DateTime]} -Descending | Format-Table DisplayName, LastSignIn, Email | Export-CSV -NoTypeInformation c:\Temp\ReportUserSignin.csv
The above two only results in True/False results of the user is a member or guest.
Can someone provide some insight as to what I'm missing here or even where the filter should be for the exported report? I greatly appreciate any and all advice! :)

PowerShell/VBScript - Extract Outlook Mails Based on Condition

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.

how to get exact user name from get-mobiledevicestatistics in powershell

I have a small script to get all user mobile devices info from exchange 2013 server.
Get-Mailbox -ResultSize Unlimited |
ForEach {Get-MobileDeviceStatistics -Mailbox:$_.Identity} |
Select-Object #{label="User" ; expression={$_.Identity}},DeviceOS, lastsuccesssync
I just want to get an exact user name instead of a path in AD. How can I do it in expression={?}
Here is another script to do it, it gives me the user name, but all devices belongs to user are not in separated lines, they all in one line...
$EASMailboxes = Get-CASMailbox -Filter {HasActiveSyncDevicePartnership -eq $True -and DisplayName -notlike "CAS_{*"} | Get-Mailbox
$EASMailboxes | Select-Object DisplayName, PrimarySMTPAddress, #{Name="Mobile Devices";Expression={(Get-MobileDeviceStatistics -Mailbox $_.Identity).DeviceOS}} |
Out-GridView
I don't have the environment to test this but is this not what you are looking for ?
Get-Mailbox -ResultSize Unlimited | ForEach {
$user = $_.SamAccountName
Get-MobileDeviceStatistics -Mailbox:$_.Identity |
Select-Object #{label="User" ; expression={$user}},DeviceOS, lastsuccesssync
}
That should output the user for every device they own on its own line. You could then easily export this to Export-CSV or some such thing that way.
We save the $user so it is available later in the pipe. Could also have used Add-Member but the result would have been the same.
If you have the identity field, which looks like this
domain.com/Users/OU/UserName/ExchangeActiveSyncDevices/iPhone
Then to split on the / and get the third result, you simply request:
$_.Identity.Split("/")[3]
>UserName
PowerShell begins indexing with number zero, so to request the fourth entry in the list, we request index number 3.
Update
OP mentioned that the OU level might vary, meaning that he couldn't count on a fixed position to request the Index. In order to accomodte that scenario, try this method, which will look for the index of ExchangeActiveSyncDevices and then pick the index position before that.
$_.Identity.Split('/')[($_.Identity.Split('/').Indexof('ExchangeActiveSyncDevices')-1)]
Get-Mailbox -resultsize unlimited|foreach {Get-MobileDeviceStatistics -Mailbox:$_.identity} |Select-Object #{l="user";e={$_.Identity.parent.parent.name}}, lastsuccesssync
on e2k13

Exchange 2010 TotalItemSize.Value.ToBytes() always empty

I'm trying to create simple reports on Exchange 2010 mailbox size.
While this works:
Get-MailboxStatistics -server <serverfqdn> |ft displayname, TotalItemSize
this doesn't (second column stays empty):
Get-MailboxStatistics -server <serverfqdn> |ft displayname, {$_.TotalItemSize.Value.ToBytes()}
The problem is that I need the size as an integer, so the first line of code doesn't serve my purpose.
According to several websites the second line of code should work but unfortunately doesn't on my machine.
I know I could parse the value after using the first line but that would be unnecessarily inefficient, wouldn't it? :-)
Hope anyone can help.
Regards,
Kevin
If performing from a imported PS session the methods .ToMB() is lost as the type becomes a custom object.
The $variable.TotalItemSize.Value becomes a two element array [0] in KB,MB or GB and [1] always in bytes.
So to use this we can play with strings to achieve what we want.. in long hand for clarity
$mailboxes = Get-Mailbox -Filter{(RecipientType -eq "UserMailbox") -and (CustomAttribute12 -eq "whatever")}
foreach ($mailbox in $mailboxes)
{
$size1 = Get-MailboxStatistics $mailbox.id
[string]$bob = $size1.TotalItemSize.Value
[int]$bill = $bob.TrimEnd(" bytes)").Split("(")[1] # The bytes part of the array.
$bill = $bill/1mb # Convert into MB's
if ($bill -le 1500) {do something} Else {"Too Big " + $bill} # note -le 1500 NOT 1500MB
}
I hope this helps
this worked for me
$a = get-mailbox -id user | Get-MailboxStatistics
$a.TotalItemSize.Value.ToMB()
$a.TotalItemSize.Value.ToKB()
I have the same issue. I'm not sure if you resolved this.
I have this, which is quite ugly - but works:
$a = get-mailbox USER | get-mailboxstatistics
$intTotalItemSize = [int]$a.TotalItemSize.SubString($a.TotalItemSize.indexof("(")+1, $a.TotalItemSize.indexof(" b")-$a.TotalItemSize.indexof("("))
Try this for your size expression:
#{expression={$_.TotalItemSize.Value.ToMB()};label="Mailbox Size(MB)"}
I believe there is also a ToKB() method.
MVP Shay Levy has delved into this on his blog (http://blogs.microsoft.co.il/blogs/scriptfanatic/archive/2011/08/22/get-full-control-over-your-exchange-remote-powershell-session.aspx).
Basically, you have to modify a setting in the PowerShell virtual directory on the server that you are remoting to.
This is great news for those who are remoting to Exchange servers that they have this kind of control over, but is not helpful for those of us who use hosted Exchange solutions and cannot change these settings. I suppose we will just have to abandon some of the uber-coolness of PowerShell and go back to parsing the string to get the bytes and convert from there.
--EDIT--
This is how I tackled outputting a file of all of my users' mailbox sizes. It could be compressed a bit further, but is a little more readable this way.
$allMailboxes = Get-Mailbox -ResultSize Unlimited
ForEach ( $mailbox in $allMailboxes ) {
$itemSizeString = ( Get-MailboxStatistics $mailbox.Identity ).TotalItemSize.Value.ToString()
$posOpenParen = $itemSizeString.IndexOf("(") + 1
$numCharsInSize = $itemSizeString.IndexOf(" bytes") - $posOpenParen
$mailboxSizeInBytes = $itemSizeString.SubString($posOpenParen,$numCharsInSize).Replace(",","")
Write-Output "$($mailbox.alias),$($mailboxSizeInBytes)"
}
Please, see this article: http://blogs.technet.com/b/gary/archive/2010/02/20/the-get-mailboxstatistics-cmdlet-the-totalitemsize-property-and-that-pesky-little-b.aspx
Get-Mailbox | Get-MailboxStatistics | Add-Member -MemberType ScriptProperty -Name TotalItemSizeinMB -Value {$this.totalitemsize.value.ToMB()} -PassThru | Format-Table DisplayName,TotalItem*
I needed to have this work outside of a remoting session, so I simplified the answer from Greybear to this:
$a = get-mailbox USER | get-mailboxstatistics
$intTotalItemSize = [int64]($a.TotalItemSize -split '[\( ]')[3]
Or in the format of the original question::
Get-MailboxStatistics -Server <serverfqdn> | Select-Object -Property DisplayName,#{label="TotalItemSize";expression={[int64]($_.TotalItemSize -split '[\( ]')[3]}} | ft
Realized that [int] would fail for mailboxes over 4GB, so changed to [int64]. Alternately, display the mailboxes in MB:
Get-MailboxStatistics -Server <serverfqdn> | Select-Object -Property DisplayName,#{label="TotalItemSize";expression={[int64](([int64]($_.TotalItemSize -split '[\( ]')[3])/1048576)}} | ft
The name needs to go before the expression. This will work.
Get-MailboxStatistics -Identity [name] | select #{label=”User”;expression={$_.DisplayName}},lastlogontime,#{label=”Total Size (MB)”;expression={$_.TotalItemSize.Value.ToMB()}}
This works for me
#{Name="TotalSize (MB)"; Expression={((($_.TotalItemSize) -split " ")[0])}}
You might try:
get-mailbox -resultsize unlimited | Get-MailboxStatistics | ft displayname,#{label="Total Size (MB)";expression={$_.TotalItemSize.Value.ToMB()}}