How to migrate contacts from Windows Live Mail to Outlook.com

(English translation coming soon !)
Il semble qu’il y ait un problème d’export / import de contacts de « Windows Live Mail » vers « Outlook.com ».
import_outlook
Le format d’export de Windows Live mail (fichier *.CSV) ne semble pas reconnu par Outlook…
Solution : On ne va pas se laisser abattre ! Migrons le format CSV de Windows Live Mail vers le format reconnu par Outlook avec un petit traitement powerShell pour faire cet import :
import_outlook_2
Le script PowerShell peut ressembler à ci-dessous. Tout ce que vous avez à changer est le nom du fichier « windows_live_mail_export_file.csv ». Attention, je récupère les champs les plus utilisés :

#Header line. Every value must be enclosed in double-quotes (that’s not the cas in Windows Live mail export)
$output = "`"Title`",`"First Name`",`"Middle Name`",`"Last Name`",`"Suffix`",`"Given Name Yomi`",`"Family Name Yomi`",`"Home Street`",`"Home City`",`"Home State`",`"Home Postal Code`",`"Home Country`",`"Company`",`"Department`",`"Job Title`",`"Office Location`",`"Business Street`",`"Business City`",`"Business State`",`"Business Postal Code`",`"Business Country`",`"Other Street`",`"Other City`",`"Other State`",`"Other Postal Code`",`"Other Country`",`"Assistant’s Phone`",`"Business Fax`",`"Business Phone`",`"Business Phone 2`",`"Callback`",`"Car Phone`",`"Company Main Phone`",`"Home Fax`",`"Home Phone`",`"Home Phone 2`",`"ISDN`",`"Mobile Phone`",`"Other Fax`",`"Other Phone`",`"Pager`",`"Primary Phone`",`"Radio Phone`",`"TTY/TDD Phone`",`"Telex`",`"Anniversary`",`"Birthday`",`"E-mail Address`",`"E-mail Type`",`"E-mail 2 Address`",`"E-mail 2 Type`",`"E-mail 3 Address`",`"E-mail 3 Type`",`"Notes`",`"Spouse`",`"Web Page`"" + "`r`n"
$output | out-file ".outlook.com_export_file.csv"
# Let’s parse each line of the original export file
Get-Content "windows_live_mail_export_file.csv" | % {
# Values are separated by comas
$infosArray = $_.Split(",")
# Store in variable the wanted values
$FirstName = $infosArray[0]
$Name = $infosArray[1]
$Email = $infosArray[5]
$Street = $infosArray[6]
$Town = $infosArray[7]
$PostalCode = $infosArray[8]
$Country = $infosArray[10]
$HomePhone = $infosArray[11]
$HomePhone2 = $infosArray[12]
$MobilePhone = $infosArray[13]
$WebSite = $infosArray[14]
$Comment = $infosArray[28]
$output = ",`"$FirstName`",,`"$Name`",,,,`"$Street`",`"$Town`",`"$Dpt`",`"$PostalCode`",`"$Country`",,,,,,,,,,,,,,,,,,,,,,,`"$HomePhone`",`"$HomePhone2`",,`"$MobilePhone`",,,,,,,,,,`"$Email`",,,,,,`"$Comment`",,`"$WebSite`""
# Concatenation of new line
Add-Content ".outlook.com_export_file.csv" $output
}

Attention, lors du choix du format de l’import, il faut choisir « Outlook.com » !
import_outlook_3

DevOps + SharePoint ?

I think the structure of SharePoint is naturally « DevOps oriented ». Actions to create web applications and configure services through a web interface is a DevOps philosophy ! On standard .NET environnements, such actions require interventions on servers, but SharePoint does this « out-of-the-box ».
But the work of DevOps in a SharePoint environment is not limited to that. In the case of a SharePoint farm hosting several applications, how to ensure that a solution deployment does not impact non-concerned applications ? How to be sure that an application will not be broken by an undisciplined neighbor ?
Because SharePoint is a complex service, the traditional tools of production operators are not sufficient to watch a farm. And on the other hand, development teams should not have to worry about server scalability !
This is the role of DevOps : Being the bridge between developers and production, while maintaining a consistent chain of delivery.
In a future post I will talk about the tools available to the « DevOps SharePoint ».
This is my view about what a « DevOps SharePoint » shoud be :

How to "DevOps" SharePoint ?
How to « DevOps » SharePoint ?

Traduction française :
Je pense que la structure même de SharePoint est orientée DevOps. Les actions de création d’applications web et de configuration de services au travers d’une interface web est une philosophie DevOps ! Ce genre d’actions nécessiteraient des interventions sur les serveurs, mais ici c’est SharePoint qui contrôle cela « out-of-the-box ».
Mais le travail du DevOps dans un environnement SharePoint ne se limite pas à cela. Dans le cas d’une ferme SharePoint qui hébergeraient plusieurs applications autonomes, comment garantir qu’un déploiement de solution n’impacte pas des applications non concernées ? Comment être sûr qu’une application ne soit pas impactée par le développement du voisin ?
Parce que SharePoint est un service complexe, les outils classiques des opérateurs / exploitants de production ne suffisent pas à gérer une ferme. Mais d’un autre côté, les équipes de développement n’ont pas à se soucier de l’évolutivité (scalability) des serveurs !
C’est là le rôle du DevOps : Faire le pont entre dev et prod, tout en maintenant une chaine de livraison cohérente.
Dans un prochain post je parlerais des outils à disposition du « DevOps SharePoint ».

Combien ça rapporte de développer un jeu pour mobiles ?

Et bien pas grand chose !
Attention, on parle d’un jeu de base sans prétention développé par un clampin sur ses heures de sommeil.
Prenons Colorseeds pour Windows Phone : il est gratuit, et rapporte quelques millièmes de centime d’euro à chaque fois qu’une publicité s’affiche (bannière en haut de l’écran de jeu).
Prenons le mois d’avril :
– Colorseeds est présent dans plus de 180 pays, et il a été mis en avant (= plus de visibilité sur le Store) environ 60 fois (dont des pays à fort potentiel comme les Etats-Unis et le Canada),
– Il a été téléchargé 8290 fois, dont 1000 en France (c’est très peu !),
– Plus d’un million de publicités ont été affichées (c’est beaucoup ! Les gens qui ont téléchargé ont beaucoup joué),
– Le CPM (« coût par mille »), c’est à dire le nombre d’euros que me rapporte 1000 publicités affichées est de : 0.05€ (pas terrible),
– Ce qui donne : 1 543 138 pub * 0.05 CPM / 1000 = 51€ environ…
Bref, il me faudrait plus d’une vingtaine de jeux pour gagner un SMIC… Ou alors investir dans de la promo massive !
pubcenter_colorseeds_avril2014
 
Pour les heureux possesseurs d’un Windows Phone, Colorseeds se télécharge ici :
Download Colorseeds for Windows Phone !

DevOps, ou comment nommer l'innommable.

Le métier de DevOps est de réconcilier les développeurs et les exploitants.
Les exploitants de production gèrent leurs serveurs avec toute l’affection qu’une mère porte à sa couvée. On surveille, on s’inquiète. Pas trop de température ? Pourquoi les fichiers de logs grossissent ? Y aurait pas comme une pointe de consommation de CPU là ?
Quant aux développeurs, voilà une bande d’hystériques* toujours à l’affût du dernier framework à la mode, prêts à déployer n’importe quelle fonctionnalité à peine testée sur les beaux serveurs clusterisés qui n’avaient rien demandé.
Bref, on oppose stabilité et changement. Deux politiques contradictoires qui doivent pourtant collaborer étroitement !
Quoi de plus frustrant qu’une gestion de projet agile s’il elle se casse les dents au moment de la mise en prod ?
pass
Mais voici le DevOps ! Celui qui va faciliter les mises en prod, fluidifier les processus, apaiser les craintes.
Il intervient dans la mise en place des processus suivants – que chaque adorateur de l’agilité reconnaîtra :

  • L’intégration continue : Déploiements réguliers sur les serveurs d’intégration.
  • La livraison continue : Déploiements réguliers de builds vers la recette, puis pré-prod et prod.

Et le DevOps intervient aussi dans la mise à disposition d’outils « passerelles » entre ces différentes plateformes.
Pourquoi je parle de tout cela ? Parce qu’il s’agit de ma mission actuelle. Difficile à nommer au départ (admin ? dev ? AMOE ?), elle peut peut enfin être qualifiée en « DevOps ».
Plus qu’un terme à la mode, les équipes DevOps sont une brique essentielle des grandes entreprises IT telle que Google, qui peuvent rapidement mettre en place de nouvelles fonctionnalités dans leur services.
Sources : Article sur 01.netDevOpsDays
*Humour

Check my "European e-Competence Framework"

Quand on demande « quelles sont vos compétences », il est important d’avoir le même langage, les mêmes termes. C’est le but du « Référentiel européen des compétences informatiques » (e-CF), qui permet au personnel technique, aux clients de services informatiques et aux RH de communiquer 🙂 Alors je me suis amuser à auditionner mes propres compétences – en toute transparence !
Compétences
 
Source : http://www.ecompetences.eu/site/objects/download/6063_EUeCF2.0userguideCWAPartIIFR.pdf
http://www.ecompetences.eu/site/objects/download/6068_EUeCF2.0CWAPartIFR.pdf

Utilisation du type de variables "Decimal"

« Decimal » a été créé pour avoir une précision plus grande, mais dans une plage de valeurs plus restreinte.
Il est préconisé dans les applications monétaires, tandis que les autres types à virgules flottantes (double, single) sont destinés aux calcules scientifiques (et ils ont une vitesse de traitement plus rapide).
Fait amusant :

Decimal numerateur = 1m;
Decimal denominateur = 3m;
Console.WriteLine(numerateur / denominateur * denominateur);

Le résultat sera 0.999999… Ceci parce que Decimal est justement trop précis !
L’utilisation de Round permettra de profiter de la précision de Decimal, tout en faisant les arrondis nécessaires. Comme cité dans cette ressource : « Le type Decimal n’élimine pas la nécessité d’arrondir. Il réduit plutôt des erreurs en raison de l’arrondi ».

Console.WriteLine(Math.Round(numerateur / denominateur * denominateur, 2));

Ceci retournera 1.00.
L’utilisation des autres flottants n’est pas conseillé. Car les erreurs d’arrondis vont plus faciement s’accumuler à fur et à mesure des calculs.
Cet exemple ci-dessous ne doit pas fausser l’opinion des développeurs :

Double numerateur = 1f;
Double denominateur = 3f;
Console.WriteLine(numerateur / denominateur * denominateur);

Le résultat sera de 1 ! Mais cela reflète simplement un manque de précision de la division avec ce type de flottants : numerateur / denominateur = 0.3333343
 

Log4Net / Powershell : Modifier à la volée la configuration d'un appender

Pour les besoins d’un projet, je devais modifier dynamiquement le nom du fichier de traces généré par la bibliothèque Log4Net. La majorité de la configuration est située dans un fichier .config, tandis que le nom du fichier de sortie est géré à l’exécution du script.
Voici l’adaptation de mon script Powershell que j’ai dû effectuer :

# Chargement de la bibliothèque et de sa configuration.
 [void][Reflection.Assembly]::LoadFrom( "log4net.dll")
 $FileInfo=new-object System.IO.FileInfo "log4net.Config"
 [log4net.Config.XmlConfigurator]::Configure($FileInfo)
# Configuration du nom du fichier de trace
 # - Récupération de l'appendre défini dans le fichier .config
 $hierarchy = [log4net.LogManager]::GetRepository()
 $appender = $hierarchy.GetAppenders() | Where-Object { $_.Name -eq "MonAppender" }
# - Modification du nom du fichier log
 $appender.File = "E:	racesout.log"
 $appender.ActivateOptions()
# Récupération de l'objet pour gérer les traces dans le script
 $LogFile = [log4net.LogManager]::GetLogger($logger)
$LogFile.Error("bla bla bla")

Pour info, voici à quoi ressemble le fichier de configuration :

<?xml version="1.0" encoding="utf-8" ?>
 <log4net>
 <appender name="MonAppender" type="log4net.Appender.RollingFileAppender">
 <file value="E:	races" />
 <appendToFile value="true" />
 <staticLogFileName value="false" />
 <rollingStyle value="Date" />
 <layout type="log4net.Layout.PatternLayout">
 <param name="ConversionPattern" value="%d{yyyy-MM-dd hh:mm:ss} %-5p - %m%n" />
 </layout>
 <filter type="log4net.Filter.LevelRangeFilter">
 <levelMin value="DEBUG" />
 <levelMax value="FATAL" />
 </filter>
 </appender>
<root>
 <level value="DEBUG" />
 <appender-ref ref="MonAppender" />
 </root>
 </log4net>

Batch DOS : Supprimer un ensemble de fichiers en conservant les plus récents

Pour supprimer tous les fichiers d’un répertoire, mais en conservant les plus récents, une seule ligne de commande suffit.
Pratique lorsque qu’on souhaite conserver les fichiers de traces *.log des 7 derniers jours par exemple :
forfiles /P "C:dossier races" /M "*.log" /C "cmd /c del @file" /d -7
Et oui, je découvre la commande « forfiles » à 33 ans, c’en est presque émouvant. Plus d’info ici : Technet.

SharePoint 2010 : Workflow d'envoi de mails déclenché par un utilisateur anonyme.

Les utilisateurs anonymes ne sont pas autorisés à déclencher certains flux de travail (workflow), notamment ceux qui envoient des mails.
Prenons l’exemple d’une liste qui déclenche un workflow d’envoi de mail sur l’ajout d’un élément :
Workflow_1
Ici l’envoi de mail sera un échec, car la tâche d’envoi de mail nécessite plus de droit que ne peut avoir un utilisateur anonyme.
Pour remédier à cela, une solution serait de faire déclencher le workflow par un événement tiers :
Workflow_2
Il suffit d’insérer un event-handler qui va prendre en charge l’événement « ajout d’un élément » à la place du workflow, et qui va forcer le démarrage du workflow « à la main ».
Le code de l’event-handler pourrait ressembler à cela :

public class List_EventReceiver : SPItemEventReceiver
{
 /// <summary>
 /// Un élément a été ajouté, on lance le workflow avec privilèges.
 /// </summary>
 public override void ItemAdded(SPItemEventProperties properties)
 {
    base.ItemAdded(properties);

        // Exécution en élévation de privilège
    SPSecurity.RunWithElevatedPrivileges(delegate()
   {
      using (SPSite site = new SPSite("http://mon_site"))
      {
        using (SPWeb siteWeb = site.OpenWeb())
        {
          SPList list = siteWeb.Lists["Ma_Liste"];
          SPWorkflowAssociation wf = list.WorkflowAssociations.GetAssociationByName("Nom_du_Workflow", System.Globalization.CultureInfo.CurrentCulture);
          // Lancement du workflow
          site.WorkflowManager.StartWorkflow(list.GetItemById(properties.ListItemId), wf, wf.AssociationData);
        }
      }
   });
 }
}

PERL / Appcmd : Add a mapping element that contains spaces and quotes.

How to encode encoded characters without escaping them ? ^_^
When you try to add a module mapping for perl, it is supposed to be configured like this in IIS :
Request Path : *.pl
Executable : C:Perlinperl.exe « %s » %s
This declaration looks like this in IIS config files (web.config or machine.config) :
<handlers>
<add name="Perl" path="*.pl" verb="GET,HEAD,POST" modules="CgiModule" scriptProcessor="E:Perl64Perl64inperl.exe &quot;%s&quot; %s" />
</handlers>
The double-quotes that surrounds %s are encoded with XML encoding.
But when you use appcmd command to declare this module mapping, it is a bit more tricky, because you cannot use the special character &. Furthermore, the presence of spaces into the « scriptProcessor » attribute force you to surround the whole expression with double-quotes…
So, this is the appcmd command :
appcmd.exe set config /section:handlers /"+[name='Perl',paverb='GET,HEAD,POST',modules='CgiModule',scriptProcessor='E:Perl64Perl64inperl.exe %u0022%s%u0022 %s']"