Outlook on the web
On-prem: Supports one signature (New Email preferred).
Cloud: Combines with Roaming Signatures for mobile browser access.
What it needs, how it works and how to use it
Most companies choose the same default setup for their environment:
The best for this scenario is to run Set-OutlookSignatures on each user's primary device as described in the Quickstart guide: Depending on your needs and environment, you may realize this with a logon script, a scheduled task, a desktop icon, a desired state configuration, or other methods.
Of course, users never see Set-OutlookSignatures - signatures are just there and always up-to-date.
You then add the Outlook add-in to the mix to make signatures available in Outlook running on secondary devices (Outlook on Android, Outlook on iOS, etc.). This also covers the use of Outlook on devices that are not managed, such as accessing the company mailbox from Outlook installed on a private computer.
Sometimes, this default scenario is not possible or not wanted. Examples are:
Set-OutlookSignatures and the Benefactor Circle add-on support all these scenarios by offering differing methods for the creation of signatures as well as for making these signatures available to end users.
Contrary to other solutions, you do not have to decide for one fixed combination of these methods - you can mix and match different combinations to perfectly meet your requirements.
Our recommendation is also the scenario used most often by our customers:
The following chapters dive deeper into the differences between creating signatures and out-of-office replies, and making signatures available to end users. They also describe which options are available, what their pros and cons are, and when they are used best.
Set-OutlookSignatures comes with client mode, the Benefactor Circle add-on adds SimulateAndDeploy mode.
While building the base for SimulateAndDeploy, pure simulation mode is not discussed here as it is not intended to be used for mass deployment but as a quality control feature.
| Client mode | SimulateAndDeploy | |
|---|---|---|
| Advantages |
Uses idle resources on end user devices (Linux, Windows, macOS). Runs within the security context of the logged-on user. Is typically run more often, usually every two hours or at every log-on. |
Users do not need a primary device that is managed and runs Linux, macOS or Windows. Software or at least configuration must only be deployed to involved central systems. |
| Disadvantages |
End users must log on to a device (Linux, Windows, macOS), not just to Outlook. The primary device of each user must be managed und run Windows, Linux or macOS. Software or at least configuration must be deployed to many decentral systems. |
Uses one or more central systems, which need according resources. Runs within the security context of a service account requiring (temporary) full access to all user mailboxes. Is typically run less frequent, usually once a day or less often. Can only see and influence the configuration of Outlook on the web, reducing the feature set of Set-OutlookSignatures to what is possible in simulation mode. |
| Recommended for |
Users logging on to a primary device that is managed and runs Linux, Windows or macOS. |
Scenarios where you cannot or do not want to run Set-OutlookSignatures in the context of the logged-on user. |
With the Benefactor Circle add-on, both modes can set out-of-office replies for internal and external recipients, and also deploy signatures for mailboxes (and other Exchange recipient objects) the user has access to but not added to Outlook (see VirtualMailboxConfigFile for details, and combine it with Export-RecipientPermissions for maximum automation).
In client mode, signatures are automatically made available to the local Outlook installation. With the Benefactor Circle add-on, client mode also makes signatures available in the 'Documents' folder of the logged-on user.
SimulateAndDeploy mode has no access to end user devices and therefore treats Outlook on the web as the local Outlook installation. It cannot not make signatures available in a user's 'Documents' folder.
With the Benefactor Circle add-on active, both modes per default also make signatures available in Outlook on the web, as roaming signatures (cloud only), for use with the Outlook add-in, and in a draft email:
Outlook on the web
On-prem: Supports one signature (New Email preferred).
Cloud: Combines with Roaming Signatures for mobile browser access.
Roaming Signatures
Exchange Online feature; stores signatures in the mailbox.
Synchronized via our engine across Linux, Windows, and macOS to avoid native sync issues.
Outlook Add-in
Perfect for Android, iOS, and unmanaged BYOD devices.
Automatic signature selection based on sender and many other properties, interactive taskpane for manual insertion.
Draft Email
Universal compatibility via copy-paste.
Creates a draft email containing all signatures in HTML and plain text for clients like Apple Mail, Gmail, and Thunderbird.
Documents Folder
File-level access across all synchronized devices.
Exports signatures to a local path (e.g. synced OneDrive) for easy access in non-Outlook clients.
The security model of Set-OutlookSignatures and the Benefactor Circle add-on is built on the principles of Digital Sovereignty, Least Privilege, and Need to Know.
Unlike many competitors who bury their permission requirements deep within technical documentation (often to obscure the extent of data access required), we provide a transparent, granular matrix of exactly what is needed and why.
When running in client mode for on-premises mailboxes, no additional permissions or Graph API registrations are required. The script runs in the context of the logged-on user, who already possesses all the necessary permissions required to manage its signatures and out-of-office replies.
In Exchange Online, the security posture is even tighter. The delegated permissions requested by the application are actually a subset of the user's total permissions — the script can only access the specific Graph endpoints required for signature and OOF management, rather than having the full range of actions the logged-on user could manually perform.
| Permission | Client mode | SimulateAndDeploy | Outlook add‑in | Required for |
|---|---|---|---|---|
| Setup instructions | Manual setup: .\config\default graph config.ps1Scripted setup via .\sample code\Create-EntraApp.ps1 |
Manual setup: .\sample code\SimulateAndDeploy.ps1Scripted setup via .\sample code\Create-EntraApp.ps1 |
Manual setup: Add-in documentation Scripted setup via .\sample code\Create-EntraApp.ps1 |
|
| All environments: Full access to mailboxes | ● Required | Access to roaming signatures in Exchange Online. Direct-to-mailbox sync on-prem. | ||
| All environments: Outlook add-in manifest, ReadWriteMailbox | ● Required | Set signature. | ||
| Cloud Only: Graph API, delegated, email | ● Required | ● Required | Log on the current user. | |
| Cloud Only: Graph API, delegated, Files.Read.All | ○ Optional | ○ Optional | Access templates and config stored in SharePoint Online. Use Files.SelectedOperations.Selected as fine-grained alternative. | |
| Cloud Only: Graph API, delegated, GroupMember.Read.All | ● Required | ● Required | ● Required | Find groups, get SIDs, and check license groups. |
| Cloud Only: Graph API, delegated, Mail.Read | ● Required | Required because of Microsoft restrictions accessing roaming signatures. | ||
| Cloud Only: Graph API, delegated, Mail.ReadWrite | ● Required | ● Required | Connect to Outlook on the web. Set Outlook signatures. | |
| Cloud Only: Graph API, delegated, MailboxConfigItem.ReadWrite | ● Required | ● Required | Connect to Outlook on the web. Set Outlook signatures. | |
| Cloud Only: Graph API, delegated, MailboxSettings.ReadWrite | ● Required | ● Required | Detect OOF state and set OOF replies. | |
| Cloud Only: Graph API, delegated, offline_access | ● Required | ● Required | Get a refresh token from Graph. | |
| Cloud Only: Graph API, delegated, openid | ● Required | ● Required | Log on the current user. | |
| Cloud Only: Graph API, delegated, profile | ● Required | ● Required | Log on the current user and get basic properties. | |
| Cloud Only: Graph API, delegated, User.Read.All | ● Required | ● Required | ● Required | Get values for replacement variables. UPN lookup. |
| Cloud Only: Graph API, application, Files.Read.All | ○ Optional | Access templates and config stored in SharePoint Online. Use Files.SelectedOperations.Selected as fine-grained alternative. | ||
| Cloud Only: Graph API, application, GroupMember.Read.All | ● Required | Find groups, get SIDs, and check license groups. | ||
| Cloud Only: Graph API, application, Mail.ReadWrite | ● Required | Connect to Outlook on the web. Set Outlook signatures. | ||
| Cloud Only: Graph API, application, MailboxConfigItem.ReadWrite | ● Required | Connect to Outlook on the web. Set Outlook signatures. | ||
| Cloud Only: Graph API, application, MailboxSettings.ReadWrite | ● Required | Detect OOF state and set OOF replies. | ||
| Cloud Only: Graph API, application, User.Read.All | ● Required | Get values for replacement variables. UPN lookup. |
You need Exchange Online or Exchange on-prem.
Set-Outlook can run on Linux, macOS or Windows systems with PowerShell:
Set-OutlookSignatures can run in two modes. See 'Architecture considerations' later in this document for details. In short:
On Windows, Outlook and Word are usually required, but not in all constellations:
Signature templates can be in DOCX (Windows) or HTML format (Windows, Linux, macOS). Set-OutlookSignatures comes with sample templates in both formats.
The software must run in PowerShell Full Language mode. Constrained Language mode is not supported, as some features such as Base64 conversions are not available in this mode or require very slow workarounds.
On Windows and macOS, unblock the file 'Set-OutlookSignatures.ps1'. You can use the PowerShell cmdlet 'Unblock-File' for this, or right-click the file in File Explorer, select Properties and check 'Unblock'.
This removes the 'mark of the web', which can prevent script execution when the PowerShell execution policy is set to RemoteSigned.
If you use AppLocker or a comparable solution (Defender, CrowdStrike, Ivanti, and others), you may need to add the existing digital file signature to your allow list, or define additional settings in your security software.
Thanks to our partnership with ExplicIT Consulting, Set-OutlookSignatures and its components are digitally signed with an Extended Validation (EV) Code Signing Certificate (which is the highest code signing standard available).
This is not only available for Benefactor Circle members, but also the Free and Open Source core version is code signed.
The paths to the template and configuration files (SignatureTemplatePath, OOFTemplatePath, GraphConfigFile, etc.) must be accessible by the currently logged-in user. The files must be at least readable for the currently logged-in user.
In cloud environments, you need to register Set-OutlookSignatures as Entra ID app and provide admin consent for the required permissions. See the Quickstart guide or '.\config\default graph config.ps1' for details.
Not all features of Set-OutlookSignatures and the Benefactor Circle add-on are yet available or possible on Linux and macOS. Every parameter contains appropriate information, which are summarized below.
These restrictions only apply to Set-OutlookSignatures and the Benefactor Circle add-on, the Outlook add-in is not affected.
GraphOnly is automatically set to true and Linux and macOS, which requires an Entra ID app - the Quickstart guide helps you implement this.UseHtmTemplates is automatically set to true on Linux and macOS.SignatureTemplatePath, SignatureIniFile, OOFTemplatePath, OOFIniFile, AdditionalSignaturePath, ReplacementVariableConfigFile, GraphConfigFile, etc.). The default values for these parameters are automatically set correctly, so that you can follow the Quickstart guide without additional configuration. When hosting GraphConfigFile on SharePoint Online make sure you also define the GraphClientID parameter.As mentioned before: These restrictions only apply to Set-OutlookSignatures and the Benefactor Circle add-on, the Outlook add-in is not affected.
$([IO.Path]::Combine([environment]::GetFolderPath('MyDocuments'), 'Outlook Signatures')) per default (parameter AdditionalSignaturePath).$([IO.Path]::Combine([environment]::GetFolderPath('MyDocuments'), 'Outlook Signatures')) per default (parameter AdditionalSignaturePath).When no Active Directory connection is available or the GraphOnly parameter is set to true, Entra ID is queried for transitive group membership via the Graph API. This query includes security and distribution groups.
Transitive means that not only direct group membership is considered, but also the membership resulting of groups being members of other groups, a.k.a. nested or indirect membership.
In Microsoft Graph, membership in dynamic groups is automatically considered.
When an Active Directory connection is available and the GraphOnly parameter ist not set to true, Active Directory is queried via LDAP.
Per default, all static security and distribution groups of group scopes global and universal are considered.
Group membership is evaluated against the whole Active Directory forest of the mailbox, and against all trusted domains (and their subdomains) the user has access to.
Group membership is evaluated transitively. Transitive means that not only direct group membership is considered, but also the membership resulting of groups being members of other groups, a.k.a. nested or indirect membership.
When Active Directory is used, SIDHistory is always included when evaluating group membership.
In Exchange resource forest scenarios with linked mailboxes, the group membership of the linked account (as populated in msExchMasterAccountSID) is not considered, only the group membership of the actual mailbox.
Group membership from Active Directory is retrieved by combining queries:
Only static groups are considered. Please see the FAQ section for detailed information why dynamic groups are not included in group membership queries on-prem.
Per default, the mailbox's own forest is not checked for membership in domain local groups, no matter if of type security or distribution. This is because querying for membership in domain local groups cannot be done fast, as there is no cache and every domain local group domain in the forest has to be queried for membership. Also, domain local groups are usually not used when granting permissions in Exchange. You can enable searching for domain local groups in the mailbox's forest by setting the parameter IncludeMailboxForestDomainLocalGroups to $true.
Outlook and Set-OutlookSignatures can run simultaneously.
On Windows, Outlook is never run or stopped by Set-OutlookSignatures. On macOS, Outlook may be started in the background, as this is a required by Outlook's engine for script access.
New and changed signatures can be used instantly in Outlook.
Changing which signature name is to be used as default signature for new emails or for replies and forwards requires restarting Outlook.
Only Word files with the extension .docx and HTML files with the extension .htm are supported as signature and OOF template files.
The name of the signature template file without extension is the name of the signature in Outlook. Example: The template "Test signature.docx" will create a signature named "Test signature" in Outlook.
This can be overridden in the INI file with the 'OutlookSignatureName' parameter. Example: The template "Test signature.htm" with the following INI file configuration will create a signature named "Test signature, do not use".
[Test signature.htm]
OutlookSignatureName = Test signature, do not use
To make life easier for template maintainers and for users, a consistent template and signature naming convention should be used.
There are multiple approaches, with the following one gaining popularity: <Company> <internal/external> <Language> <formal/informal> <additional info>
Let's break down the components:
Example signature names for a user having access to his own mailbox and the office mailbox:
For the user, the selection process may look complicated at first sight, but is actually quite natural and fast:
Don't forget: You can use one and the same template for different signature names. In the example above, the template might not be named CompA ext EN frml office@.docx, but CompA ext EN frml shared@.docx and be used multiple times in the INI file:
# office@example.com
[CompA ext EN frml shared@.docx]
office@example.com
OutlookSignatureName = CompA ext EN frml office@
DefaultNew
# marketing@example.com
[CompA ext EN frml shared@.docx]
marketing@example.com
OutlookSignatureName = CompA ext EN frml marketing@
DefaultNew
Tags define properties for templates, such as
There are additional tags which are not template specific, but change the behavior of Set-OutlookSignatures:
If you want to give template creators control over the INI file, place it in the same folder as the templates.
Tags are case insensitive.
<yyyyMMddHHmm-yyyyMMddHHmm>, -:<yyyyMMddHHmm-yyyyMMddHHmm>
yyyy = year, MM = month, dd = day, HH = hour (00-24), mm = minute).-: prefix makes this template invalid during the specified time range.202112150000-202112262359 for the 2021 Christmas season, -:202202010000-202202282359 for a deny in February 2022202112150000Z-202112262359Z<DNS or NetBIOS name of AD domain> <SamAccountName of group>, <DNS or NetBIOS name of AD domain> <Display name of group>, -:<DNS or NetBIOS name of AD domain> <SamAccountName of group>, -:<DNS or NetBIOS name of AD domain> <Display name of group>
-: prefix makes this template invalid for the specified group.EXAMPLE Domain Users, -:Example GroupAEveryone and Authenticated Users only exist locally, not in Active Directory or Entra ID.<DNS or NetBIOS name of AD domain> <SamAccountName of group> and <DNS or NetBIOS name of AD domain> <Display name of group> can be queried from Microsoft Graph if the groups are synced between on-prem and the cloud. SamAccountName is queried before DisplayName. Use these formats when your environment is hybrid or on premises.EntraID <Object ID of group>, EntraID <securityIdenfifier of group>, EntraID <email-address-of-group@example.com>, EntraID <mailNickname of group>, EntraID <DisplayName of group> do not work with a local Active Directory, only with Microsoft Graph. They are queried in the order given. You can use 'AzureAD' instead of 'EntraID'. 'EntraID' and 'AzureAD' are the literal, case-insensitive strings 'EntraID' and 'AzureAD', not a variable. Use these formats when you are in a hybrid or cloud only environment.EntraID and AzureAD always refer to the home tenant of the currently logged-in user. To address a specific tenant in cross-tenant scenarios (see GraphClientID for details), use one of the following formats: EntraID_<a registered DNS domain> (EntraID_example.onmicrosoft.com), or EntraID_<Tenant ID> (EntraID_00000000-0000-0000-0000-000000000000).<DNS or NetBIOS name of AD domain> and <EXAMPLE> are just examples. You need to replace them with the actual NetBios domain name of the Active Directory domain containing the group.<DNS or NetBIOS name of AD domain> <…> format, use the SamAccountName whenever possible. The combination of domain name and SamAccountName is unique, while a display name may exist multiple times in a domain.EntraID <…> format, prefer Object ID and securityIdentifier whenever possible. Object ID and securityIdentifier are always unique, email address and mailNickname can wrongly exist on multiple objects, and the uniqueness of displayName is in your hands.-GraphOnly true parameter, prefer Entra ID groups (EntraID <…>). You may also use on-prem groups (<DNS or NetBIOS name of AD domain> <…>) as long as they are synchronized to Entra ID.-GraphOnly true parameter, prefer on-prem groups (<DNS or NetBIOS name of AD domain> <…>) synchronized to Entra ID. Pure entra ID groups (EntraID <…>) only make sense when all mailboxes covered by Set-OutlookSignatures are hosted in Exchange Online.<DNS or NetBIOS name of AD domain> <…>). When moving to a hybrid environment, you do not need to adapt the configuration as long as you synchronize your on-prem groups to Entra ID.CURRENTUSER:<syntax of "Assign template to group">
Example: Assign template to every mailbox, but not if the mailbox of the current user is member of the group EXAMPLE\Group
[template.docx]
-CURRENTUSER:EXAMPLE Group
<SmtpAddress>, -:<SmtpAddress>
-: prefix makes this template invalid for the specified email address.office@example.com, -:test@example.comCURRENTUSER: and -CURRENTUSER: prefixes make this template invalid for the specified email addresses of the current user.Useful for delegate or boss-secretary scenarios: "Assign a template to everyone having the boss mailbox userA@example.com in Outlook, but not for UserA itself" is realized like that in the INI file:
[delegate template name.docx]
# Assign the template to everyone having userA@example.com in Outlook
userA@example.com
# Do not assign the template to the actual user owning the mailbox userA@example.com
-CURRENTUSER:userA@example.com
You can even only use only one delegate template for your whole company to cover all delegate scenarios. Make sure the template correctly uses $CurrentUser[…]$ and $CurrentMailbox[…]$ replacement variables, and then use the template multiple times in the INI file, with different signature names:
[Company EN external formal delegate.docx]
# Assign the template to everyone having userA@example.com in Outlook
userA@example.com
# Do not assign the template to the actual user owning the mailbox userA@example.com
-CURRENTUSER:userA@example.com
# Use a custom signature name instead of the template file name
OutlookSignatureName = Company EN external formal userA@
[Company EN external formal delegate.docx]
# Assign the template to everyone having userX@example.com in Outlook
userX@example.com
# Do not assign the template to the actual user owning the mailbox userX@example.com
-CURRENTUSER:userX@example.com
# Use a custom signature name instead of the template file name
OutlookSignatureName = Company EN external formal UserX@
<ReplacementVariable>, -:<ReplacementVariable>
-: prefix makes this template invalid for the specified replacement variable.$CurrentMailboxManagerMail$ (apply if current user has a manager with an email address)-:$CurrentMailboxManagerMail$ (do not apply if current user has a manager with an email address)Use a custom replacement variable config file, define the custom replacement variable $CurrentMailbox-IsMemberOf-MarketingAndSales$ and set it to yes if the current user's mailbox is member of the Marketing and the Sales groups at the same time:
@(
@('CurrentUser', '$CurrentUser-IsMemberOf-MarketingAndSales$', 'EXAMPLEDOMAIN Marketing', 'EXAMPLEDOMAIN Sales'),
@()
) | Where-Object { $_ } | ForEach-Object {
if (
$((Get-Variable -Name "ADProps$($_[0])" -ValueOnly).GroupsSids -icontains $(ResolveToSid($_[2]))) -and
$((Get-Variable -Name "ADProps$($_[0])" -ValueOnly).GroupsSids -icontains $(ResolveToSid($_[3])))
) {
$ReplaceHash[$_[1]] = 'yes'
} else {
$ReplaceHash[$_[1]] = $null
}
}
The template INI configuration then looks like this:
[template.docx]
$CurrentUser-IsMemberOf-MarketingAndSales$
If you want a template only to not be applied to users whose primary mailbox is a of the Marketing group and the Sales group at the same time:
[template.docx]
-:$CurrentUser-IsMemberOf-MarketingAndSales$
Combinations are possible: Only in January 2024, for all members of EXAMPLEDOMAIN\Examplegroup but not for the mailbox example@example.com and not for users whose primary mailbox is a of the Marketing group and the Sales group at the same time:
[template.docx]
202401010000-202401312359
EXAMPLEDOMAIN Examplegroup
-:example@example.com
-:$CurrentUser-IsMemberOf-MarketingAndSales$
writeProtect
defaultNew (signature template files only)
defaultReplyFwd (signature template files only)
internal (OOF template files only)
internal nor external is defined, the template is set as default OOF message for internal and external recipientsexternal (OOF template files only)
internal nor external is defined, the template is set as default OOF message for internal and external recipients
Tags can be combined: A template may be assigned to several groups, email addresses and time ranges, be denied for several groups, email adresses and time ranges, be used as default signature for new emails and as default signature for replies and forwards - all at the same time. Simple add different tags below a file name, separated by line breaks (each tag needs to be on a separate line).
.\templates\Signatures DOCX with ini and .\templates\Out-of-Office DOCX with ini as templates and starting point[Company external English formal.docx][file a.docx] is the same as ["File A.docx"] and ['fILE a.dOCX']$CurrentMailbox[…]$ variables. A user can have multiple of these shared mailboxes in his Outlook configuration.
template shared mailbox A.docxtemplate shared mailbox B.docxtemplate shared mailbox C.docxINI file
[template shared mailbox A.docx]
SharedMailboxA@example.com
[template shared mailbox B.docx]
SharedMailboxB@example.com
[template shared mailbox C.docx]
SharedMailboxC@example.com
template shared mailboxes.docxINI file
[template shared mailboxes.docx]
SharedMailboxA@example.com
OutlookSignatureName = template SharedMailboxA
[template shared mailboxes.docx]
SharedMailboxB@example.com
OutlookSignatureName = template SharedMailboxB
[template shared mailboxes.docx]
SharedMailboxC@example.com
OutlookSignatureName = template SharedMailboxC
You can even only use only one delegate template for your whole company to cover all delegate scenarios. Make sure the template correctly uses $CurrentUser[…]$ and $CurrentMailbox[…]$ replacement variables, and then use the template multiple times in the INI file, with different signature names:
[Company EN external formal delegate.docx]
# Assign the template to everyone having userA@example.com in Outlook
userA@example.com
# Do not assign the template to the actual user owning the mailbox userA@example.com
-CURRENTUSER:userA@example.com
# Use a custom signature name instead of the template file name
OutlookSignatureName = Company EN external formal userA@
[Company EN external formal delegate.docx]
# Assign the template to everyone having userX@example.com in Outlook
userX@example.com
# Do not assign the template to the actual user owning the mailbox userX@example.com
-CURRENTUSER:userX@example.com
# Use a custom signature name instead of the template file name
OutlookSignatureName = Company EN external formal UserX@
defaultNew
defaultNew is the same as DefaultNew and dEFAULTnEWOutlookSignatureName = This is a custom signature nameSignatureIniFile and/or OOFIniFile parameterSignatures are applied mailbox for mailbox. The mailbox list is sorted as follows (from highest to lowest priority):
For each mailbox, templates are applied in a specific order:
Within these template groups, templates are sorted according to the SortOrder and SortCulture parameters defined in the INI file used.
Every template is only applied to the mailbox with the highest priority allowed to use it. This ensures that no mailbox with lower priority can overwrite a signature intended for a higher priority mailbox. You can influence this behavior with the MailboxSpecificSignatureNames parameter or the OutlookSignatureName template option in the INI file.
OOF templates are only applied if the out-of-office assistant is currently disabled. If it is currently active or scheduled to be automatically activated in the future, OOF templates are not applied.
Replacement variables are case insensitive placeholders in templates which are replaced with actual user or mailbox values at runtime.
Replacement variables are replaced everywhere, including links, QuickTips and alternative text of images.
With this feature, you cannot only show email addresses and telephone numbers in the signature and OOF message, but show them as links which open a new email message ("mailto:") or dial the number ("tel:") via a locally installed softphone when clicked.
Custom Active directory attributes are supported as well as custom replacement variables, see .\config\default replacement variables.ps1 for details.
Attributes from Microsoft Graph need to be mapped, this is done in .\config\default graph config.ps1.
Variables can also be retrieved from other sources than Active Directory by adding custom code to the variable config file.
Per default, .\config\default replacement variables.ps1 contains the following replacement variables:
$CurrentUserGivenName$: Given name$CurrentUserSurname$: Surname$CurrentUserDepartment$: Department$CurrentUserTitle$: (Job) Title$CurrentUserStreetAddress$: Street address$CurrentUserPostalcode$: Postal code$CurrentUserLocation$: Location$CurrentUserState$: State$CurrentUserCountry$: Country$CurrentUserTelephone$: Telephone number$CurrentUserFax$: Facsimile number$CurrentUserMobile$: Mobile phone$CurrentUserMail$: email address$CurrentUserPhoto$: Photo from Active Directory or Entra ID, see "9.1. Photos (account pictures, user image) from Active Directory or Entra ID" for details$CurrentUserPhotoDeleteEmpty$: Photo from Active Directory or Entra ID, see "9.1. Photos (account pictures, user image) from Active Directory or Entra ID" for details$CurrentUserExtAttr1$ to $CurrentUserExtAttr15$: Exchange extension attributes 1 to 15$CurrentUserOffice$: Office room number (physicalDeliveryOfficeName)$CurrentUserCompany$: Company$CurrentUserMailNickname$: Alias (mailNickname)$CurrentUserDisplayName$: Display Name$CurrentUserManager[…]$ instead of $CurrentUser[…]$$CurrentMailbox[…]$ instead of $CurrentUser[…]$$CurrentMailboxManager[…]$ instead of $CurrentMailbox[…]$The software supports replacing images in signature templates with photos stored in Active Directory.
When using images in OOF templates, please be aware that Exchange and Outlook do not yet support images in OOF messages.
As with other variables, photos can be obtained from the currently logged-in user, its manager, the currently processed mailbox and its manager.
Set-Outlooksignatures comes with the following default replacement variables for handling account pictures:
$CurrentUserPhoto$$CurrentUserPhotoDeleteEmpty$$CurrentUserManagerPhoto$$CurrentUserManagerPhotoDeleteEmpty$$CurrentMailboxPhoto$$CurrentMailboxPhotoDeleteEmpty$$CurrentMailboxManagerPhoto$$CurrentMailboxManagerPhotoDeleteEmpty$When using DOCX template files, there are two ways you can embed account pictures: The shape option or the "link and embed" option.
Both ways allow to apply Word image features such as sizing, a shadow, a glow or a reflection. The shape option allows for more graphical freedom, as you can use arrows, stars and many more as container for account pictures.
The crucial part for both ways is to set the text wrapping to "inline with text". If you don't, Outlook and other email clients will not place the image in the correct place as the position of floating shapes in Word cannot reliably be translated to HTML.
The sample signature template Test all default replacement variables contains examples for both ways, as well as some images formatted as "floating" images.
Steps for the shape option:
$CurrentUserPhoto$) to the alternative text of the shape.Steps for the "link and embed" option:
Insert | Pictures | This device (Word 2019, other versions have the same feature in different menus) and to select the option Insert and Link - if you forget this step, a specific Word property is not set and the software will not be able to replace the image.$CurrentUserPhoto$) to the alternative text of the shape.When Set-OutlookSignatures finds a shape in a template file with an image replacement variable in its alternative text, it fills the shape with the account picture.
When Set-Outlooksignatures finds a linked and embedded image in a template file with an image replacement variable in its alternative text, it replaces the image with the account picture (as if you would use Word's "Change picture" function).
Images are replaced when the src or alt property of the image tag contains an image replacement variable.
Be aware that Outlook does not support the full HTML feature set. For example:
width and height properties for embedded images.Test all default replacement variables.files in the sample templates folder) and additionally set the Set-OutlookSignatures parameter 'EmbedImagesInHtml' to ``false`.If there is no photo available in Active Directory, there are two options:
$Current[…]Photo$ variables: The sample image used as placeholder is shown in the signature.$Current[…]PhotoDeleteempty$ variables: The sample image used as placeholder is deleted from the signature, which may affect the layout of the remaining signature depending on your formatting options.Attention: A signature with embedded images has the expected file size in DOCX, HTML and TXT formats, but the RTF file will be much bigger.
The signature template .\templates\Signatures DOCX\Test all signature replacement variables.docx contains several embedded images and can be used for a file comparison:
The software uses a workaround, but the resulting RTF files are still huge compared to other file types and especially for use in emails. If this is a problem, please either do not use embedded images in the signature template (including photos from Active Directory), or switch to HTML formatted emails.
If you ran into this problem outside this script, consider modifying the ExportPictureWithMetafile registry key as described in the Microsoft Knowledge Base article 224663. This is one of many articles that have not been migrated to the new learn.microsoft.com platform and are no longer available on microsoft.com, but you can give Beta Archive's snapshot of the article a try.
You can avoid creating multiple templates which only differ by the images contained by only creating one template containing all images and marking this images to be deleted when a certain replacement variable is empty.
Just add the text $<name of the replacement variable>DELETEEMPTY$ (for example: $CurrentMailboxExtAttr10DeleteEmpty$ ) to the description or alt text of the image. Taking the example, the image is deleted when extension attribute 10 of the current mailbox is empty.
This can be combined with the GroupsSIDs attribute of the current mailbox or current user to only keep images when the mailbox is member of a certain group.
Examples:
IncludeMailboxForestDomainLocalGroups parameter to true when running Set-OutlookSignatures, so that the SIDs of these groups are considered too.You only have to modify three strings right at the beginning:
# Check if current mailbox is member of group 'EXAMPLEDOMAIN\Marketing' and set $ReplaceHash['$CurrentMailbox-ismemberof-marketing$'] accordingly
#
# Replace 'EXAMPLEDOMAIN Marketing' with the domain and group you are searching for. Use 'EntraID' or 'AzureAD' instead of 'EXAMPLEDOMAIN' to only search Entra ID/Graph
# Replace '$CurrentMailbox-ismemberof-marketing$' with the replacement variable that should be used
# Replace 'CurrentMailbox' with 'CurrentUser' if you do not want to check the current mailbox group SIDs, but the group SIDs of the current user's mailbox
#
# The 'GroupsSIDs' attribute is available for the current mailbox and the current user, but not for the managers of these two
# It contains the mailboxes' SID and SIDHistory, the SID and SIDHistory of all groups the mailbox belongs to (nested), and also considers group membership (nested) across trusts.
# Attention on-prem users: If Active Directory groups of the Domain Local type are queried, you need to set the `IncludeMailboxForestDomainLocalGroups` parameter to `true` when running Set-OutlookSignatures, so that the SIDs of these groups are considered in GroupsSIDs, too.
@(
@('CurrentMailbox', '$CurrentMailbox-IsMemberOf-Marketing$', 'EXAMPLEDOMAIN Marketing'),
@()
) | Where-Object { $_ } | ForEach-Object {
if ((Get-Variable -Name "ADProps$($_[0])" -ValueOnly).GroupsSids -icontains ResolveToSid($_[2])) {
$ReplaceHash[$_[1]] = 'yes'
} else {
$ReplaceHash[$_[1]] = $null
}
}
You can fill custom image replacement variables yourself with a byte array: $CurrentUserCustomImage[1..10]$, $CurrentUserManagerCustomImage[1..10]$, $CurrentMailboxCustomImage[1..10]$, $CurrentMailboxManagerCustomImage[1..10]$.
Use cases: Account pictures from a share, QR code vCard/URL/text/Twitter/X/Facebook/App stores/geo location/email, etc.
Per default, $Current[..]CustomImage1$ is a QR code containing a vCard (in MeCard format) - see file .\config\default replacement variables.ps1 for the code behind it.
The behavior of custom image replacement variables and the possible configuration options are the same as with replacement variables for account pictures from Active Directory/Entra ID.
As practical as QR codes may be, they should contain as little information as possible. The more information they contain, the larger the image needs to be, which often has a negative impact on the layout and always has a negative impact on the size of the email.
QR codes with too much information and too small an image size become visually blurred, making them impossible to scan - for DOCX templates, DocxHighResImageConversion can help. Consider bigger image size, less content, less error correction, MeCard instead of vCard, and pointing to an URL containing the actual information.
If the currently logged-in user has configured his personal mailbox in Outlook, the default signature for new emails is configured in Outlook on the web automatically.
If the default signature for new mails matches the one used for replies and forwarded email, this is also set in Outlook.
If different signatures for new and reply/forward are set, only the new signature is copied to Outlook on the web.
If only a default signature for replies and forwards is set, only this new signature is copied to Outlook on the web.
If there is no default signature in Outlook, Outlook on the web settings are not changed.
All this happens with the credentials of the currently logged-in user, without any interaction neccessary.
Set-OutlookSignatures supports three directory environments:
The software parameter GraphOnly defines which directory environment is used:
-GraphOnly false or not passing the parameter: On-prem AD first, Entra ID only when on-prem AD cannot be reached-GraphOnly true: Entra ID only, even when on-prem AD could be reachedTo allow communication between Microsoft Graph and Set-Outlooksignatures, both need to be configured for each other.
The easiest way is to once start Set-OutlookSignatures with a cloud administrator. The administrator then gets asked for admin consent for the correct permissions:
Set-OutlookSignatures.ps1 -GraphOnly trueIf you don't want to use custom Graph attributes or other advanced configurations, no more configuration in Microsoft Graph or Set-OutlookSignatures is required.
If you prefer using own application IDs or need advanced configuration, follow these steps:
.\config\default graph config.ps1..\config\default graph config.ps1 as a template for a custom Graph configuration file
$GraphClientID to the application ID created by the Graph administrator before, or pass this value using the GraphClientID parameter.GraphConfigFile parameter to make the tool use the newly created Graph configuration file.The Graph configuration file allows for additional, advanced configuration:
$GraphEndpointVersion: The version of the Graph REST API to use$GraphUserProperties: The properties to load for each graph user/mailbox. You can add custom attributes here.$GraphUserAttributeMapping: Graph and Active Directory attributes are not named identically. Set-OutlookSignatures therefore uses a "virtual" account. Use this hashtable to define which Graph attribute name is assigned to which attribute of the virtual account.$ADPropsCurrentUser[…] in .\config\default replacement variables.ps1, and therefore has a direct impact on replacement variables.In hybrid and cloud-only scenarios, Set-OutlookSignatures automatically tries multiple ways to authenticate the user. Silent methods, also known as non-interactive methods, are preferred as they are invisible to the user.
Get-MgDomain cmdlet from the Microsoft.Graph.Identity.DirectoryManagement PowerShell module.https://aka.ms/msal-net-iwa for details.When all silent authentication methods fail, a dialog informs the user that Set-OutlookSignatures requires interactive authentication. You can change the text displayed in the dialog or disable the dialog using a custom graph configuration file. See .\config\default graph config.ps1 for details and more options related to authentication against the Graph API.
No custom components are used, only the official Microsoft 365 authentication site, the user's default browser and the official Microsoft Authentication Library for .Net (MSAL.Net).
After successful authentication the refresh token is stored for later use by the silent authentication steps described above.
$(Join-Path -Path ([Environment]::GetFolderPath([Environment+SpecialFolder]::LocalApplicationData)) -ChildPath '\Set-OutlookSignatures\MSAL.PS\MSAL.PS.msalcache.bin3').
$(Join-Path -Path ([Environment]::GetFolderPath([Environment+SpecialFolder]::LocalApplicationData)) -ChildPath '\Set-OutlookSignatures\MSAL.PS\MSAL.PS.msalcache.bin3').$(Join-Path -Path ([Environment]::GetFolderPath([Environment+SpecialFolder]::LocalApplicationData)) -ChildPath '\Set-OutlookSignatures\MSAL.PS\MSAL.PS.msalcache.bin3').Set-OutlookSignatures always keeps you informed about where and how the token is stored, and how you can delete it to force re-authentication without using the cached refresh token:
Encrypted file '$($cacheFilePath)', delete file to remove cached tokenUnencrypted file '$($cacheFilePath)', delete file to remove cached tokenEncrypted default keyring entry 'Set-OutlookSignatures Microsoft Graph token via MSAL.Net', use keychain app to remove cached tokenUnencrypted file '$($cacheFilePath)', delete file to remove cached tokenEncrypted default keychain entry 'Set-OutlookSignatures Microsoft Graph token via MSAL.Net', use 'security delete-generic-password "Set-OutlookSignatures Microsoft Graph token via MSAL.Net"' to remove cached tokenUnencrypted file '$($cacheFilePath)', delete file to remove cached tokenIf you want to see more information around authentication, run Set-OutlookSignatures with the "-verbose" parameter.
If a user executes Set-OutlookSignatures on a client several times in succession and is asked for authentication each time:
Simulation mode is enabled when the parameter SimulateUser is passed to the software. It answers the question "What will the signatures look like for user A, when Outlook is configured for the mailboxes X, Y and Z?".
Simulation mode is useful for content creators and admins, as it allows to simulate the behavior of the software and to inspect the resulting signature files before going live. Such a dry-run is not only very helpful for running tests in the production environment without affecting anyone, it also greatly supports problem analysis.
In simulation mode, Outlook registry entries are not considered and nothing is changed in Outlook and Outlook on the web. The template files are handled just as during a real script run, but the signatures are only saved to the folder defined by the AdditionalSignaturePath parameter.
SimulateUser is a mandatory parameter for simulation mode. This value replaces the currently logged-in user. Use a logon name in the format 'Domain\User' or a Universal Principal Name (UPN, looks like an email address, but is not neecessarily one).
SimulateMailboxes is optional for simulation mode, although highly recommended. It is a comma separated list of email addresses replacing the list of mailboxes otherwise gathered from the registry.
SimulateTime is optional for simulation mode. Simulating a certain time is helpful when time-based templates are used.
An example: Simulate user a@example.com with the additional mailbox x@example.com, and save the results to 'c:\test':
& .\Set-OutlookSignatures.ps1 -SimulateUser 'a@example.com' -SimulateMailboxes 'a@example.com', 'x@example.com' -AdditionalSignaturePath 'c:\test'
Also see .\sample code\SimulationModeHelper.ps1 for sample code showing how to use simulation mode.