GraphEmailSender.psm1
### --- PUBLIC FUNCTIONS --- ### #Region - Send-GraphEmail.ps1 function Send-GraphEmail { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [mailaddress] $SenderUPN, [Parameter(Mandatory=$false)] [mailaddress[]] $Recipients, [Parameter(Mandatory=$false)] [mailaddress[]] $CopyRecipients, [Parameter(Mandatory=$false)] [mailaddress[]] $HidenRecipients, [Parameter(Mandatory=$true)] [string] $MailSubject, [Parameter(Mandatory=$true)] [string] $MessageBody, [Parameter(Mandatory=$false)] [string[]] $AttachmentPaths, [Parameter(Mandatory=$false)] [string] $MessageBodyContentType = "Text", [Parameter(Mandatory=$true)] [PSCustomObject] $Token ) begin { #requires -module GraphApiRequests Import-module GraphApiRequests } process { Write-Verbose "Checking if recipients defined" if(!$Recipients -and !$CopyRecipients -and !$HidenRecipients){ Write-Verbose "There are no recipients" throw "There are no recipients. Function can't be invoked" break } $MailObjectSplat = @{ SenderUPN = $SenderUPN MailSubject = $MailSubject MessageBody = $MessageBody MessageBodyContentType = $MessageBodyContentType ErrorAction = "STOP" } if ($Recipients){ $MailObjectSplat.Add('Recipients', $Recipients) } if ($CopyRecipients){ $MailObjectSplat.Add("CopyRecipients", $CopyRecipients) } if ($HidenRecipients){ $MailObjectSplat.Add("HidenRecipients", $HidenRecipients) } if($AttachmentPaths){ foreach($Attacment in $AttachmentPaths){ $IsPathValid = Test-Path -Path $Attacment if (!$IsPathValid) { throw "Attachment with path $Attacment hasn't been found! Please check the path." break } } $MailObjectSplat.Add("AttachmentPaths", $AttachmentPaths) } try { $MailObjectSplat = New-GraphEmailObject @MailObjectSplat } catch { Write-Verbose $_.Exception break } $RequestURI = "users/$SenderUPN/sendMail" $RequestPayLoad = $MailObjectSplat | ConvertTo-Json -Depth 6 Write-Verbose "URI for graph request: $RequestURI" Write-Verbose "Message Payload: `n$RequestPayLoad" $RequestSplat = @{ Token = $Token Resource = $RequestURI Method = "POST" Body = $RequestPayLoad ErrorAction = "STOP" } Invoke-GraphApiRequest @RequestSplat } } Export-ModuleMember -Function Send-GraphEmail #EndRegion - Send-GraphEmail.ps1 ### --- PRIVATE FUNCTIONS --- ### #Region - New-GraphEmailObject.ps1 function New-GraphEmailObject { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [mailaddress] $SenderUPN, [Parameter(Mandatory=$false)] [mailaddress[]] $Recipients, [Parameter(Mandatory=$false)] [mailaddress[]] $CopyRecipients, [Parameter(Mandatory=$false)] [mailaddress[]] $HidenRecipients, [Parameter(Mandatory=$true)] [string] $MailSubject, [Parameter(Mandatory=$true)] [string] $MessageBody, [Parameter(Mandatory=$false)] [string[]] $AttachmentPaths, [Parameter(Mandatory=$false)] [string] $MessageBodyContentType = "Text" ) Write-Verbose "Creating main MessageObject" $MessageCustomObject = [ordered]@{ message = @{ subject = $MailSubject body = @{ contentType = $MessageBodyContentType content = $MessageBody } } } Write-Verbose "Checking if recipients exist and theirs count" if ($Recipients.Count -eq 1) { Write-Verbose "There is only 1 recipient" $Recipient = $Recipients[0].Address $ToRecipients = @{address = $Recipient} Write-Verbose "Adding recipient $Recipient to the MessageObject" $MessageCustomObject.message += [ordered]@{ toRecipients = @( @{ emailAddress = $ToRecipients } ) } } elseif ($Recipients.Count -gt 1) { Write-Verbose "There are more than 1 recipients. Count: $($Recipients.Count)" $AddressesTable = @() foreach($Recipient in $Recipients){ Write-Verbose "Adding $Recipient to recipient list" $AddressesTable += @{ emailAddress = @{address = $Recipient.Address} } } Write-Verbose "Adding recipient list to MessageObject" $MessageCustomObject.message += [ordered]@{ toRecipients = $AddressesTable } } Write-Verbose "Checking CopyRecipients" if($CopyRecipients.count -eq 1){ $CopyRecipient = $CopyRecipients[0].Address Write-Verbose "There is 1 CopyRecipient: $CopyRecipient" $ccRecipients = @{address = $CopyRecipient} Write-Verbose "Adding recipient $CopyRecipient to the MessageObject" $MessageCustomObject.Message += [ordered]@{ ccRecipients = @( @{ emailAddress = $ccRecipients } ) } } elseif ($CopyRecipients.Count -gt 1) { Write-Verbose "There are more than 1 CopyRecipients. ccRecipients count: $($CopyRecipients.Count)" $CopyAddressesTable = @() foreach ($CopyRecipient in $CopyRecipients){ Write-Verbose "Adding $CopyRecipient to copy recipients list" $CopyAddressesTable += @{ emailAddress = @{address = $CopyRecipient.Address} } } Write-Verbose "Adding ccRecipients list to MessageObject" $MessageCustomObject.Message += [ordered]@{ ccRecipients = $CopyAddressesTable } } Write-Verbose "Checking HidenRecipients and count" if($HidenRecipients.count -eq 1){ $HidenRecipient = $HidenRecipients[0].Address Write-Verbose "There is only 1 hiden recipient: $HidenRecipient" $bccRecipients = @{address = $HidenRecipient} Write-Verbose "Adding $HidenRecipient to the MessageObject" $MessageCustomObject.Message += [ordered]@{ bccRecipients = @( @{ emailAddress = $bccRecipients } ) } } elseif ($HidenRecipients.Count -gt 1) { Write-Verbose "There are more than one hidenRecipients. HidenRecipients count: $($HidenRecipient.Count)" $HidenAddressesTable = @() foreach ($HidenRecipient in $HidenRecipients){ Write-Verbose "Adding HidenRecipient $HidenRecipient to the list" $HidenAddressesTable += @{ emailAddress = @{address = $HidenRecipient.Address} } } Write-Verbose "Adding hidden recipients list to the MessageObject" $MessageCustomObject.Message += [ordered]@{ bccRecipients = $HidenAddressesTable } } Write-Verbose "Checking attachments and count" if ($AttachmentPaths) { if ($AttachmentPaths.count -eq 1) { Write-Verbose "There is only 1 attachment: $AttachmentPaths" $isAttachmentValid = Test-Path $AttachmentPaths if ($isAttachmentValid) { Write-Verbose "Attachment $AttachmentPaths successfully checked." $AttachmentName = ((Get-Item -Path $AttachmentPaths).name) $Base64String = [Convert]::ToBase64String([IO.File]::ReadAllBytes($AttachmentPaths)) $MessageCustomObject.Message.attachments += @( @{ '@odata.type' = "#microsoft.graph.fileAttachment" name = $AttachmentName contentType = 'text/plain' contentBytes = $Base64String } ) } else{ throw "Provided attachment path is invalid" break } } elseif ($AttachmentPaths.count -gt 1) { Write-Verbose "There are more than 1 attachments. Count: $($AttachmentPaths.count)" $AttachmentsObjectLists = @() foreach ($Attachment in $AttachmentPaths) { Write-Verbose "Checking the file $Attachment" $isAttachmentValid = Test-Path $Attachment if ($isAttachmentValid) { Write-Verbose "File $Attachment is reachable" $AttachmentName = ((Get-Item -Path $Attachment).name) $Base64String = [Convert]::ToBase64String([IO.File]::ReadAllBytes($Attachment)) Write-Verbose "Adding $AttachmentName to the list" $AttachmentsObjectLists += @{ '@odata.type' = "#microsoft.graph.fileAttachment" name = $AttachmentName contentType = 'text/plain' contentBytes = $Base64String } } else{ throw "Attachment with path $Attachment hasn't been found! Please check the path." break } } if($AttachmentsObjectLists.count -gt 1) { Write-Verbose "Adding prepared list to the MailObject" $MessageCustomObject.Message += [ordered]@{ attachments = $AttachmentsObjectLists } } } } return $MessageCustomObject } #EndRegion - New-GraphEmailObject.ps1 |