Showing posts with label office. Show all posts
Showing posts with label office. Show all posts

Friday, 7 May 2021

Connect to Office365/O365 using Powershell

A quick an easy post with details on how to connect your Office 365 (O365) environment to allow management with powershell cmdlets

Make sure you change the value next to -Credential from username@domain.com to the username you need to use to connect

$ex = New-PSSession -ConfigurationName Microsoft.Exchange -Credential username@domain.com -ConnectionUri https://outlook.office365.com/powershell -Authentication basic -AllowRedirection

import-pssession $ex

After executing this command, a popup window will appear for you to enter your password into



You will then receive a couple of warning messages to indicate that your session has been redirected to a slightly different URL, and another about some of the imported commands. These can be safely ignored

WARNING: Your connection has been redirected to the following URI: "https://outlook.office365.com/PowerShell-LiveID?PSVersion=5.1.17763.1852 "
WARNING: The names of some imported commands from the module 'tmp_4kculvlx.2wc' include unapproved verbs that might make them less discoverable. To find the commands with unapproved verbs, run the Import-Module command again with the Verbose parameter. For a
 list of approved verbs, type Get-Verb.

You can then proceed to manage your Office 365 environment with the standard powershell commands - get-mailbox etc.


Tuesday, 4 May 2021

Reading Emails from O365 Mailbox with Powershell

Here is a script you can use to connect to an Office 365 (O365) mailbox to read/parse email messages. After the message has been read it is then moved to a specific folder within the mailbox. The full script is included first, and I will then break it down section by section afterwards

#Enable Exchange/O365 cmdlets
add-pssnapin *exchange* -erroraction SilentlyContinue
Import-Module MSOnline -ErrorAction SilentlyContinue

#Credentials
$email = email@domain.com
$password = "password"
$emaildomain = domain.com

#Connect to Mailbox
[void][Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll")
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$s.Credentials = New-Object Net.NetworkCredential($email, $password, $emaildomain)
$s.Url = new-object Uri("https://outlook.office365.com/EWS/Exchange.asmx");
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)

#Setup folder and folder view (to move completed messages to)
$fv = new-object Microsoft.Exchange.WebServices.Data.FolderView(30)
$fv.Traversal = "Deep"
$folders = $s.findFolders([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$fv)
$processedfolder = $folders | where {$_.displayname -eq "ProcessedEmails"}

#Get unread messages
$msgs = $null
$iv = new-object Microsoft.Exchange.WebServices.Data.ItemView(50)
$inboxfilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And)
$ifisread = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::IsRead,$false)
$inboxfilter.add($ifisread)
$msgs = $s.FindItems($inbox.Id, $inboxfilter, $iv)

#If unread message(s) found, do stuff
if ($msgs.totalcount -ne 0)
    {
    $psPropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
    $psPropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;
    $s.LoadPropertiesForItems($msgs,$psPropertySet)
    $msgs = $msgs.items
    }

#Move Message to Processed Folder
$msg.Move($processedfolder.Id)


The #Enable Exchange/O365 Cmdlets section as the comment suggests is to enable the Microsoft Exchange & Office 365 cmdlets

add-pssnapin *exchange* -erroraction SilentlyContinue
Import-Module MSOnline -ErrorAction SilentlyContinue

The #Credentials section is where you enter the details (username, password and email domain) used to connect to the mailbox

#Credentials
$email = email@domain.com
$password = "password"
$emaildomain = domain.com

Next, we will connect to the mailbox (and look at the Inbox folder specifically), using the credentials specified above and Microsoft Exchange Web Services. If you don't already have the Exchange Web Services files installed you will need to install them

#Connect to Mailbox
[void][Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll")
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$s.Credentials = New-Object Net.NetworkCredential($email, $password, $emaildomain)
$s.Url = new-object Uri("https://outlook.office365.com/EWS/Exchange.asmx");
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)

Now, a folder view is setup to obtain the list of all the folders in the mailbox. All the list of available folders are stored in the $folders variable. We then look for a folder called "ProcessedTickets" and set this folder to be the $processedfolder variable. We use this variable (folder) later on to move processed emails into. You can of course change this folder name to be anything you like.

#Setup folder and folder view (to move completed messages to)
$fv = new-object Microsoft.Exchange.WebServices.Data.FolderView(30)
$fv.Traversal = "Deep"
$folders = $s.findFolders([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$fv)
$processedfolder = $folders | where {$_.displayname -eq "ProcessedEmails"}

Now we will retrieve any unread messages within the mailbox - filters are set using the $inboxfilter and $ifisread variables. All messages matching the search criteria are stored in the $msgs variable

#Get unread messages
$msgs = $null
$iv = new-object Microsoft.Exchange.WebServices.Data.ItemView(50)
$inboxfilter = new-object
Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And)
$ifisread = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::IsRead,$false)
$inboxfilter.add($ifisread)
$msgs = $s.FindItems($inbox.Id, $inboxfilter, $iv)

If messages are found in the $msgs variable, the properties for those messages are then loaded back into the $msgs variable

#If unread message(s) found, do stuff
if ($msgs.totalcount -ne 0)
    {
    $psPropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
    $psPropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;
    $s.LoadPropertiesForItems($msgs,$psPropertySet)
    $msgs = $msgs.items
    }

If you look at the $msgs variable at this point, it should contain the properties of all mail messages found in the inbox that are unread. You can then use a foreach loop to cycle through each message and action accordingly.

Properties such as subject, body text, from address are all available and can be used to further filter entries

Once you've actioned the email and done what you need, you can then move the email into the processedfolders folder we previously specified

#Move Message to Processed Folder
$msg.Move($processedfolder.Id)