Deploying a Unified Email Signature Template in Outlook

Global Email Templates

I have been asked by several clients to create a global email template in Outlook so that businesses can maintain professional consistency when dealing with clients through email. Below, I will describe how to deploy a unified email signature template in Outlook 2003, 2007, and 2010.

PowerShell Script

I came across the following blog where I found a PowerShell script that claims to pull information from Active Directory and place it in a user’s Outlook signature.

Script Shortcomings

The script worked, but it had some shortcomings:

  • Email addresses are inserted as text instead of links
  • It used a complex process for changing the signature, which required modifying the script and multiple files on the server

Script Modifications

I modified the script to fix these issues. The following PowerShell script can be pushed out via Group Policy if you are running Windows Server 2008 R2 (Salespeople, looking to claw your way into 2003 to 2008 server upgrades, here’s your chance).

Use the Script over Group Policy

  1. Create a CompanyName.docx file with your signature (Use the following keywords: DisplayName, Title, Email)
  2. Ensure these fields are filled out for all users in Active Directory Users and Computers
  3. Copy this .docx file to your server under the following path \\domain\NETLOGON\sig_files\CompanyName\CompanyName.docx
  4. Ensure this script is set to run from Group Policy – download script file
 ###########################################################################" # # NAME: Set-OutlookSignature.ps1 # # AUTHOR: Jan Egil Ring # Modifications by Darren Kattan # # COMMENT: Script to create an Outlook signature based on user information from Active Directory. # Adjust the variables in the "Custom variables"-section # Create an Outlook-signature from Microsoft Word (logo, fonts etc) and copy this signature to \\domain\NETLOGON\sig_files\$CompanyName\$CompanyName.docx # This script supports the following keywords: # DisplayName # Title # Email # See the following blog-post for more information: http://blog.crayon.no/blogs/janegil/archive/2010/01/09/outlook-signature-based-on-user-information-from-active-directory.aspx # # Tested on Office 2003,2007 and 2010 # # You have a royalty-free right to use, modify, reproduce, and # distribute this script file in any way you find useful, provided that # you agree that the creator, owner above has no warranty, obligations, # or liability for such use. # # VERSION HISTORY: # 1.0 09.01.2010 - Initial release # 1.1 11.09.2010 - Modified by Darren Kattan # - Removed bookmarks. Now uses simple find and replace for DisplayName, Title, and Email. # - Email address is generated as a link # - Signature is generated from a single .docx file # - Removed version numbers for script to run. Script runs at boot up when it sees a change in the "Date Modified" property of your signature template. # 1.11 11.15.2010 - Revised by Darren Kattan # - Fixed glitch with text signatures # # ###########################################################################" #Custom variables $CompanyName = 'Immense Networks' $DomainName = 'IN.local' $SigSource = "\\$DomainName\netlogon\sig_files\$CompanyName" $ForceSignatureNew = '1' #When the signature are forced the signature are enforced as default signature for new messages the next time the script runs. 0 = no force, 1 = force $ForceSignatureReplyForward = '1' #When the signature are forced the signature are enforced as default signature for reply/forward messages the next time the script runs. 0 = no force, 1 = force #Environment variables $AppData=(Get-Item env:appdata).value $SigPath = '\Microsoft\Signatures' $LocalSignaturePath = $AppData+$SigPath $RemoteSignaturePathFull = $SigSource+'\'+$CompanyName+'.docx' #Get Active Directory information for current user $UserName = $env:username $Filter = "(&(objectCategory=User)(samAccountName=$UserName))" $Searcher = New-Object System.DirectoryServices.DirectorySearcher $Searcher.Filter = $Filter $ADUserPath = $Searcher.FindOne() $ADUser = $ADUserPath.GetDirectoryEntry() $ADDisplayName = $ADUser.DisplayName $ADEmailAddress = $ADUser.mail $ADTitle = $ADUser.title $ADTelePhoneNumber = $ADUser.TelephoneNumber #Setting registry information for the current user $CompanyRegPath = "HKCU:\Software\"+$CompanyName if (Test-Path $CompanyRegPath) {} else {New-Item -path "HKCU:\Software" -name $CompanyName} if (Test-Path $CompanyRegPath'\Outlook Signature Settings') {} else {New-Item -path $CompanyRegPath -name "Outlook Signature Settings"} $SigVersion = (gci $RemoteSignaturePathFull).LastWriteTime #When was the last time the signature was written $ForcedSignatureNew = (Get-ItemProperty $CompanyRegPath'\Outlook Signature Settings').ForcedSignatureNew $ForcedSignatureReplyForward = (Get-ItemProperty $CompanyRegPath'\Outlook Signature Settings').ForcedSignatureReplyForward $SignatureVersion = (Get-ItemProperty $CompanyRegPath'\Outlook Signature Settings').SignatureVersion Set-ItemProperty $CompanyRegPath'\Outlook Signature Settings' -name SignatureSourceFiles -Value $SigSource $SignatureSourceFiles = (Get-ItemProperty $CompanyRegPath'\Outlook Signature Settings').SignatureSourceFiles #Forcing signature for new messages if enabled if ($ForcedSignatureNew -eq '1') { #Set company signature as default for New messages $MSWord = New-Object -com word.application $EmailOptions = $MSWord.EmailOptions $EmailSignature = $EmailOptions.EmailSignature $EmailSignatureEntries = $EmailSignature.EmailSignatureEntries $EmailSignature.NewMessageSignature=$CompanyName $MSWord.Quit() } #Forcing signature for reply/forward messages if enabled if ($ForcedSignatureReplyForward -eq '1') { #Set company signature as default for Reply/Forward messages $MSWord = New-Object -com word.application $EmailOptions = $MSWord.EmailOptions $EmailSignature = $EmailOptions.EmailSignature $EmailSignatureEntries = $EmailSignature.EmailSignatureEntries $EmailSignature.ReplyMessageSignature=$CompanyName $MSWord.Quit() } #Copying signature sourcefiles and creating signature if signature-version are different from local version if ($SignatureVersion -eq $SigVersion){} else { #Copy signature templates from domain to local Signature-folder Copy-Item "$SignatureSourceFiles\*" $LocalSignaturePath -Recurse -Force $ReplaceAll = 2 $FindContinue = 1 $MatchCase = $False $MatchWholeWord = $True $MatchWildcards = $False $MatchSoundsLike = $False $MatchAllWordForms = $False $Forward = $True $Wrap = $FindContinue $Format = $False #Insert variables from Active Directory to rtf signature-file $MSWord = New-Object -com word.application $fullPath = $LocalSignaturePath+'\'+$CompanyName+'.docx' $MSWord.Documents.Open($fullPath) $FindText = "DisplayName" $ReplaceText = $ADDisplayName.ToString() $MSWord.Selection.Find.Execute($FindText, $MatchCase, $MatchWholeWord, $MatchWildcards, $MatchSoundsLike, $MatchAllWordForms, $Forward, $Wrap, $Format, $ReplaceText, $ReplaceAll ) $FindText = "Title" $ReplaceText = $ADTitle.ToString() $MSWord.Selection.Find.Execute($FindText, $MatchCase, $MatchWholeWord, $MatchWildcards, $MatchSoundsLike, $MatchAllWordForms, $Forward, $Wrap, $Format, $ReplaceText, $ReplaceAll ) $MSWord.Selection.Find.Execute("Email") $MSWord.ActiveDocument.Hyperlinks.Add($MSWord.Selection.Range, "mailto:"+$ADEmailAddress.ToString(), $missing, $missing, $ADEmailAddress.ToString()) $saveFormat = [Enum]::Parse([Microsoft.Office.Interop.Word.WdSaveFormat], "wdFormatHTML"); $path = $LocalSignaturePath+'\'+$CompanyName+".htm" $MSWord.ActiveDocument.saveas([ref]$path, [ref]$saveFormat) $saveFormat = [Enum]::Parse([Microsoft.Office.Interop.Word.WdSaveFormat], "wdFormatRTF"); $path = $LocalSignaturePath+'\'+$CompanyName+".rtf" $MSWord.ActiveDocument.SaveAs([ref] $path, [ref]$saveFormat) $saveFormat = [Enum]::Parse([Microsoft.Office.Interop.Word.WdSaveFormat], "wdFormatText"); $path = $LocalSignaturePath+'\'+$CompanyName+".txt" $MSWord.ActiveDocument.SaveAs([ref] $path, [ref]$SaveFormat) $MSWord.ActiveDocument.Close() $MSWord.Quit() } #Stamp registry-values for Outlook Signature Settings if they doesn`t match the initial script variables. Note that these will apply after the second script run when changes are made in the "Custom variables"-section. if ($ForcedSignatureNew -eq $ForceSignatureNew){} else {Set-ItemProperty $CompanyRegPath'\Outlook Signature Settings' -name ForcedSignatureNew -Value $ForceSignatureNew} if ($ForcedSignatureReplyForward -eq $ForceSignatureReplyForward){} else {Set-ItemProperty $CompanyRegPath'\Outlook Signature Settings' -name ForcedSignatureReplyForward -Value $ForceSignatureReplyForward} if ($SignatureVersion -eq $SigVersion){} else {Set-ItemProperty $CompanyRegPath'\Outlook Signature Settings' -name SignatureVersion -Value $SigVersion} 

Update: December 19, 2011
This idea has been expanded to include OWA and let you stop end users from changing the signature. See http://www.edugeek.net/blogs/thescarfedone/1016-centrally-managing-signatures-outlook-owa-free-way.html

20 replies
  1. Lewis Cooksey
    Lewis Cooksey says:

    Hi there, great adaptation of the email signature generator. I’ve had it working temperamentally, but most of the time it brings up the following error

    The term ‘else’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelli
    ng of the name, or if a path was included, verify that the path is correct and try again.
    At line:1 char:5
    + else <<<<
    + CategoryInfo : ObjectNotFound: (else:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    Any help would be greatly appreciated!

    Reply
  2. DC
    DC says:

    I am confused by this part:

    Use the following keywords: DisplayName, Title, Email)
    Can you clarify what you are asking us to do in that step?

    Reply
  3. Paul T. Ireland
    Paul T. Ireland says:

    Thanks for this awesome script. I’d like to see if I can get help editing the script to include fax numbers. Also, does it matter if I have users grouped into different OUs based on physical location? This makes it easier to assign address information, fax numbers, etc. for a large number of users at the same time and to setup a template user with the correct information for future users.

    Reply
  4. zullu
    zullu says:

    If you need the Faxnumber you will have to add this line
    $Searcher.PropertiesToLoad.AddRange(@(“facsimileTelephoneNumber”,”sn”,”givenName”,”displayName”,”Title”,”mail”))
    before $Searcher.FindOne()
    and after $Searcher.FindOne() you will add a line like this:
    $faxnbr=””
    if($ADUserPath.Properties.Contains(“facsimiletelephonenumber”))
    { $faxnbr=[String]$ADUserPath.Properties[“facsimiletelephonenumber”] }

    now you will have your Faxnumber in the Variable $faxnbr. the ldap attributename as you can see in ADSI Edit must be written in lowercase.

    Reply
  5. Janne
    Janne says:

    Hello there, is there a fault in this script? You can only run the script once and after that it doesnt run if there is no changes made in the \domainnetlogonsig_filesCompany file?

    Im having this sort of issue with this and im not able to figure out why doesnt it run.

    So to clear all things up I can only run the script once after that it works correctly makes my signature from the .docx template but no other user is able to get their signature if I dont do changes in the template file.

    Reply
  6. Jelmer
    Jelmer says:

    This script has the directory where the signatures are stored semi-hardcoded. It points to %appdata%/Microsoft/Signatures , but unfortunately the “Signatures” subdir can be localized.
    The real path to the signature subdir can be found in the registry, at the key HKCUSoftwareMicrosoftOffice12.0CommonGeneral, the value “Signatures” will contain the name of the subdir.

    Reply
  7. Hector
    Hector says:

    Hello,

    I am trying to deploy this script and im testing it out but no luck. I am confused on what to type in for $CompanyName = ‘Immense Networks’ $DomainName = ‘IN.local’. Is $companyName the name of the file and DomainName the name of the server where the file is located at?

    Thanks

    Reply
  8. Hector
    Hector says:

    Hello again, I was able to correct my issue above and the registry keys are written but no signature is showing up when I open a new emial message or reply/forward an email. Can you help?

    Thanks

    Reply
  9. HiltonT
    HiltonT says:

    Wow – the SyntaxHighlighter script really destroys the syntax display and layout of the code segment, jamming it all into a single line, making it almost indecipherable. 🙁 I’ve tried in IE9, Chrome and also Firefox.

    Is there any chance we can have a version that’s not been mangled? The reason I ask is that when I attempt to expand this out (manually) I end up with a line that reads:

    $SignatureVersion = (Get-ItemProperty $CompanyRegPath’Outlook Signature Settings’).SignatureVersion Set-ItemProperty $CompanyRegPath’Outlook Signature Settings’ -name SignatureSourceFiles -Value $SigSource

    … which is invalid and causes the script to fail.

    Aside from this showstopper issue, this looks like quite a good way to handle company-wide signature creation and deployment. 🙂

    Reply
  10. Cris
    Cris says:

    This is great Thanks! My only problem is for some users, I get a pop-up to save the changes on normal.dot on MS word at log on… Plus I cannot immediately open outlook because it will give me a pop-up that it’s in use by another process…. Those are show stoppers for us to deploy this.

    Any body else who faced this? Thanks a lot!

    Reply
  11. Scott
    Scott says:

    @Cris I am getting this same issue – did you find a fix for it? It has only started happening to my users recently.

    Thanks!

    Reply
  12. Dex
    Dex says:

    Hi,

    I have a problem where it is reading the date and time in Australian format, but it is writing the time in regkey in American format.

    How can i get it to write in Australian date format ?

    Reply
  13. Snikt
    Snikt says:

    Hello,

    Great script, I have one issue :
    When signature has picture with hyperlink, picture is converted into png format, but I need it to be converted into jpg as png occured some trouble with mail to fax feature of some of our customer.

    Any idea on how to do this ?

    Reply

Trackbacks & Pingbacks

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *