Fill Email Body

Hey there,
I want to create an email with PowerShell and fill the body with an precreated email.
So i got this going:

# Gruppe abfragen
param(
     [Parameter(Mandatory=$true)]
     [String]$Group
     )
 
# Active Directory Modul laden
Import-Module ActiveDirectory
 
 echo $Group
 
# Email-Adressen ermitteln
$EmailAddresses = Get-ADGroupMember $Group -Recursive | Get-ADUser -Properties mail | Select mail
 echo $EmailAddresses
ForEach ($EmailAddress In $EmailAddresses){
  $OLAddresses = $EmailAddress.mail + ";" + $OLAddresses
}
 
# Outlookmail erstellen
$OL = New-Object -comObject Outlook.Application  
$Mail = $OL.CreateItem(0)
$Body = ""
$Mail.Body = $Body
$Mail.TO = $OLAddresses
#$Mail.BCC = $OLAddresses
$Mail.Display()

Now i got an .oft template and I want to use this to fill the body of my new Email I created.
Thanks for your help.
Greetings Knutonier

Why not just use Send-MailMessage?

$EmailAddresses = Get-ADGroupMember $Group -Recursive | Get-ADUser -Properties mail | Select -expandProperty mail
 
Send-MailMessage -SMTPServer  -To $EmailAddresses -From  -Body $Body -Subject 

Sometimes we need to change the email before we send it out.
And we want to check the mail before we send it out.

Why not send the mail, as Matt advised, to a QA person and once checked they can send it to a Dist List?

Have a look at the CreateItemFromTemplate method of the Outlook object. I think it will do what you are describing.

Like already mentioned above I think CreateItemFromTemplate will do that. When working with a comobject it sometimes can be helpfull to look at what your options are from within the VBA designer or just explorer your options with Get-Member.

I needed to do something similar to this once when setting up the process for staff member name changes. When the staff member submits a request for a name change to HR, I send them a notification letting them know that their primary email address will change. I wanted to be able to generate a message from the AD user attributes and preview the message before sending, but I despise the Office Interop assemblies so I found a different way to do it. This script will spin up a windows forms web browser object and insert your custom HTML. If you’re happy with the message you can click send and the message will be configured to send to the AD user using their UserPrincipalName value:

function Send-ADUserEmail
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [Microsoft.ActiveDirectory.Management.ADUser] $Identity,

        [parameter(Mandatory=$true)]
        [string] $NewLast,

        [parameter(Mandatory=$true)]
        [string] $NewUPN,

        [string] $From,

        [string] $FromDisplayName,

        [string] $FromTitle,

        [string] $FromDept,

        [string] $FromOrg,

        [string] $SMTPServer,

        [string] $MessageSubject
    )

    begin
    {
        function Exit-Application {
            $script:ExitCode = 0
        }

        function Start-WebBrowser {
            param
            (
                [Parameter(Mandatory=$true)]
                [string]
                $HtmlPath
            )

            Add-Type -AssemblyName System.Windows.Forms

            #region Generated Form Objects

            [System.Windows.Forms.Application]::EnableVisualStyles()
            $form1 = New-Object -TypeName 'System.Windows.Forms.Form'
            $webbrowser1 = New-Object -TypeName 'System.Windows.Forms.WebBrowser'
            $buttonYes = New-Object -TypeName 'System.Windows.Forms.Button'
            $buttonCancel = New-Object -TypeName 'System.Windows.Forms.Button'
            $InitialFormWindowState = New-Object -TypeName 'System.Windows.Forms.FormWindowState'

            #endregion Generated Form Objects

            $FormEvent_Load={
                $webbrowser1.navigate($HtmlPath)
            }

            #region Generated Events

            $Form_StateCorrection_Load=
            {
                #Correct the initial state of the form to prevent the .Net maximized form issue
                $form1.WindowState = $InitialFormWindowState
            }

            $Form_Cleanup_FormClosed=
            {
                #Remove all event handlers from the controls
                try
                {
                    $form1.remove_Load($FormEvent_Load)
                    $form1.remove_Load($Form_StateCorrection_Load)
                    $form1.remove_FormClosed($Form_Cleanup_FormClosed)
                }
                catch [Exception]
                { }
            }
            #endregion Generated Events

            #region Generated Form Code

            # form1

            $form1.Controls.Add($webbrowser1)
            $form1.Controls.Add($buttonYes)
            $form1.AcceptButton = $buttonYes
            $form1.Controls.Add($buttonCancel)
            $form1.CancelButton = $buttonCancel
            $form1.ClientSize = '520, 520' # '520, 475'
            $form1.FormBorderStyle = 'FixedDialog'
            $form1.MaximizeBox = $False
            $form1.MinimizeBox = $False
            $form1.Name = "form1"
            $form1.StartPosition = 'CenterScreen'
            $form1.Text = "Please review before sending"
            $form1.add_Load($FormEvent_Load)

            # webbrowser1

            $webbrowser1.Location = '30, 27'
            $webbrowser1.MinimumSize = '20, 20'
            $webbrowser1.Name = "webbrowser1"
            $webbrowser1.Size = '469, 450' # '469, 385'
            $webbrowser1.TabIndex = 1

            # buttonYes

            $buttonYes.Anchor = 'Bottom, Left'
            $buttonYes.DialogResult = 'Yes'
            $buttonYes.Location = '433, 485'
            $buttonYes.Name = "buttonYes"
            $buttonYes.Size = '75, 23'
            $buttonYes.TabIndex = 0
            $buttonYes.Text = "Send"
            $buttonYes.UseVisualStyleBackColor = $True

            # buttonCancel

            $buttonCancel.Anchor = 'Bottom, Right'
            $buttonCancel.DialogResult = 'Cancel'
            $buttonCancel.Location = '30, 485'
            $buttonCancel.Name = "buttonCancel"
            $buttonCancel.Size = '75, 23'
            $buttonCancel.TabIndex = 0
            $buttonCancel.Text = "Cancel"
            $buttonCancel.UseVisualStyleBackColor = $True

            #endregion Generated Form Code

            #Save the initial state of the form
            $InitialFormWindowState = $form1.WindowState
            #Init the OnLoad event to correct the initial state of the form
            $form1.add_Load($Form_StateCorrection_Load)
            #Clean up the control events
            $form1.add_FormClosed($Form_Cleanup_FormClosed)
            #Show the Form
            return $form1.ShowDialog()
        }
    }

    process
    {
        $Body = @"

$($Identity.GivenName)),

Sup from the IT Department?

$FromDisplayName
$FromTitle
$FromDept
$FromOrg

"@
        $HtmlPath = "$Env:Temp\NameChange$(Get-Random).html"
        $Body | Out-File -FilePath $HtmlPath
        $Result = Start-WebBrowser -HtmlPath $HtmlPath
        Exit-Application
        Remove-Item -Path $HtmlPath -ErrorAction SilentlyContinue

        if ($Result -eq 'Yes')
        {
            $Splat = @{
                From = $From
                To = $Identity.UserPrincipalName
                Subject = $MessageSubject
                BodyAsHtml = $true
                Body = $Body
                SMTPServer = $SMTPServer
            }

            Send-MailMessage @Splat
        }
        else
        {
            Write-Warning -Message "Message send canceled!"
        }
    }
}

You’d just need to customize the $Body here-string to make it say what you want.

P.S. I didn’t write all the forms code - I found it somewhere in a blog but can’t find the original source at the moment. If I do I’ll credit the author here.

Thanks for your replies. Ithink i can manange it now :slight_smile:

I used the CreateItemFromTemplate like that:

param(
     [Parameter(Mandatory=$true)]
     [String]$Group
     )
 
# Active Directory Modul laden
Import-Module ActiveDirectory
 
 echo $Group
 
# Email-Adressen ermitteln
$EmailAddresses = Get-ADGroupMember $Group -Recursive | Get-ADUser -Properties mail | Select mail
 echo $EmailAddresses
ForEach ($EmailAddress In $EmailAddresses){
  $OLAddresses = $EmailAddress.mail + ";" + $OLAddresses
}
 
# Outlookmail erstellen
$OL = New-Object -comObject Outlook.Application  
$Mail = $OL.CreateItem(0)
$Body = $OL.CreateItemFromTemplate("$path") #$path is just an example
$Mail.Body = $Body
$Mail.TO = $OLAddresses
#$Mail.BCC = $OLAddresses
$Mail.Display()

But my Email Body is just filled with this: "System.__ComObject "

An object is returned from CreateItemFromTemplate, you need to select the Property that contains the body data.

$Body|gm

Just a guess though, $Body.Body

Edit:

Another thought after I posted, why create 2 items?

$Mail = $OL.CreateItemFromTemplate(“$path”)

Now the initial item has everything from your template, including subject, default addresses, etc.

Simple but effective, it works thanks :slight_smile: