PI Services

Le blog des collaborateurs de PI Services

Powershell / Exchange : Erreur 9323 - Certificat expiré sur un objet AD

Introduction

Cet article permet de montrer la gestion des certificats via Powershell au travers d'un problème concret rencontré sur une infrastructure Exchange. Une solution basée sur un script Powershell sera détaillée.

Erreur rencontrée

Contexte : Infrastructure Exchange 2010 avec plusieurs dizaine de milliers de contacts Active Directory importés et mis à jour par un outil tierce.

Dans l’observateur d’événements de nombreux événements 9323 apparaissent.

9323

Ces derniers sont liés à la génération de l'OAB. Exchange détecte un utilisateur dont un certificat est expiré. Ces événements n'apparaissent que sur des objets de type "Contact"  La solution doit contrôler tous les objets Active Directory de ce type.

Solution

La soluton proposée pour purger les certificats invalides des contacts Active Directory se base sur un script Powershell V2. Ce dernier analyse l'attribut UserCertificate (il s'agit d'une liste de certificat).

Avec le type d'objet "System.Security.Cryptography.X509Certificates.X509Certificate2", il est possible d'obtenir des informations sur les certficats contenus dans cet attribut sous forme lisible (et non pas un tableau de bytes ou de valeur hexadécimal comme sur la console Active Directory Users and Computers).

Ci-dessous, un exemple de données récupérées sur les certificats d'un objet Active Directory (ici, il n'y a qu'un seul certificat et la variable $User est un utilisateur Active Directory).

Certificate

On remarque qu'on accède à des renseignements comme l'émetteur ou le sujet. Les informations qui nous interessent (dates de validité du certificat) sont aussi présentes. Il suffit donc de comparer la date d'expiration contenue dans l'attribut "notAfter" avec la date du jour en cours pour détecter les certificats expirés.

Grâce à la cmdlet "Set-ADObject", il sera ensuite possible de supprimer les certificats qui ne sont plus valides.

Script

En amont de ce script, un transcript est lancé afin de loguer toute les opération effectuées. Une vérification de la présence du module ActiveDirectory ainsi que son chargement sont ensuite réalisées.

