Outlook handtekening met informatie uit Active Directory

Bij veel organisaties die RES Workspace Manager (voorheen PowerFuse), AppSense Environment Manager of CodeTwo Exchange Rules gebruiken is het al jaren gemeengoed: een Outlook handtekening met daarin informatie uit Active Directory verwerkt. Iedereen gebruikt op die manier dezelfde handtekening onderaan hun uitgaande e-mail, maar aangevuld met de persoonlijke gegevens van de verzender. Veel van onze klanten maken geen gebruik van deze software en dat geldt ook voor onze Online Werkplek omgeving. Daarom hebben we deze functionaliteit zelf gerealiseerd met behulp van PowerShell.

 

Outlook handtekening maken in HTML

Er zijn een aantal voorbeelden te vinden van PowerShell scripts om handtekeningen te generen (voorbeeld 1 en voorbeeld 2), maar daarin wordt vaak een Word-document gebruikt als basis. Om te zorgen dat een Outlook handtekening in verschillende versies van Outlook (2010, 2013 en 2016) hetzelfde weergegeven wordt en er ook goed versiebeheer op los gelaten kan worden, gebruiken wij een HTML-document. In dit HTML-document zijn vervolgens variabelen opgenomen die bij het opslaan van de handtekening worden vervangen door informatie uit Active Directory. Het basis (bron) HTML-document voor onze eigen handtekening ziet er daardoor als volgt uit:

Bij iedere keer inloggen wordt de handtekening ingesteld d.m.v. een PowerShell script. In deze blog zal ik onderstaande stappen bespreken, die essentieel waren bij het opzetten van onze Outlook handtekening:

  • Bronbestanden plaatsen
  • Afbeeldingen toevoegen
  • Informatie uit Active Directory ophalen
  • Variabelen vervangen

Bronbestanden plaatsen

Op zich een logische en simpele stap, maar door verschillende versies van Outlook toch ‘tricky’. Bij ons bleek wisselend Office in het Nederlands en het Engels geïnstalleerd te zijn. Op zich is dat geen probleem, maar daardoor was de locatie waar de bestanden voor de Outlook handtekening moeten worden opgeslagen wel wisselend. Deze kan worden bepaald d.m.v. het register van de gebruiker:

PS C:\> $SignatureFolder = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\Office\16.0\Common\General" -Name "Signatures").Signatures
PS C:\> $SignatureFolder
Handtekeningen

Let hierbij op dat de locatie van deze registerwaarde verschilt per versie van Office (in dit geval Office 2016, ofwel 16.0). Om deze waarde te bepalen kan ook het register gebruikt worden:

$OutlookRegPath =  "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Outlook.exe"
if (Test-Path $OutlookRegPath) {
   $path = Get-ItemProperty -Path $OutlookRegPath
   $apppath = "$($path.Path)\Outlook.exe"
   $fileversion = (Get-Command $apppath).FileVersionInfo.FileVersion
   $officeversion = $fileversion.Split(".")[0]
} else {
   Write-Warning "Outlook is niet geïnstalleerd op deze machine"
}

De bestanden kunnen in de volgende map worden opgeslagen:

$OutlookFilesPath = Join-path -Path $Env:APPDATA -ChildPath ("Microsoft\" + $SignatureFolder)

Het HTML-bestand (met als bestandsextensie .htm) en de benodigde afbeeldingen in een submap kunnen hier worden opgeslagen. Een leeg RTF-document met dezelfde naam als het HTML-bestand dient te worden aangemaakt in diezelfde map, anders wordt de handtekening niet herkend door Outlook. De inhoud van de HTML-handtekening wordt bij het eerste gebruik omgezet naar een RTF-handtekening. Een leeg document is daarom voldoende. Ook een TXT-bestand moet worden aangemaakt met dezelfde naam, maar het is aan te raden deze net als een HTML-bestand aan te maken als een sjabloon met variabelen.

 

Afbeeldingen toevoegen

Vanaf Office 2013 (onder water versie 15.0 en hoger) worden afbeeldingen in Outlook handtekening standaard alleen gelinkt en niet toegevoegd aan de e-mail. Gevolg daarvan is dat de handtekening er nog netjes uit ziet bij het opstellen van een e-mailbericht, maar bij het ontvangen wordt vervolgens voor iedere afbeelding de foutmelding “The linked image cannot be displayed. The file may have been moved, renamed, or deleted. Verify that the link points to the correct file and location.” getoond:

Om dit te verhelpen dient de volgende waarde in het register gezet te worden:

Sleutel: HKCU:\Software\Microsoft\Office\15.0\Outlook\Options\Mail
Naam: Send Pictures With Document
Type: DWORD
Waarde: 1

Wij hebben dit meegenomen in het PowerShell script waarmee de handtekening wordt aangemaakt:

if ($officeversion -ge "15") {
   try {
      $_path = "HKCU:\Software\Microsoft\Office\$officeversion.0\Outlook\Options\Mail"
      if (Test-Path $_path) {
         Set-ItemProperty -Path $_path -Name "Send Pictures With Document" -Value 1
      } else {
         Write-Host"De sleutel $_path is niet beschikbaar en zal worden aangemaakt."
         New-Item -Path $_path -Force
         Set-ItemProperty -Path $_path -Name "Send Pictures With Document" -Value 1
      }
   } catch {
      Write-Warning "Fout bij het zetten van de waarde voor `"Send Pictures With Document`": $($_.Exception.Message)"
   }
}

Informatie uit Active Directory ophalen

De informatie uit Active Directory halen we op via de methode DirectorySearcher uit .NET Framework. Hierdoor hoeven, in de omgeving van de eindgebruiker, geen extra modules of andere software geladen te worden om de informatie uit Active Directory op te halen.

$strFilter = "(&(objectCategory=User)(samAccountName=([string]$env:username)))"
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.Filter = $strFilter
$objPath = $objSearcher.FindOne()
$objUser = $objPath.GetDirectoryEntry()

Variabelen vervangen

Als de bestanden zijn geplaatst, moeten de variabelen nog worden vervangen. Wij hebben er voor de duidelijkheid voor gekozen om variabelen in het document te zetten met speciale tekens eromheen. Bijvoorbeeld &displayName& en &title&. Deze variabelen hebben we voor het gemak overeen laten komen met de namen van de attributen in Active Directory. Voor het vervangen van de variabelen gebruiken we een simpele functie die voor zowel de HTML- als de TXT-bestanden kan worden gebruikt:

Function Search-AndReplace {
   [CmdletBinding()]
   param(
      [Parameter(ValueFromPipeline=$true,Position=0,Mandatory=$true)]
      [string]$filePath,

      [Parameter(ValueFromPipeline=$true,Position=1,Mandatory=$true)]
      [ValidateNotNullOrEmpty()]
      [string]$text,

      [Parameter(ValueFromPipeline=$true,Position=2,Mandatory=$true)]
      [ValidateNotNullOrEmpty()]
      [string]$replacement
   )
   try {
      (Get-Content $filePath) | Foreach-Object {$_ -replace $text, $replacement} | Set-Content $filePath
   } catch {
      "$text kan niet worden gevonden"
   }
}

Sommige variabelen zijn niet altijd gevuld in Active Directory. Een veel voorkomend voorbeeld daarvan is bijvoorbeeld het mobiele telefoonnummer. Om te voorkomen dat de variabele blijft staan vervangen we deze voor een lege string. Het vervangen van een variabele als een mobiel telefoonnummer ziet er dus als volgt uit:

if(!(IsNullOrEmpty $userinfo.mobile)) {
   Search-AndReplace -filePath $htmlpath -text "&mobile&" -replacement ($textMobile + " " + $userinfo.mobile)
} else {
   Search-AndReplace -filePath $htmlpath -text "&mobile&" -replacement " "
}

De ervaren PowerShell-scripter ontdekt hier nog een slimmigheid in de vorm van de simpele functie IsNullOrEmpty om snel te checken of een string de waarde $null of geen tekst bevat, overgenomen vanuit TechNet Forums.

In een vervolg zal ik bespreken wat er nodig is om de handtekening in te stellen, af te dwingen en hoe de handtekening ook in Outlook Web App gebruikt kan worden. Later meer!