Translate

samedi 18 août 2012

[TECH]: Compter le nombre de boîtes aux lettres dans une Mailbox Database en seulement quelques millisecondes

Hier, je cherchais je-ne-sais-plus-quoi et je suis tombé sur le blog d'un collègue norvégien, nommé Jan: http://blog.powershell.no/2010/11/21/retrieve-number-of-mailboxes-per-database-in-exchange-server-2010/

Bref, je me suis mis à lire l'article et il s'avère simplement que l'auteur cherchait à savoir comment compter le nombre de BàL par Mailbox Database le plus rapidement possible...

En effet, il y a des techniques plus ou moins rapide, et plus ou moins gourmandes en mémoire. Une technique "simple" est de faire un Get-Mailbox -Database <IdentifiantDB> -ResultSize:Unlimited. Cela retourne une collection ou $null si rien n'a été trouvé.

Au demeurant, le problème majeur de cette technique est qu'elle pourrait être rapide (c'est en fait la plus rapide en utilisant juste la cmdlet Get-Mailbox) mais elle a le gros désavantage de retourner une collection d'objets: c'est lent et cela consomme de la mémoire.

Typiquement, on ferait:
([Object[]] $Mailboxes = Get-Mailbox -Database <IdentifiantDB> -ResultSize:Unlimited).Count

Et si l'on voulait compter toutes les BàL Exchange 2010 (en utilisant la même technique):
([Object[]] (Get-MailboxDatabase | Get-Mailbox -ResultSize:Unlimited)).Count

On obtiendait alors des temps pas terribles (on mesure avec Measure-Command): 35 secondes et quelques pouillemes, mon lab a 8 Databases et environ 1200 BàL. Pis: dans de gros environnments, ce type de commandes échoue systématiquement ou finit par consommer une mémoire infernale (j'ai vu des sessions Powershell à plus de 8GB parfois :p).
Alors la technique de notre ami norvégien 'Jan Egil Ring' est d'utiliser une requête LDAP et de compter le nombre d'objets ayant le 'homeMDB' égal au DistinguishedName de la Database où l'on souhaite compter. Une peu à la Exchange 2000/2003 au fond...

Cela fonctionne très bien et c'est finalement ce que fait la commande Get-Mailbox (en construisant un filtre LDAP et en requêtant l'Active Directory), mais cela prends encore "quelques" secondes (le "quelques" étant variable). D'ailleurs j'utilisais cette technique moi-même avec des résultats que je jugeais alors optimums (j'ai de bons souvenirs d'optimisations de requêtes LDAP dans une grosse forêt multi-domaines avec plus de 200 mille objets...).

Je me suis dit qu'il faisait trop chaud (36°C à l'ombre :p) pour sortir gratter dans le jardin, et me suis lancé un mini-le défit: d'optimiser encore. J'ai finalement trouvé la réponse rapidement (c'est ballot car le soleil n'a pas décliné, et il fait encore 36°C :p).

Parmi les nombreux attributs présent sur un objet Mailbox Database (msExchPrivateMDB), il en est un qui s'appelle le 'homeMDBBL'... 'BL' pour Back Link. Il s'agit donc d'un attribut construit par AD lorsque l'attribut backlinké est modifié. Ici, l'attribut backlinké est le 'homeMDB'. Tiens donc... ? Cela signifie alors que le homeMDBBL contient les DistinguishedNames des BàL de cette Database. Pratique non ? S'agissant d'un attribut multi-valué, il suffit de récupérer l'attribut 'Count' via les interfaces ADSI.

On s'apperçoit que dans la liste il y a toujours une SystemMailbox{<} car à sa création, chaque DB se voit attribuer un GUID et une BàL (rien de nouveau sous le soleil quoi, c'est comme ça depuis Exchange 2000). Bref, on constate donc que le nombre de BàL dans une Mailbox Database est donc égal à 'compte d'entrées dans homeMDBBL moins 1'.

Un petit script que l'on nommera ici Get-MailboxCount.ps1, et voici ce que cela donne (en utilisant 'Measure-Object -Sum' afin de faire la somme:
Soit 50 millisecondes !!!
  • Pas de requête LDAP
  • Interrogation de l'objet AD correspondant à la DB depuis la partition Configuration, donc disponible sur tous les Contrôleurs de Domaine
  • Attribut disponible dans le Global Catalog
  • Si l'objet (ou les objets) Database est déjà stocké dans une variable, on gagne encore quelques millisecondes puisque l'on évite le Get-MailboxDatabase...
Gros handicap toutefois, il devient compliqué d'ajouter des filtres additionels. Mais cela permet d'jà de répondre au besoin initial de compter le nombre de BàL par Mailbox Database. Et vite!

Epatant, non? :)

Vous trouverez le script en question, ainsi que bien d'autres ici: http://sdrv.ms/PtoxZo

mardi 14 août 2012

[TECH]: Let's PowerShell - Scripts d'installation des pré-requis Lync et Exchange - 2010 et 2013...

Si vous me lisez de temps en temps, vous avez probablement remarqué au travers des captures d'écran prises lors de certain tutoriels que j'utilise des scripts faits maison.

Aujourd'hui est jour de fête (ou pas...) car je mets certains de ces scripts à disposition. Rien de révolutionnaire, mais ce sont toujours (je l'espère) de bon exemples.

Scripts de préparation des pré-requis Windows pour Lync
Lync 2010: INS-LS2010-WindowsRolesAndFeatures.ps1
Lync 2013(Preview): INS-LS2013-WindowsRolesAndFeatures.ps1

