VMware Horizon Community
lansti
Hot Shot
Hot Shot

DEM - Update Outlook signature

Hi.

We currently have 4 annual updates of our outlook signatures, which insert a picture of our company logo, based on seasons. Well, this is brandingstuff that Marketing department wants...
The challenge is that there is a PS1 script running from DEM during logon, that makes these updates when needed.
What happens is that outlook seems to hang/freeze, or it will make changes to the normal.dot file, og that normal.dot file suddenly is write protected, which in turn creates problems for the user.
How are you fixing these changes? Do you use scripts, DEM, GPO or other stuff?

Appreciate tips

Best regards
Lansti
0 Kudos
5 Replies
DEMdev
VMware Employee
VMware Employee

Hi @lansti,

The Outlook signature is just a bunch of files in %APPDATA%\Microsoft\Signatures, right? I suppose the script is run as a DEM logon task, configured to run After profile archive import?

Can you share the (logic of) the script? Does it work correctly if you run the script manually during the session?

0 Kudos
lansti
Hot Shot
Hot Shot

Hi This script is trigged by a VBScript we are running during logontask from DEM. After profile archive import.

my powershell looks like this:

#Custom variables 
$CompanyName = ‘company’ 
$DomainName = ‘company.com’ 
 
$SigSource = “\\$DomainName\netlogon\OLSignatur\$CompanyName” 
$ForceSignatureNew = '0' #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 = '0' #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\Signaturer’ 
$LocalSignaturePath = $AppData+$SigPath 
$RemoteSignaturePathFull = $SigSource+'\'+$CompanyName+’.docx’ 
$RemoteSignaturePathFullNor = $SigSource+'\'+$CompanyName+'Nor.docx' 
$RemoteSignaturePathFullEng = $SigSource+'\'+$CompanyName+'Eng.docx' 
 
#Get Active Directory information for current user 
$UserName = $env:username 
$Filter = “(&(objectCategory=User)(samAccountName=$UserName)(mail=*))” 
$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 
$ADStreetAddress = $ADUser.streetAddress
$ADPOBox = $ADUser.postOfficeBox
$ADPostalCode = $ADUser.postalCode
$ADCity = $ADUser.l
 
#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”} 
 
$ForcedSignatureNew = (Get-ItemProperty $CompanyRegPath'\Outlook Signature Settings').ForcedSignatureNew 
$ForcedSignatureReplyForward = (Get-ItemProperty $CompanyRegPath'\Outlook Signature Settings').ForcedSignatureReplyForward 
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 = $True 
$MatchWholeWord = $True 
$MatchWildcards = $False 
$MatchSoundsLike = $False 
$MatchAllWordForms = $False 
$Forward = $True 
$Wrap = $FindContinue 
$Format = $False 
 
#Insert variables from Active Directory to rtf signature-file to Norwegian version
$MSWord = New-Object -com word.application 
$fullPath = $LocalSignaturePath+'\'+$CompanyName+'Nor.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    ) 

$FindText = “TelephoneNumber” 
$ReplaceText = $ADTelePhoneNumber.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()) 

$FindText = “StreetAddress” 
$ReplaceText = $ADStreetAddress.ToString() 
$MSWord.Selection.Find.Execute($FindText, $MatchCase, $MatchWholeWord,    $MatchWildcards, $MatchSoundsLike, $MatchAllWordForms, $Forward, $Wrap,    $Format, $ReplaceText, $ReplaceAll    ) 

$FindText = “POBox” 
$ReplaceText = $ADPOBox.ToString() 
$MSWord.Selection.Find.Execute($FindText, $MatchCase, $MatchWholeWord,    $MatchWildcards, $MatchSoundsLike, $MatchAllWordForms, $Forward, $Wrap,    $Format, $ReplaceText, $ReplaceAll    ) 

$FindText = “PostalCode” 
$ReplaceText = $ADPostalCode.ToString() 
$MSWord.Selection.Find.Execute($FindText, $MatchCase, $MatchWholeWord,    $MatchWildcards, $MatchSoundsLike, $MatchAllWordForms, $Forward, $Wrap,    $Format, $ReplaceText, $ReplaceAll    ) 

$FindText = “City” 
$ReplaceText = $ADCity.ToString() 
$MSWord.Selection.Find.Execute($FindText, $MatchCase, $MatchWholeWord,    $MatchWildcards, $MatchSoundsLike, $MatchAllWordForms, $Forward, $Wrap,    $Format, $ReplaceText, $ReplaceAll    ) 
 
$MSWord.ActiveDocument.Save() 
$saveFormat = [Enum]::Parse([Microsoft.Office.Interop.Word.WdSaveFormat], “wdFormatHTML”); 
[ref]$BrowserLevel = “microsoft.office.interop.word.WdBrowserLevel” -as [type] 
 
$MSWord.ActiveDocument.WebOptions.OrganizeInFolder = $true 
$MSWord.ActiveDocument.WebOptions.UseLongFileNames = $true 
$MSWord.ActiveDocument.WebOptions.BrowserLevel = $BrowserLevel::wdBrowserLevelMicrosoftInternetExplorer6 
$path = $LocalSignaturePath+'\'+$CompanyName+”Nor.htm” 
$MSWord.ActiveDocument.saveas([ref]$path, [ref]$saveFormat) 
$MSWord.ActiveDocument.Close() 
$MSWord.Quit() 
 
#Insert variables from Active Directory to rtf signature-file to English version
$MSWord = New-Object -com word.application 
$fullPath = $LocalSignaturePath+'\'+$CompanyName+'Eng.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    ) 

$FindText = “TelephoneNumber” 
$ReplaceText = $ADTelePhoneNumber.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()) 

$FindText = “StreetAddress” 
$ReplaceText = $ADStreetAddress.ToString() 
$MSWord.Selection.Find.Execute($FindText, $MatchCase, $MatchWholeWord,    $MatchWildcards, $MatchSoundsLike, $MatchAllWordForms, $Forward, $Wrap,    $Format, $ReplaceText, $ReplaceAll    ) 

$FindText = “POBox” 
$ReplaceText = $ADPOBox.ToString() 
$MSWord.Selection.Find.Execute($FindText, $MatchCase, $MatchWholeWord,    $MatchWildcards, $MatchSoundsLike, $MatchAllWordForms, $Forward, $Wrap,    $Format, $ReplaceText, $ReplaceAll    ) 

$FindText = “PostalCode” 
$ReplaceText = $ADPostalCode.ToString() 
$MSWord.Selection.Find.Execute($FindText, $MatchCase, $MatchWholeWord,    $MatchWildcards, $MatchSoundsLike, $MatchAllWordForms, $Forward, $Wrap,    $Format, $ReplaceText, $ReplaceAll    ) 

$FindText = “City” 
$ReplaceText = $ADCity.ToString() 
$MSWord.Selection.Find.Execute($FindText, $MatchCase, $MatchWholeWord,    $MatchWildcards, $MatchSoundsLike, $MatchAllWordForms, $Forward, $Wrap,    $Format, $ReplaceText, $ReplaceAll    ) 
 
$MSWord.ActiveDocument.Save() 
$saveFormat = [Enum]::Parse([Microsoft.Office.Interop.Word.WdSaveFormat], “wdFormatHTML”); 
[ref]$BrowserLevel = “microsoft.office.interop.word.WdBrowserLevel” -as [type] 
 
$MSWord.ActiveDocument.WebOptions.OrganizeInFolder = $true 
$MSWord.ActiveDocument.WebOptions.UseLongFileNames = $true 
$MSWord.ActiveDocument.WebOptions.BrowserLevel = $BrowserLevel::wdBrowserLevelMicrosoftInternetExplorer6 
$path = $LocalSignaturePath+'\'+$CompanyName+”Eng.htm” 
$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} 

 

Best regards
Lansti
0 Kudos
DEMdev
VMware Employee
VMware Employee

Hi @lansti,

I noticed that the script is using COM to interact with Word; do you have DirectFlex enabled for Word, by any chance?

Does it work correctly if you manually launch the script during the session?

Could it maybe be an option to run the script at logoff, before capturing Outlook's settings, so that the newly updated signature takes effect in the user's next session?

0 Kudos
lansti
Hot Shot
Hot Shot

Hi @DEMdev 

DirectFlex is not enablet, most of our policies are running are running with "apply settings after profile archive import.
I need this policy to run for new users so the signature is generated during logon, and the signature will follow users since we have this one in our confifile for Outlook:
[IncludeFolderTrees]
<AppData>\Microsoft\Signatures

 

So, the VBscript that we are running during logon, will trigger the PS1 script, it will check a registry value, and from here it will run through an IF Else sentence... if it will run the script or not..

What i experience, is that i can run it manually, but sometimes I'll get the save message for Normal.dot or that Outlook will hang/freeze. And then user need to kill the process, but for most users, they do not know how to do this, so they logs out and in again.. then the signatures is fine.

I'm curious about how others out there solve this with instant clone signatures

Best regards
Lansti
0 Kudos
DEMdev
VMware Employee
VMware Employee

Hi @lansti,

i can run it manually, but sometimes I'll get the save message for Normal.dot or that Outlook will hang/freeze

I'm afraid that makes it more of a Word COM automation question than a DEM one, and I can't help with that. Hopefully someone else on this forum has similar requirements as you (or your marketing department 😉) and they can point to a more robust approach.