Le blog technique

Toutes les astuces #tech des collaborateurs de PI Services.

#openblogPI

Retrouvez les articles à la une

Office 365 – Retour d’expérience d’une migration IMAP

Introduction

L’offre Office 365 inclut un outil de migration. Cet outil permet la migration des boites mails depuis Exchange (2003 / 2007 / 2010 /2013) vers Office 365 ou depuis un autre serveur de messagerie utilisant l’IMAP vers Office 365.
Ce billet portera sur mon retour d’expérience d’une migration IMAP vers Office 365.

Retour d’expérience

Les prérequis

1) Chaque compte migré doit avoir un utilisateur unique associé avec une licence active. Le compte peut être uniquement dans le cloud ou synchronisé avec Active Directory (via DirSync par exemple).
Dans le cadre d’une architecture hybride (c’était le cas dans ce projet), d’autres prérequis utilisateurs sont nécessaires. L’utilisateur doit être "connu" par les serveurs Exchange OnPremise. Pour cela la commande PowerShell suivante est à passer sur les serveurs Exchange OnPremise :

Enable-RemoteMailbox –Identity Utilisateur –RemoteRoutingAddress utilisateur@tenant.mail.onmicosoft.com –PrimarySMTPAddress utilisateur@domaine.fr
Remarque : Attention, si l’utilisateur possède d’autres adresses SMTP que la principale il est nécessaire de les indiquer dans la commande à l’aide du paramètre EmailAddresses
Remarque 2 : Il est également recommandé d’avoir l’UPN (UserPrincipalName) de l’utilisateur qui soit égal à l’adresse email afin de faciliter la connexion aux services Office 365.

2) Un Migration Endpoint avec les éléments suivants :

  • L’URL du serveur IMAP
  • Le type d’authentification (Basic ou NTLM)
  • Le chiffrement (Aucun, SSL, TLS)
  • Le port utilisé pour se connecter en IMAP au serveur
  • Le nombre maximum de migrations simultanées
  • Le nombre maximum de synchronisation incrémentales simultanées

image
3) Un fichier CSV contenant l’adresse email cible, le nom d’utilisateur et le mot de passe du compte IMAP (ou d’un compte administrateur). Le fichier CSV sera construit ainsi :

Les éléments migrés

La migration IMAP n’inclut que la partie mail. En effet les éléments de type contacts, calendrier, tâches… ne sont pas pris en compte.
La migration IMAP prend en compte les mails qui se trouvent dans les différents dossiers (et sous dossiers) personnels ainsi que les dossiers de base (Boite de réception, éléments envoyés, éléments supprimés…).

La migration

La migration se déroule par lot. Chaque lot peut comporter jusqu’à 5000 utilisateurs.
Pour une meilleure gestion des erreurs et de la volumétrie, des lots de 1200 utilisateurs environ ont été fait.
A titre d’exemple, le temps de migration pour un lot de 1200 utilisateurs ayant une volumétrie d’environ 30 Go au total (soit une moyenne de 25Mo/BAL) a mis un peu plus de deux heures.
Cette estimation est bien évidement propre à l’architecture et peut être différente en fonction de la bande passante et des performances du serveur source.

La gestion des erreurs

Il est courant qu’un lot de migration comporte des erreurs. Pour les identifier il est possible d’utiliser la commande PowerShell suivante sur le tenant Office 365 :
Get-MigrationUser -ResultSize Unlimited | ?{$_.Status -ne "Synced"}

image

Les utilisateurs en échec peuvent être sorti du lot de migration et relancés dans un lot séparé.
Remarque : Un utilisateur ne peut pas être inclus dans un nouveau lot s’il appartient déjà à un lot. Microsoft met également à disposition des rapports (au format CSV) sur la plateforme d’administration d’Office 365 – Exchange.

Conclusion

Dans le cadre de cette migration, le pourcentage d’erreur a été de 0.2% (moins d’une vingtaine de boites en erreur sur plus de 6000 boites migrées).
Le seul point négatif est la limite des éléments migrés. Les calendriers, carnets d’adresses… ne sont pas pris en compte et doivent être fait manuellement par l’utilisateur ou via un autre outil de migration.

Pour conclure l’outil de migration fonctionne parfaitement. Même s’il possède peu de fonctionnalités contrairement à d’autres outils de migration (Refresh IT, Quest…) il permet une migration simple à un moindre coût.

SCOM – Créer une vue avec un filtre « NOT »

 

Tout administrateur SCOM qui se respecte a déjà été amené à créer des vues d’alerte ou d’état spécifiques, ciblées sur une classe et filtrées en fonction d‘un niveau de résolution (resolution state), d’une criticité…

clip_image001

clip_image002

Une problématique revient cependant de temps en temps : comment créer une vue qui exclue spécifiquement certaines alertes en fonction de leur nom ?
Autrement dit, comment afficher toutes les alertes SAUF celles correspondant à un certain nom ?

