Category Archives: EWS

Get High Priority Email Message as a Phone Call using EWS API and PowerShell

baby-phone-scam

A colleague shared a blog post and asked me a script to get high priority email using PowerShell? Well, it’s the same way  by modifying the search filter as required as shown below.

$SearchFilter = [Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo]::new([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Importance, 
                "High")

and the below is the view to get the number of email we need from the inbox – In our case just one!

$View = [Microsoft.Exchange.WebServices.Data.ItemView]::new(1)

Hey, I need a phone call for a high priority email and it should read the message! That’s a Friday fever! For any IT Professional major incidents are not new 🙂 check the below email body 🙂 let’s get a call for the same !

Email Body

2016-10-28_13-05-55

 

Here is the sample code !

$Credential = Get-Credential "Chendrayan.Venkatesan@contoso.com"
$Service = [Microsoft.Exchange.WebServices.Data.ExchangeService]::new([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1)
$Service.Credentials = [System.Net.NetworkCredential]::new($Credential.UserName,$Credential.Password)
$Service.AutodiscoverUrl($UserID,{$true})
$Service.Url = "https://outlook.office365.com/EWS/Exchange.asmx"
$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
$View = [Microsoft.Exchange.WebServices.Data.ItemView]::new(1)
$SearchFilter = [Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo]::new([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Importance, 
                "High")
$Results = $Service.FindItems([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$SearchFilter,$View)
$ItemId = $Results.Items[0].Id.UniqueId

# Fun and it's Fun
$Call = $Service.UnifiedMessaging.PlayOnPhone($ItemId, "+31<Number>")
$Call.Refresh()

Enjoy PowerShell!

Import User Profile Picture from Exchange Online using EWS and PowerShell

One of our customer requested a solution to import user profile picture from Exchange Online. Not a big task but this article is to share the simple and clean method to carry out the task without MSOnline module. Yes, we use only PowerShell! At customer environment user uploads profile picture in intranet portal which saves the picture in file share, yeah I got the same question why can’t they get it from the file share? We can but not easy to do because of the profile image file naming convention, every user has an intranet portal profile ID so the files are saved as ID_DATETIMESTAMP. E.G “PROFILEID_YYYYMMDDHHMMSS”. There are many possibilities to do like query intranet portal DB to retrieve image file information and retrieve, use MSOnline module Get-UserPhoto etc.

Outclass is to use PowerShell and get it done on the fly. All we need is the EWS url for the profile picture residing in the Exchange Online and it’s shared below with sizes for reference and hew is the documentation for Get User Photos by using EWS in Exchange

1 https://outlook.office365.com/ews/Exchange.asmx/s/GetUserPhoto?email=”UserEmail” &size=HR96x96 HR96x96
2 https://outlook.office365.com/ews/Exchange.asmx/s/GetUserPhoto?email=”UserEmail” &size=HR240x240 HR240x240
3 https://outlook.office365.com/ews/Exchange.asmx/s/GetUserPhoto?email=”UserEmail” &size=HR648x648 HR648x648

 

All set to spin up PowerShell ISE for scripting! Simply use Invoke-WebRequest cmdlet with OutFile parameter to save the profile image in disk like shown below

$Param =@{
Uri = "https://outlook.office365.com/ews/Exchange.asmx/s/GetUserPhoto?email=Chendrayan.Venkatesan@contoso.com&size=HR648x648"
Credential = (Get-Credential "Chendrayan.Venkatesan@contoso.com")
OutFile = "C:\Temp\UserID.jpg"
}

Invoke-WebRequest @Param

Yay, its easy to get the profile picture information at ease without using Get-UserPhoto cmdlet and no need of Set-Content with Encoding parameters (Saves more time) ! here is my picture – Output of the above snippet!

Chen

Check out the sample script below which use ADSI Searcher to retrieve user AD information and save the picture in disk as sAMAccountName_DisplayName.jpg 🙂

function Get-xUserPhoto
{
<#
.Synopsis
   Imports User Profile Picture from Exchange Online using PowerShell and EWS
.DESCRIPTION
   This is a sample script to export user profile picture from exchange online using EWS and PowerShell.
   Use Invoke-Webrequest cmdlet
.EXAMPLE
   Get-xUserPhoto -Email Chendrayan.Venkatesan@contoso.com -Path C:\Temp\ -Credential "Chendrayan.Venkatesan@contoso.com"
   Import single user profile picture from Exchange Online and save it in C:\Temp as sAMAccountName_DisplayName.jpg
.EXAMPLE
   "Chendrayan.Venkatesan@contoso.com" , "Chendrayan.Venkatesan@contoso.com" | Get-xUserPhoto -Path C:\temp -Credential "Chendrayan.Venkatesan@contoso.com"
   Retrieves multiple user profile picture and save it in C:\temp
#>
    param
    (
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        $Email,

        [Parameter(Mandatory=$False)]
        [ValidateSet("96x96","240x240","648x648")]
        $Size="648x648",

        [Parameter(Mandatory)]
        $Path,

        [Parameter(Mandatory)]
        [pscredential]
        [System.Management.Automation.CredentialAttribute()]
        $Credential
    )

    process
    {
        try
        {
            $DEObj = ([adsisearcher]"(&(objectclass=user)(objectclass=person)(mail=$Email))").FindOne().GetDirectoryEntry()
            $Uri = [String]::Concat("https://outlook.office365.com/ews/Exchange.asmx/s/GetUserPhoto?email=",$Email,"&size=HR",$Size)
            if(Test-Path -Path $Path)
            {
                $File = [string]::Concat($Path,"\",$DEObj.sAMAccountName, "_", $DEObj.DisplayName,".jpg")
                Invoke-WebRequest -Uri $Uri -Credential $Credential -OutFile $File
            }
            else
            {
                Write-Warning "Please Check the Path"
            }
        }
        catch
        {
            $_.Exception.Message 
        }
    }
}

 

Exploring LYNC Contacts Using PowerShell

Exploring LYNC Contact folders using PowerShell.

Get-MailboxFolderStatistics will display all the folders information in users mailbox. So using this we can explore LYNC Contacts with the folder type ‘Quick Contacts’.

Get-MailboxFolderStatistics -Identity <MailboxID> | 
? {$_.FolderType -eq 'QuickContacts'}

Lync Contact Folders with 0 EntriesLync Contact Folders with 0 Entries

If we delete lync contacts programmatically it may appear as GUID as well. Like shown below.

Get-MailboxFolderStatistics -Identity <MailboxID> | 
Select Name , ItemsinFolder | ft -AutoSize

2Underneath Contacts we can see two GUID – That’s LYNC and GAL Contacts

Refer this article to remove LYNC contact entries using PowerShell and EWS

How to Explore all folders?

Delete Lync Contact Entries in Exchange Online Using PowerShell

PowerShell code to remove LYNC Contacts entries in Exchange Online.

Code

#Target MailboxID's
$MailboxNames =  "TargetMailBoxID1" , "TargetMailBoxID1"

#Any Exchange Admin ID with appropriate permissions
$AdminID = "AdminID"

#Fetch password as secure string
$AdminPwd = Read-Host "Enter Password" -AsSecureString

#Load the Exchange Web Service DLL
$dllpath = "C:\Microsoft.Exchange.WebServices.dll"
[Reflection.Assembly]::LoadFile($dllpath)

#Create a Exchange Web Service
$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1)

#Credentials to impersonate the mail box
$Service.Credentials = New-Object System.Net.NetworkCredential($AdminID , $AdminPwd)
foreach($MailboxName in $MailboxNames)
{
#Impersonate using Exchange WebService Class
$Service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)
$Service.AutodiscoverUrl($MailboxName,{$true})

#Assing EWS URL
$service.Url = 'https://outlook.office365.com/EWS/Exchange.asmx'
Write-Host "Processing Mailbox: $MailboxName" -ForegroundColor Green

#Fetch Root Folder ID
$RootFolderID = New-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root, $MailboxName)
$RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$RootFolderID)

#Create a Folder View
$FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$FolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep

#Retrieve Folders from view
$response = $RootFolder.FindFolders($FolderView)

#Query Folder which has display name like Lync Contacts
$Folder =  $response | ? {$_.FolderClass -eq 'IPF.Contact.MOC.QuickContacts'}
$Folder | Select DisplayName , TotalCount

#Purge the items

$Folder.Empty([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete, $false)
$Folder.Load()

Perform Delete
$Folder.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete)
Write-Host "Removed Lync Contacts Folder on: $MailboxName mailbox" -ForegroundColor Green

}