Scripts de préparation des pré-requis Windows pour Exchange
Il va de soi que les scripts pour Lync 2013 et Exchange 2013 ne sont pas dans leur version définitive, même si très proche. En particulier, la partie concernant la détection du système d'exploitation Windows Server 2012 n'est pas encore finalisée, puisque la version RC est actuellement détectée comme la RTM. Cela sera changé dès que j'aurai pu installer la version RTM de Windows Server 2012, mis à jour le numéro de build en conséquence et validé le changement.

Bonus
Quelques autres scripts en vrac:
Il y a quelques utilitaires sympas (par exemple des commandes PowerShell pour l'AD et sans utiliser le module AD PowerShell de Win 2008 R2), c'est assez basique mais j'en rajouterai probablement au fur et à mesure.

Get-ADSchemaVersion.ps1
Get-ADDomain.ps1, Get-ADDomainController.ps1, Get-ADSchemaHistory.ps1

Amusez-vous bien ! Et profitez de cette fin d'été pour vous mettre à Windows Server 2012 RTM, Lync/Exchange/SharePoint 2013 Preview et Office 365 v2 Preview !!! :)

[TUTORIEL]: Comment créer vous même un répartiteur de charge avec Ubuntu Server et HAProxy

Il y a quelques mois maintenant (plus d'un an en fait!) j'avais promis à certains de publier un guide expliquant comment créer son propre répartiteur de charge (load-balancer) en utilisant Ubuntu Server et HAProxy.

Ce guide, je l'avais commencé fin 2010 dans un but purement pédagogique interne à Avanade. Devant le succès rencontré auprès de certains collègues, je m'étais réfreiné afin de conserver un peu d'avance de connaissance sur la concurrence. Au final, le sujet étant désormais pleinement maîtrisé (tout du moins en ce qui concerne "comment load-balancer Exchange 2010 ou Lync 2010" :)), je mets maintenant le guide à disposition ici.

Attention: le guide est en anglais, mais pas d'inquiétudes toutefois: c'est beaucoup de blabla au début, et pas mal de technique ensuite...


Rappel: ce guide n'est pas là pour vous éviter d'implémenter un "vrai" load-balancer. L'auteur (moi) et les personnes morales ou sociétés dont les noms figurent dans ce guide ne sont aucunement engagées ou responsable de tout problème pouvant découler de l'utilisation de ce guide.

mercredi 8 août 2012

[TECH]: Exchange 2013 Preview, IIS et Kerberos - Ou: questionnement autour du MaxFieldLength

Tous ceux ayant déjà travaillé avec IIS sur SharePoint, Exchange et Lync et ayant "joué" à activer le Kerberos le savent: dans des environnements respectables et où il y a beaucoup de groupes de sécurités, il faut configure le pilote HTTP de Windows afin de supporter des en-têtes (MaxFieldLength) et tailles de requêtes (MaxRequestBytes) supérieures à la normale.

L'article idoine de la KB Microsoft (http://support.microsoft.com/kb/820129) le dit très bien:
Et, pour Exchange Server 2010, la DevTeam avait bien prévu l'augmentation de la taille des ces deux limites au travers d'un script nommé "LargeToken-IIS_EWS.ps1" (disponible dans "$exscript"). Ce qui est intéressant ici ce n'est pas tant que l'équipe Exchange l'avait prévu (à la base il s'agit en fait d'un script créé pour des cas particuliers) mais la valeur de MaxFieldLength qui est donc à son maximum de 64Ko - 2 octets (réservés pour les deux caractères de fin de chaîne en HTTP).

La valeur configurée dans le script d'Exchange Server 2010 est donc alignée avec la base de connaissance IIS de Microsoft. Dans des environnements plus classiques, mettre 65534 pour MaxFieldLength et 65536 pour MaxRequestBytes suffit généralement à résoudre 99.99% des problèmes (Note: MaxRequestBytes doit être à minima supérieur de 2 octets à MaxFieldLength).

Bref, éviter les problèmes Kerberos... Il semblerait que cela soit la volonté de la DevTeam car dans Exchange Server 2013 Preview, on constate que ces deux valeurs sont positionnées par défaut... à 65536 ! (Au passage, on remarque que les scripts en rapport avec Kerberos n'existent plus... :))

La preuve en images:
Là où le bât blesse est que la valeur positionnée par Exchange Server 2013 dépasse le maximum théoriquement configurable. Il faudra donc effectuer quelques tests et vérifier que le pilote HTTP.SYS se comporte correctement sur les deux systèmes supportés (Windows Server 2008 R2 SP1 et +, et 2012 RTM et +). En effet, il arrive parfois qu'une valeur de registre dépassant le maximum autorisé soit traitée comme invalide et donc ignorée (et donc 16Ko ici)... si le code du pilote HTTP.SYS est bien fait, il devrait traiter toute valeur hors limites comme étant la limite (donc ici, dépassant la limite haute: 65536 est corrigé en 65534).
Fait étrange (mais probablement pas exprès :)), Lync Server 2013 ne positionne pas cette valeur. Pourtant, il est fréquent que le Remote Shell Lync ne fonctionne pas pour cette même raison (à cause de la taille du token Kerberos...) et que cela fasse planter le Lync Control Panel .
Donc, sauf erreur de ma part, et étant un puriste, MaxFieldLength devrait être positionné à 65534. Je vais tout de même tenter de prévenir la DevTeam au cas où...