Le filtre « with a specific name » ne permet à première vue pas de réaliser cette exclusion ; il semble plutôt prévu pour fonctionner en mode « inclusif » : seules les alertes répondant à la chaine de caractères entrée seront affichées :

clip_image004

Mais il est en réalité possible d’utiliser une expression d’exclusion dans ce champ, en plus des wildcards « SQL », à l’aide de la syntaxe suivante :

[^AlerteAExclure]

clip_image006

Voici le résultat obtenu :

clip_image008

Il est également possible de combiner plusieures exclusions à l’aide du symbole « pipe » :

[^(AlerteAExclure)|(TestAlert2)]

Attention toutefois, cette astuce exclut en réalité un groupe de caractères et ne supporte donc pas l’utilisation d’espaces.

Powershell: Gestion des erreurs sur Cmdlet

 

Dans mon précédent blog, je vous est montré comment on pouvait mettre en place la gestion d’erreur sur des commandes sous powershell qui ne sont pas des CMDLET, cette fois-ci nous allons voir comment appliquer la gestion d’erreur sur une CMDLET

PERIMETRE: Dans le cadre de l’amélioration des script powershell concernant la vérification des services après le redémarrage des serveurs en production chez un de nos client, celui-ci à laisser le soin au service architecture de trouver une solution.

 

Mon script d’origine:

######SERVEURS A REDEMARRER################

$Computerstring = "orches1"
$Computerdestination = $Computerstring.Split(",")

######SERVICES A ARRETER ET REDEMARRER################

$Servicesstring = "wudfsvc"
$Servicesname = $Servicesstring.Split(",")

######LOG CREER POUR LA VERIFICATION AVANT L’ARRET DES SERVICES SUR CHAQUES SERVEURS + GESTION ERREUR SUR SYNTAXE Command###
$StatusService = foreach ($vm in $Computerdestination){
         get-Service -ComputerName $vm -name $Servicesname | select status,name,machinename }
       

#GESTION ERREUR DES SERVICES

$ExitCodeService = foreach ($SRVservices in $StatusService) {
if ($($SRVservices.status) -eq "Running"){
"Success : Service(s) Running" + $SRVservices
}else{
"Error : Service(s)" + $SRVservices
}
}

$ErrorStatusSVC = if ($StatusService -eq $null){
"Error : Service(s) "
}else{
"Success : Service(s)"
}  

Voici le résultat pour les sortie erreurs:

$ExitCodeService

image

$ErrorStatusSVC

image

Vous voyez au dessus $ExitCodeService prend en compte que le service wudfsvc étant arrêté comme SUCCESS condition voulu ceci est normal et que $ErrorStatusSVC à été mise en place pour anticipé les erreurs $ExitCodeService si aucune valeur ne ressort ($ExitCodeService = VIDE) cela peut être une erreur de syntaxe, de service ou de serveurs inaccessible ou inexistant

Par contre aucune erreur détailler il faut effectuer une recherche supplémentaire.

 

Mon script amélioré:

######SERVEURS A REDEMARRER################

$Computerstring = "orches1"
$Computerdestination = $Computerstring.Split(",")

######SERVICES A ARRETER ET REDEMARRER################

$Servicesstring = "wudfsvc"
$Servicesname = $Servicesstring.Split(",")

######LOG CREER POUR LA VERIFICATION AVANT L’ARRET DES SERVICES SUR CHAQUES SERVEURS + GESTION ERREUR SUR SYNTAXE Command###

$StatusService =
Try {
foreach ($vm in $Computerdestination){
         get-Service -ComputerName $vm -name $Servicesname -ErrorAction stop | select status,name,machinename
        }
}catch{
   "$vm => " + $Error[0]
   }

#GESTION ERREUR DES SERVICES

$ExitCodeService =                                                                                         foreach ($SRVservices in $StatusService) {
            if ($($SRVservices.status) -eq "stopped"){
                    "Success:" + $SRVservices
            }else{
                   "Error:" + $SRVservices
            } 
    }

Voici le résultat pour la sortie d’erreur:

La correction se base sur la gestion d’erreur avec les commandes Try et Catch

Dans la partie Try  entre crochets, la commande get-service doit obligatoirement avoir l’option qui permet la sortie d’erreur qui se nomme        –ErrorAction stop cela permettra d’avoir dans la partie catch les messages d’erreur le déroulement du processus $Error[0] . 

Message des erreurs qui sont géré dans : $StatusService

image

Erreur sur le compte d’ordinateur inexistant ou inaccessible:

image

Erreur sur le service inexistant ou inaccessible:

image

Erreur sur la syntaxe commande get-service:

image

Les messages de sortie sont aussi retransmis dans la variable  $ExitCodeService à l’aide des conditions if et else