Le script appelle une fonction créée pour traiter tout objet AD (ou tableau d'objets AD) qui lui est passé. Pour ma part, je transmets en paramètre tous les contacts présents dans Active Directory. Cependant cette fonction peut très bien être utilisée avec des utilisateurs. Voici l'algolrithme mis en place dans la fonction Test-CertExpiration :

  1. Filtrage des objets pour ne conserver que ceux ayant au moins un certificat présent dans l'attribut userCertificate.
  2. Boucle ForEach sur tous les utilisateurs :
    1. Boucle For sur tous les certificats de l'utilisateur (pas de ForEach afin d'être certain de la position du certificat dans l'attribut userCertificate)
    2. Analyse de la date d'expiration
    3. Si le paramètre DeleteExpired est présent alors on supprime le certificat dans Active     Directory s'il n'est plus valide.
    4. Si le paramètre DeleteExpired n'est pas présent alors deux attributs sont ajoutés à l'objet     AD :
      1. CertExpired : contient les index des certificats expirés dans le tableau de l'attribut userCertificate
      2. CertValid : contient les index des certificats valides dans le tableau de l'attribut userCertificate
  3. Si le paramètre Export et ExportPath ont été renseigné alors le tableau d'objet AD est exporté sous format CSV avec la liste des index des certificats valides et expirés.

Ci-dessous, vous trouverez le script intégralement commenté. A noter, que le compte exécutant ce script doit posséder les droit suffisants à la modifications des objets AD concernés (via une délégation par exemple).

Ici, la fonction Test-CertExpiration, est utilisée en mode suppression, cependant il est aussi possible de se servir du mode Export pour n'effectuer qu'un simple audit (logué dans un fichier) des objets concernés via la commande suivante :

$ADObjets est un tableau d'objets Active Directory.

Il est enfin possible de ne donner qu'un tableau d'objets AD à traiter sans spécifier le mode export ou suppression :

Dans ce cas, un tableau d'objets AD est retourné. Pour chaque objet, les attributs CertExpired et CertValid sont ajoutés.

Quelques points clés du fonctionnement de la fonction Test-CertExpiration :

Les paramètres Export et DeleteExpired sont de type switch et ne peuvent apparaître ensemble. Le paramètre ExportPath est dynamique et n'est disponible que si le paramètre Export a été choisi.

Pour information, il n'est pas nécessaire de paralléliser le processus de contrôle du certificat. Après un test effectué sur plus de 90000 contacts Active Directory, il s'avère que ce dernier a duré moins de 5 minutes. Utiliser du multi thread (workflow ou job Powershell) alourdirai le script et ralentirai le processus au lieu de l'accélérer.

Exchange 2013 - Erreur 5203 (source WAS) sur un serveur multi-rôles Exchange 2013 CU2

Symptômes

Ce type d’erreur peut se rencontrer sur un serveur multi-rôles (Client Access et Mailbox) en version Exchange Server 2013 CU1 ou Exchange Server 2013 CU2.

Les symptômes sont les suivants :

  • Les services Web Exchange (OWA, Outlook Anywhere…) dysfonctionnent
  • L’erreur 503 (source WAS) est présente en boucle dans le journal d’évènement Système

    Voici le détail de l’erreur concernée :

    Journal : System
    Source: Microsoft-Windows-WAS
    Event ID : 5203
    Level : Error
    Description: A process serving application pool 'MSExchangeRpcProxyAppPool' reported a failure trying to read configuration during startup. The process id was '27620'.  Please check the Application Event Log for further event messages logged by the worker process on the specific error.  The data field contains the error number.

Explication

Cette erreur est généralement due à la présence d’un fichier de configuration IIS corrompu.

Cela peut être mis en évidence en lançant la console d’administration IIS Manager.

image

Dans notre exemple, la console fait très clairement référence à un fichier de configuration nommé applicationHost.config et stocké dans le répertoire C:\Windows\System32\Inetsrv\Config.

Lorsque l’on tente d’éditer le fichier, ce dernier peut apparaitre remplis d’espace blancs ou bien ma formaté (selon les cas de figure).

image

Résolution

Pour résoudre ce problème il suffit de recopier le fichier sur le serveur applicationHost.config à partir d’un autre serveur Exchange en même version ou bien à partir d’une sauvegarde.

Dès le fichier copié, il devient  possible de démarrer les services IIS et les services Web sont de nouveau opérationnels.

Interaction Powershell - Exchange Web Services

Introduction

Avec Exchange 2010, pour certains besoins bien spécifiques, il se peut que les cmdlets Powershell soit limitées. Cependant, il existe aussi les Exchanges Web Services. Bien entendu, quand on parle des Exchange Web Services, on pense au C# et à un développement complexe. Cependant, on n'oublie souvent que Powershell permet d'exécuter du C#.
Il sera donc question d'accéder aux EWS via Powershell. Il s'agit surtout d'une introduction car les possibilités de scripting sont infinies. L'exemple mis en œuvre dans cet article montrera comment accéder à un dossier bien spécifique pour le purger suivant les dates de réception des emails. Cela permettra entre autres de voir le langage AQS permettant la recherche d'objets dans une boîte aux lettres Exchange.

Prérequis

Avant toute chose, pour manipuler l'API Exchange Web Services, il est nécessaire d'installer le package correspondant sur le poste qui exécutera le script. Il est trouvable en suivant ce lien : http://www.microsoft.com/en-us/download/details.aspx?id=28952

Attention si vous utilisez, Exchange 2013, il faut prendre cette version :
http://www.microsoft.com/en-us/download/details.aspx?id=35371

Il sera ensuite nécessaire d'ajouter dans chacun des scripts qui sera réalisé la dll permettant d'interagir avec les Web Services. Pour rappel, cela se réalise via la commande Powershell Add-Type :

001
002
003
Add-Type -path "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"


AQS ou Advanced Query Syntax:

Le langage AQS permet de réaliser des recherches dans les objets d'une boîte aux lettres Exchange. Il est très simple à prendre en main.

Pour comprendre toutes les possibilités de ce langage voici le lien MSDN dédié :
http://msdn.microsoft.com/en-us/library/ee693615.aspx

Grâce à ce langage il va être possible de rechercher des éléments :
- par type (emails, réunions, notes, contacts, ...)
- par date (réception ou envoi)
- par propriété d'un email (champ from, to, cc, subject, body, ...)

L'exemple suivant permet de rechercher des emails ayant été reçu le 3 Septembre 2013 :
"Kind:email AND Received:03/09/2013"

On remarque l'opérateur AND qui permet de prendre en compte 2 propositions. Il en existe d'autres comme le OU (l'une ou l'autre des propositions) et le NOT (l'inverse d'une proposition).

Script commenté

Il s'agit ici d'un script où l'utilisateur se connecte à une boîte aux lettres sur laquelle il possède des droits et dont les messages du dossier nommé Personnel seront supprimées s'ils datent de plus de 30 jours. Aussi, pour chaque dossier, il affiche la taille de celui-ci en Ko. Cette dernière opération est aussi faisable via la commande EMS Get-MailboxFolderStatistics mais avec cette exemple nous n'aurons pas besoin d'installer ces outils mais seulement l'API EWS beaucoup plus légère.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
#Mailbox à traiter
$MailboxName = 'j.dupont@myenterprise.fr'

# A installer avant : www.microsoft.com/en-us/download/details.aspx?id=28952
try{
    Add-Type -path "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
}catch{

}

#On spécifie la version des web services
$Version = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2
$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($version)

#On utilise les credentials avec lesquels on est connecté
$Service.UseDefaultCredentials = $true

#On récupère la configuration Autodiscover pour se connecter à la BAL
$Service.AutodiscoverUrl($MailboxName,{$true})

#On récupère l'ID du dossier
$RootFolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName)

#On se connecte au dossier via la connexion que l'on a initialisé
$RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$RootFolderID)

#On limite le nombre de dossier à analyser à 1000 (sinon problème de throttling)
$FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)

#On définit un ensemble de propriété à récupérer en même temps que nos dossiers
$PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
#On crée une propriété de type taille de dossier
$SizeObject = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(3592,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Long)
#On l'ajouter à notre vue de dossier afin que la taille soit aussi récupérée.
$PropertySet.Add($SizeObject); 
$FolderView.PropertySet = $PropertySet;

#On spécifie qu'on analyse l'intégralité de la hiérarchie
$FolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep

#On calcule la date d'il y a 30 jours et on la met au format dd/MM/yyyy
$DateOld = ((Get-Date).AddDays(-30)).ToString("dd/MM/yyyy")

#On récupère tous les dossiers
$Response = $RootFolder.FindFolders($FolderView)
#Pour chaque dossier
ForEach ($Folder in $Response.Folders) {
   
    $FolderSize = $null
    #Si la taille est disponible alors on l'export dans la variable $FolderSize
    if($Folder.TryGetProperty($SizeObject,[ref] $FolderSize)){
        $FolderSizeValue = ([Int64]$FolderSize)/1000 
        #On affiche la taille du dossier
        $Message = "Le dossier " + $Folder.DisplayName + " a une taille de $FolderSizeValue Ko"
        Write-Host $Message
    }else{
        $Message = "Taille du dossier " + $Folder.DisplayName +" introuvable."
        Write-host $Message
    }

    #On compare le display name avec la valeur recherchée
    if($Folder.DisplayName -eq "Personnel"){
        #Si le dossier est bien Personnel alors on récupère tous les mails selon les critères de date définies
        $Items = $Folder.FindItems("Kind:email AND Received:<$DateOld",$ItemView) 
        #Pour chaque email trouvée
        ForEach($Item in $Items){
            #On le supprime définitivement (à décommenter pour que ce soit effectif)
            #$Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)
        }
    }
}

 

On remarque l’opérateur “<” (inférieur à) dans la requête AQS qui permet de spécifier tout ce qui se trouve avant cette date.

On peut accéder aux dossiers publics, modifier, supprimer, créer, tout type d'objet y compris des dossiers. Il est aussi possible de récupérer différentes informations comme la taille d'un dossier. Il est aussi possible d'analyser les pièces jointes pour supprimer celle dont l'extension est d'un certain type. Il est donc possible d'imaginer plein de scripts comme des tâches planifiées effectuant des traitement sur des boîtes aux lettres.

Powershell : Modifier l'affichage d'un compte sous Outlook 2010

Introduction

Dans le cadre d'une migration inter-organization Exchange 2003 vers Exchange 2010, il fallait reconfigurer le profil pour que le nom de compte dans Outlook 2010 soit mis à jour avec la nouvelle adresse email (ainsi que le nom des arborescences des emails et de dossiers publics associées).

Blog1blog2

Afin de répondre à cette problématique en impactant le moins d'utilisateurs possibles, la solution proposée réalisait des modifications via un script déployer en GPO (logon script).
Ci-dessous vous trouverez les informations nécessaires à ce paramétrage via Powershell.

Récupération des informations de comptes

Afin d'effectuer ces modifications il faut aller les chercher dans le registre.
Ainsi, la ruche "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\" liste tout les profiles Outlook enregistré (par défaut le premier profil est appelé Outlook) pour l'utilisateur connecté.
Dans les ruches enfantes, si la clé de registre 001f6620 est présente c'est qu'il s'agit d'un compte Outlook. Cette dernière définit le nom du compte.

De plus, toujours dans les ruches sous-jacentes au nom d'un profile, si la clé 0003660a est positionné alors il s'agit d'une arborescence de emails ou de dossiers publics (ce sont celles qui nous intéressent dans le cas d'un changement de nom).
Si elle a la valeur "0x03,0x00,0x00,0x00" c'est qu'elle représente une arborescence de dossiers publics tandis que "0x01,0x00,0x00,0x00" représente la même chose pour des emails.
Le nom de l'arborescence est contenu dans la clé 001f3001.

Avec ces informations nous pouvons donc facilement retrouver le nom d'un compte et le profile associé pour le modifier. Pour modifier les noms des arborescences, nous avons les clés de registres à changer.

Modification du nom de compte

Pour modifier le nom du compte il n'existe actuellement qu'une seule méthode puisque la propriété du accessible via la librairie Interop (permettant d'interagir avec Outlook) n'est accessible qu'en lecture seule. Un module Powershell a été développé pour gérer les comptes Outlook : Outlook Account Manager. Il est disponible à cette adresse : http://psoutlookmanager.codeplex.com/

Il propose un jeu de commandes permettant de récupérer les profiles (Get-Profile), les comptes (Get-MAPIAccount) et de modifier ces derniers (Set-MAPIAccount).

Voici un exemple permettant le modification du nom d'un compte :

On récupère le compte Outlook que l'on souhaite renommer (Il faut spécifier le profil)
$Account = Get-MAPIAccount -ProfileName "Nom du profil" | Where-Object `   {$_.AccountName -eq "Mon compte à modifier"}
On change l'attribut AccountName avec le nouveau nom que l'on souhaite obtenir.
$Account.AccountName = "Nouveau nom"
On enregistre les changements sur le compte que l'on a mis à jour.
Set-MAPIAccount $Account

Il est à noter que le module Outlook Account Manager ne s'exécute qu'avec Powershell 32 bits. On peut donc lancer le script via la commande ci-dessous :
&"$env:windir\syswow64\windowspowershell\v1.0\powershell.exe" $Path
$Path représente ici le chemin du script.

Cette méthode peut être exécuter pendant qu'Outlook est lancé. Le résultat sera visible dès l'exécution du script (sans avoir à redémarrer Outlook).

Modification du nom d'affichage

Pour mettre à jour le nom d'affichage dans l'arborescence Outlook, il existe plusieurs méthodes.

La première, consiste à utiliser les classes Interop Outlook. Cela va lancer un processus Outlook en tâche de fond.
Tout d'abord on invoque une instance d'Outlook
$Outlook = New-Object -comObject Outlook.Application
$Namespace = $Outlook.GetNamespace("MAPI")

Permet d'obtenir tous les comptes.
$Accounts = $Namespace.Accounts

Cette méthode présente l'avantage d'obtenir un résultat visible même si Outlook est lancé (sans avoir à le redémarrer). Cependant, l'utilisateur sera prompté pour lui dire qu'un autre processus souhaite accéder à Outlook, et cela nécessitera donc une intervention manuelle. Il peut aussi être concevable de fermer toutes les instances d'Outlook avant d'exécuter ce script, ce qui peut être déroutant pour l'utilisateur.

Voici un exemple de code permettant la dernière proposition :
$OutlookProcesses = Get-Process | Where-Object {$_.Name -like "Outlook"}
ForEach($Outlook in $OutlookProcesses){
    Stop-Process $Outlook.Id
}

A la fin du script on n'oublie pas de fermer le processus ouvert par la création de l'objet COM :
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook)

La seconde méthode consiste à modifier directement la clé de registre. Pour mettre en œuvre cette opération il faut changer la valeur de la clé "001f3001" que l'on a identifier au préalable. Attention, le type de cette clé est un tableau de bytes. Bien qu'il soit possible de donner une chaine de caractère classique (String), tout en impactant pas le fonctionnement d'Outlook, cela va modifier le type. Voici donc un exemple pour créer un tableau de bytes à partir d'une chaine de caractère :

Exemple de résultat à obtenir :
blog4

On encode une String  en tableau de bytes
$enc = [system.Text.Encoding]::UTF8
$mystring = "This is a string"
$data = $enc.GetBytes($mystring)

Chaque caractère est séparé par une valeur en byte équivalente à un zéro. Pour que notre tableau soit correct il faut ajouter ce zéro après chaque caractère.
On crée un tableau modifiable (ArrayList)
$ArrayBytes = New-Object System.Collections.ArrayList
Entre chaque byte on ajoute un zéro.
foreach($d in $data){
    $ArrayBytes.Add($d)
    $ArrayBytes.Add(0)
}

Enfin on peut modifier la valeur de la clé de registre :

Set-ItemProperty "$RegistryPath" -Name 001f3001 -Value $ArrayBytes
$RegistryPath représente le chemin vers la clé de registre.

L'avantage de cette méthode est de n'avoir pas à exécuter de processus Outlook et l'utilisateur ne se rend pas compte du changement (pas de prompt ni de fermetures intempestives d'Outlook). Cependant si Outlook est lancé, le résultat ne sera visible qu'au prochain démarrage de celui-ci.

Exchange 2010–Queue Viewer

En observant les files d’attentes d’un serveur de transport on peut parfois observer une

file en mode “suspended” ne contenant aucun message dont le “delivery type” est

“DnsConnectorDelivery”. La présence de ce type est compréhensible lorsqu’un connecteur

utilise un serveur DNS pour connaitre la passerelle distante, dans mon cas il n’y a que des

connecteurs utilisant une remise vers un “smarthost” !

 

clip_image002

Quoiqu’il en soit supprimons cette file.

Passez la file en mode “resume”. Elle va passer en “ready”:

clip_image002[5]

Redémarrez le service MS Exchange Transport.

Relancez la console Queue Viewer.

clip_image002[7]

La file a disparue.

Exchange 2010 SP2 – Erreur MapiExceptionNetworkError lors du déplacement des boîtes aux lettres

Symptôme

Dans le cadre d’une migration depuis une plateforme Exchange Server 2007 SP3 vers une plateforme Exchange 2010 SP2 RU5v2, l’erreur MapiExceptionNetworkError apparaît de manière régulière dans les logs des requêtes de déplacement de boîtes aux lettres (MoveRequests).

Voici un exemple :

18/01/2013 19:03:15 [SRV] Transient error MapiExceptionNetworkError has occurred.
18/01/2013 19:13:54 [SRV] Transient error MapiExceptionNetworkError has occurred.
18/01/2013 19:19:31 [SRV] Transient error MapiExceptionNetworkError has occurred.
18/01/2013 19:25:48 [SRV] Transient error MapiExceptionNetworkError has occurred.
18/01/2013 19:36:51 [SRV] Transient error MapiExceptionNetworkError has occurred.
18/01/2013 19:42:58 [SRV] Transient error MapiExceptionNetworkError has occurred.
18/01/2013 19:53:52 [SRV] Transient error MapiExceptionNetworkError has occurred.
18/01/2013 20:00:00 [SRV] Transient error MapiExceptionNetworkError has occurred.
18/01/2013 20:11:11 [SRV] Transient error MapiExceptionNetworkError has occurred.
18/01/2013 20:17:22 [SRV] Transient error MapiExceptionNetworkError has occurred

Le code d’erreur détaillé est le suivant :

Error details: MapiExceptionNetworkError: Unable to open entry ID. (hr=0x80040115, ec=0)

Les déplacements de boîtes aux lettres ne se terminent jamais car à chaque occurrence de l’erreur réseau, le transfert des données depuis les serveurs Exchange 2007 vers les serveurs Exchange 2010 repart à zéro.

18/01/2013 20:17:53 [SRV] Restarting the move because checkpoint data doesn't exist or isn't valid in 'Primary (f3e507d4-a687-416b-a615-23d2b9173011)'.
18/01/2013 20:17:53 [SRV] Connected to source mailbox 'Primary (f3e507d4-a687-416b-a615-23d2b9173011)', database 'CLUST01\StorageGroup\DB001', Mailbox server 'CLUST01.domain.local' Version 8.3 (Build 213.0).
18/01/2013 20:17:54 [SRV] Request processing started.
18/01/2013 20:17:54 [SRV] An old copy of the mailbox was removed from the destination database. The operation will try again in 30 seconds.

 

En parallèle, on remarque sur les boîtes aux lettres migrées vers Exchange 2010, l’apparition de nombreux évènements ayant pour source Outlook et pour ID 26 sur les postes clients (équipés d’Outlook 2010).

image

L’évènement émis par Outlook avec ID 26 a pour description “La connexion MAPI a été rétablie”.

Explication

Par défaut les sessions MAPI initiées par les serveurs Exchange 2010 ont une durée de vie de deux heures (7200 secondes).

Il peut arriver qu’un équipement réseau (routeur, pare-feu, HLB…) détecté une connexion MAPI comme étant inactive (idle) et coupe la session. En cas de coupure de session les clients MAPI tentent généralement de se reconnecter.

Dans notre cas c’est ce qui se produisait d’une part avec les clients Outlook (d’où les nombreux évènements au sujet d’une connexion MAPI “rétablie”) et d’autre part lorsque les serveurs CAS déplaçaient des boîtes aux lettres (d’où les erreurs “réseau”, suivies d’une reprise de la copie à son état de départ).

Remarque : Cette problématique de timeout est documentée dans la fiche support KB 2535656 (http://support.microsoft.com/kb/2535656/en-us) mais l’impact possible sur les déplacement de boîtes aux lettres (erreur “MapiExceptionNetworkError: Unable to open entry ID) n’y est pas référencé.

Résolution

Pour résoudre ce problème, deux approches sont possibles :

A) Identifier l’équipement réseau possédant un timeout trop court et reconfigurer ce timeout sur une valeur cohérente avec celle d’Exchange 2010 (2 heures)

B) Identifier la durée du timeout (dans notre cas 300s) et ajouter la clé de registre KeepAliveTime sur l’ensemble des serveurs Exchange 2010 et 2007 pour que le timeout Exchange soit inférieur au timeout de l’équipement (par exemple positionner la valeur KeepAlive sur 180 secondes)

Dans notre cas de figure l’option la plus simple et la plus pertinente a consisté à augmenter le timeout du “protocol profil” FastL4 sur les boitiers F5 (par défaut le timeout sur ce profil était configuré à 300 secondes et il a été relevé à 7200 secondes).

clip_image001[4]

Cette opération a résolu l’ensemble des problèmes rencontrés sur la plateforme (plus d’erreurs 26 sur les clients ni d’erreur MapiNetworkException lors des transferts de boîtes aux lettres).

A titre informatif, voici un exemple de configuration de la clé KeepAliveTime (attention la valeur à entrer est en millisecondes).

image

Exchange 2010 SP2 – Message d’erreur “invalid canary” sur les serveurs CAS

Symptôme

Suite à la mise en place de la supervision SCOM sur une plateforme Exchange 2010 SP2 RU5v2, des erreurs se produisent toutes les 5 minutes sur les serveurs jouant le rôle CAS.

image

Ces erreurs ont pour source MSExchange Control Panel et correspondent aux ID 4 et 38. Voici le détail de l’erreur 38 (avec en rouge les éléments intéressants) :

Log Name: Application
Source: MSExchange Control Panel
Date: 15/01/2013 14:40:05
Event ID: 38
Task Category: General
Level: Error
Keywords: Classic
User: N/A
Computer: CAS003.domain.local
Description:
Current User: 'domain.local/IT/Applications/Exchange/Sepcial Accounts/extest_123sd45c00812'

Exchange Control Panel detected an invalid canary from request for URL 'https://mail.domain.local/ECP/RulesEditor/InboxRules.svc/GetList'.

Canary in cookie: 'eLKJ8_Sgdekahjnd4825nduehfrkqzeuYDF_ujrDBHjfznakDF46fhbzp' mismatch with canary in header/form: ', in URL '.


Du côté de IIS, une erreur 500 est déclenchée et visible dans les logs W3C.

Explication

Ces erreurs se produisent à intervalles réguliers (toutes les 5 minutes) lorsque le compte de service utilisé par SCOM (extest_<id>) tente d’exécuter la commande PowerShell Test-EcpConnectivity.

Lorsque l’on effectue des recherches sur ces erreurs ont tombe très rapidement sur une fiche support indiquant qu’il s’agit d’un bug Exchange 2010 résolu dans la mise à jour RU3v3 du SP1 d’Exchange 2010.

Unnecessary events are logged in the Application log when you run the "Test-EcpConnectivity" cmdlet in an Exchange Server 2010 environment
http://support.microsoft.com/kb/2494389/en-us

Néanmoins dans notre cas, l’environnement est déjà mis à jour en version SP2 RU5v2 ce qui rend cette solution caduque.

Après investigation il s’avère que la commande Test-EcpConnectivity ne supporte pas les URL possédant des majuscules.

La solution au problème consiste à modifier les URL internes et externes du service Web ECP (Exchange Control Panel) de manière à remplacer le /ECP par un /ecp.

Ce problème est donc totalement indépendant de la supervision SCOM qui est dans ce cas un simple révélateur du problème (car SCOM exécute régulièrement la cmdlet Test-EcpConnectivity).

Résolution

Dès la correction des URL (via la cmdlet Set-EcpVirtualDirectory), les erreurs ne se produisent plus et il est possible d’exécuter sans erreur la commande Test-EcpConnectivity.

Remarque : La correction prend effet immédiatement. Un petit délai peut être nécessaire dans certains environnements, le temps que la réplication Active Directory ait lieu. Il n’est pas nécessaire de redémarrer IIS.

Cette solution a déjà été testée avec succès sur plusieurs environnement Exchange 2010 SP2.

Exchange2010 – Erreur lors de l’installation du rôle Hub Transport

Symptôme

Lors d’un déploiement d’Exchange Server 2010 SP2 avec RU4v2 (rollup stocké dans le sous-dossier Updates des sources Exchange), j’ai rencontré l’erreur suivante durant l’installation du rôle Hub :

Service “MSExchange Transport” failed to reach status “Running” on this server.

image

Voici le détail de l’erreur dans le journal Application :

Event ID : 1002
Source : MSExchangeSetup
Task Category : Microsoft Exchange Setup
Level : Error
Error :
The following error was generated when "$error.Clear(); if ($RoleStartTransportService) { start-SetupService -ServiceName MSExchangeTransport }" was run: "Service 'MSExchangeTransport' failed to start. Check the event log for possible reasons for the service start failure.".
Service 'MSExchangeTransport' failed to start. Check the event log for possible reasons for the service start failure.

 

Cette erreur à l’installation peut être considéré comme un “classique” d’Exchange 2010 lorsqu’une mauvaise configuration IPv6 est positionnée sur le serveur (cf. ce billet réalisé peu après la sortie d’Exchange 2010 : http://blog.piservices.fr/post/Exchange2010-Erreur-lors-de-linstallation-du-role-de-transport-Hub.aspx).

Néanmoins dans ce cas précis l’erreur n’était pas liée à la configuration IPv6 (interface réseau et clé de registre DisableComponents correctement configurés).

Après investigation l’erreur d’installation s’accompagnait de plusieurs évènements autour du service AD Topology dont le suivant :

Event ID: 2080
Source: MSExchange ADAccess
Task Category:
Topology
Level:
Information
Error:
Process MSEXCHANGEADTOPOLOGYSERVICE.EXE (PID=2386). Exchange Active Directory Provider has discovered the following servers with the following characteristics:
(Server name | Roles | Enabled | Reachability | Synchronized | GC capable | PDC | SACL right | Critical Data | Netlogon | OS Version)
In-site:
dc01.domain.lan CDG 1 7 7 1 0 0 1 7 1
dc02.domain.lan CDG 1 7 7 1 0 0 1 7 1
dc03.domain.lan CDG 1 7 7 1 0 0 1 7 1
Out-of-site:
dc05.domain.lan CDG 1 7 7 1 0 0 1 7 1
dc06.domain.lan CDG 1 7 7 1 0 0 1 7 1

Explication

Après investigation il s’avère que le problème d’installation est dû à un droit manquant sur la stratégie de groupe Default Domain Controllers Policy  pour le groupe Exchange Servers.

Pour rappel le groupe Exchange Servers est créé lors de la phase de préparation de l’annuaire Active Directory pour Exchange 2010 (ou Exchange 2007) et plus exactement via la commande setup.com /PrepareAD.

Lors de la phase de préparation des domaines via la commande setup.com /PrepareDomain la GPO Default Domain Controllers Policy de chaque domaine est modifiée de manière à donner le droit Manage auditing et security log au groupe Exchange Servers.

Dans le cas rencontré ici ce droit était manquant (d’où la présence d’un zéro dans la colonne SACL right lors de la détection des contrôleurs de domaine par le service de détection de la topologie Active Directory).

Résolution

Pour résoudre le problème rencontré la stratégie de groupe GPO Default Domain Controllers Policy est éditée via la console Group Policy Management Editor. Le droit manquant est situé dans l’emplacement suivant :

Computer Configuration / Policies / Windows Settings / Security Settings / Local Policies / user Rights Assignments

image

Il faut modifier le paramètre Manage auditing and security log et y ajouter le groupe nommé “Domaine racine \ Exchange Servers”.

image

Une fois la modification de stratégie de groupe prise en compte (comptez quelques minutes), l’instalation du rôle Hub Transport peut être relancée et cette fois-ci se déroule sans encombres.

Pour aller plus loin, vous pouvez consulter les articles suivants :

http://blogs.technet.com/b/richardroddy/archive/2010/06/16/msexchange-adaccess-dsaccess-errors-and-the-manage-auditing-and-security-right.aspx

http://jasonshave.blogspot.fr/2010/04/dscenosuitablecdc-error-with-exchange.html

http://blog.mattsampson.net/index.php/exchange-hogging-dc-s-and?blog=1

Exchange 2010 - RBAC: démarche et mise en place

La mise en place de la délégation RBAC pour Exchange 2010, peut être un casse-tête pour les consultants Exchange.

Plus il y a d’équipes qui vont gérer Exchange, plus votre tâche sera ardue.

Pour rappel, Exchange 2010 introduit un nouveau mécanisme de délégation appelé RBAC (Role Based Access Control).

Je vous invite à jeter un coup d’œil sur RBAC pour ceux qui ne connaissent pas : http://technet.microsoft.com/en-us/library/dd298183.aspx

La mise en place de la délégation passe par plusieurs étapes :

1. Créer une matrice avec les différentes équipes Exchange (Groupes AD)et les rôles de chacune

Exemple :

clip_image002

2. Pour chaque tâche de la matrice, essayer de déterminer s’il faut utiliser un Management role Existant ou créer un management rôle spécifique.

Exemple :

clip_image004

3. Déterminer ensuite les scopes à créer : un scope correspond soit à une OU , DATABASE ou Server.

Exemple :

clip_image006

4. Dernière étape : lier les 3 composants : Goupe AD , le Management Role et le scope.

Ce lien est le MRA : Management Role Assignment.

L’ensemble de ces étapes sont faites en ligne de commande Powershell.

Exemples de commandes :

Création d’un Management Role :

New-ManagementRole -Name "MR-RECIPIENTCREATIONN1" -Parent "Mail recipient Creation"

Get-ManagementRoleEntry "MR-RECIPIENTCREATIONN1\*" | where {$_.name -like "new*"} | Remove-ManagementRoleEntry

Get-ManagementRoleEntry "MR-RECIPIENTCREATIONN1\*" | where {$_.name -like "remove*"} | Remove-ManagementRoleEntry -confirm:$false

Création d’un Management Scope :

New-ManagementScope Scope-Germany -RecipientRoot "domaine.local/germany" -RecipientRestrictionFilter {(RecipientType -eq "UserMailbox") -or (RecipientType -eq "Mailcontact") -or (RecipientType -eq "MailUser") -or (RecipientType -eq "MailUniversalDistributionGroup") -or (RecipientType -eq "MailUniversalSecurityGroup") -or (RecipientType –eq "DynamicDistributionGroup") -or (RecipientType -eq "PublicFolder")}

Création du Role Assignment :

New-ManagementRoleAssignment -name "RA-EXCHANGE-GERMANY-MR-MAILRECIPIENTIT-SCOPE-GERMANY" –Role "MR-RECIPIENTCREATIONN1" -SecurityGroup "AD-Exchange-Germany" -CustomRecipientWriteScope "Scope-Germany"

5. Après avoir fait vos tests , il se peut que vous ailliez besoin de revoir une configuration d’un MRA (Management Role Assisgnment ) ou d’un MR (Management Role)

Vous avez plusieurs solutions:

  • les commandes PowerShell,
  • Exchange Control Panel (ECP).
  • RBAC  MANAGER

RBAC Manager

Une Console GUI pour RBAC est disponible en CodePlex, elle permet d’afficher, de créer et modifier des rôles Assignement, des Management rôles et des scopes en mode graphique.

Elle intègre aussi un Optath Builder qui va faciliter la création des scopes ou des MR(Management Role) très ciblés

Par exemple : toutes les boites aux lettres de l’OU Paris avec comme attribut « City » égale à « Paris » .

Cela facilitera la gestion des MRA,MR et scopes.

Exemple de Commande pour modifier une commande lié à un MR en mode commande.

Avec RBAC manager , cela revient à décocher les paramètres qui seront désactivés ;)

add-ManagementRoleEntry MR-MailrecipientIT\Set-mailbox -Parameters AcceptMessagesOnlyFromDLMembers, AcceptMe

ssagesOnlyFromSendersOrMembers, AddressBookPolicy, Alias, AntispamBypassEnabled, ApplyMandatoryProperties, Arbitration,

ArbitrationMailbox, ArchiveDomain, ArchiveName, ArchiveQuota, ArchiveStatus, ArchiveWarningQuota, BypassModerationFromSe

ndersOrMembers, CalendarRepairDisabled, CalendarVersionStoreDisabled, Confirm, CustomAttribute1, CustomAttribute10, Cust

omAttribute11, CustomAttribute12, CustomAttribute13, CustomAttribute14, CustomAttribute15, CustomAttribute2, CustomAttri

bute3, CustomAttribute4, CustomAttribute5, CustomAttribute6, CustomAttribute7, CustomAttribute8, CustomAttribute9, Debug

, DeliverToMailboxAndForward, DisplayName, DomainController, DowngradeHighPriorityMessagesEnabled, EmailAddresses, Email

AddressPolicyEnabled, EndDateForRetentionHold, ErrorAction, ErrorVariable, ExtensionCustomAttribute1, ExtensionCustomAtt

ribute2, ExtensionCustomAttribute3, ExtensionCustomAttribute4, ExtensionCustomAttribute5, ExternalOofOptions, Force, For

wardingAddress, ForwardingSmtpAddress, GrantSendOnBehalfTo, HiddenFromAddressListsEnabled, Identity, IgnoreDefaultScope,

ImmutableId, Languages, LinkedCredential, LinkedDomainController, LinkedMasterAccount, LitigationHoldDate, LitigationHo

ldEnabled, LitigationHoldOwner, MailTip, MailTipTranslations, ManagedFolderMailboxPolicy, ManagedFolderMailboxPolicyAllo

wed, MaxBlockedSenders, MaxReceiveSize, MaxSafeSenders, MaxSendSize, MessageTrackingReadStatusEnabled, ModeratedBy, Mode

rationEnabled, Name, Office, OfflineAddressBook, OutBuffer, OutVariable, PrimarySmtpAddress, RecipientLimits, Recoverabl

eItemsQuota, RecoverableItemsWarningQuota, RejectMessagesFrom, RejectMessagesFromDLMembers, RejectMessagesFromSendersOrM

embers, RemoteRecipientType, RemoveManagedFolderAndPolicy, RemovePicture, RemoveSpokenName, RequireSenderAuthenticationE

nabled, ResourceCapacity, ResourceCustom, RetainDeletedItemsFor, RetainDeletedItemsUntilBackup, RetentionComment, Retent

ionHoldEnabled, RetentionPolicy, RetentionUrl, RoleAssignmentPolicy, RulesQuota, SamAccountName, SCLDeleteEnabled, SCLDe

leteThreshold, SCLJunkEnabled, SCLJunkThreshold, SCLQuarantineEnabled, SCLQuarantineThreshold, SCLRejectEnabled, SCLReje

ctThreshold, SecondaryAddress, SendModerationNotifications, SharingPolicy, SimpleDisplayName, SingleItemRecoveryEnabled,

StartDateForRetentionHold, ThrottlingPolicy, Type, UseDatabaseQuotaDefaults, UseDatabaseRetentionDefaults, UserCertific

ate, UserPrincipalName, UserSMimeCertificate, Verbose, WarningAction, WarningVariable, WhatIf, WindowsEmailAddress

Quelques Captures de la console RBAC MANAGER

Role Assignements :

image

Management Role

clip_image004[5]

Opath Builder en béta , très utile pour les scopes.

clip_image006[5]

Quelques liens utiles :

Understanding RBAC : http://technet.microsoft.com/en-us/library/dd298183.aspx

RBAC Manager : http://rbac.codeplex.com/

Exchange2010 – Erreur ActiveSync 1053 “Access is denied” suite à la migration d’une boîte aux lettres

Symptôme

Suite à la migration d’une boîte aux lettres Exchange Server 2003 SP2 vers un DAG Exchange 2010 SP1 RU6 (en environnement intra-organisationnel),  l’utilisateur ne peut plus synchroniser ses emails via ActiveSync et l’erreur suivante se produit régulièrement dans le journal Application du serveur CAS :

clip_image001

Voici le détail de l’erreur rencontrée :

Log Name: Application
Source: MSExchange ActiveSync
Date: 20/02/2012 10:00:46
Event ID: 1053
Task Category: Configuration
Level: Error
Keywords: Classic
User: N/A
Computer: CAS.domain.local
Description:

Exchange ActiveSync doesn't have sufficient permissions to create the "CN=Firstname.Lastname,OU=FR,OU=AllUsers,DC=domain,DC=local" container under Active Directory user "Active Directory operation failed on DC01.domain.local. This error is not retriable. Additional information: Access is denied.

Active directory response: 00000005: SecErr: DSID-031521D0, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0

Make sure the user has inherited permission granted to domain\Exchange Servers to allow List, Create child, Delete child of object type "msExchangeActiveSyncDevices" and doesn't have any deny permissions that block such operations.

 

De plus l’utilisateur ne peut pas voir son téléphone lorsqu’il accède à l’interface ECP (Exchange Control Panel) dans le menu Phone, puis Mobile Phone.

Explication

Avec Exchange Server 2003 les partenariats ActiveSync sont stockés dans un dossier caché au sein de la boîte aux lettres de l’utilisateur.

Ce dossier se nomme Microsoft-Server-ActiveSync et est visualisable à l’aide d’un outil tel que MFCMAPI (http://mfcmapi.codeplex.com/).

image

Avec Exchange Server 2010 les partenariats ActiveSync sont stockés directement dans l’annuaire Active Directory sous la forme d’un objet de type msexchangeActiveSyncDevice.

Lors de la migration de la boîte aux lettres vers Exchange Server 2010 le serveur Exchange possédant le rôle CAS doit donc créer un conteneur nommé CN=ExchangeActiveSyncDevices dans le compte utilisateur. Le serveur CAS créé ensuite un objet de type msexchangeActiveSyncDevice dans ce conteneur pour chaque partenariat ActiveSync établit.

Voici un exemple d’objet msexchangeActiveSyncDevice généré dans un environnement Exchange Server 2010 :

clip_image002

Dans notre exemple l’héritage des autorisations étaient désactivé sur le compte utilisateur. Cela a empêché la descente des ACL nécessaires au bon fonctionnement d’Exchange et donc a provoqué le message d’erreur 1053 Access is Denied sur le serveur CAS.

Cette désactivation était engendrée dans notre cas à cause de l’appartenance du compte utilisateur au groupe “Server Operators” qui est l’un des groupes protégé par le mécanisme AdminSDHolder.

Pour mémoire ce mécanisme a pour but de contrôler les ACL appliquées sur les objets (comptes utilisateurs, comptes ordinateurs…) membres des groupes protégés.

La liste des groupes protégés par le mécanisme AdminSDHolder dans les différentes versions de Windows (de Windows 2000 Server à Windows Server 2008 R2) est disponible sur le site de Microsoft à l’adresse suivante :

http://technet.microsoft.com/en-us/query/ee361593

Remarque : Dans notre cas le téléphone touché était un Sony Ericsson sous Symbian avec l’application RoadSync. Cependant ce problème étant dû à une configuration au niveau du compte Active Directory tout autre téléphone pourrait en être victime.

Résolution

Pour résoudre ce problème il faut se connecter à l’ADUC (Console “Utilisateurs et ordinateurs Active Directory”), puis dans les propriétés de l’utilisateur concerné choisir “Security”, “Advanced” puis cocher la case “Include inheritable permissions from this object’s parent”.

s-mail-01p - Connexion Bureau à distance

Suite à cette manipulation la synchronisation “initiale” (comprendre celle engendrant la génération des objets dans l’annuaire Active Directory) du téléphone fonctionnera ainsi que toutes les synchronisations ultérieures.

Une fois la première synchronisation effectuée l’utilisateur pourra visualiser et gérer ses partenariats ActiveSync dans l’interface ECP (la capture d’écran ci-dessous est un exemple).

image

Remarque : Il est intéressant de noter que le mécanisme AdminSDHolder remodifiera automatiquement les ACL (et donc re-désactivera l’héritage des autorisations) dans un délai d’une heure maximum (en effet le processus s’exécute toutes les 60 minutes par défaut).