Ce n’est pas la première fois que j’ai à coder rapidement un petit fichier .bat pour exécuter des commandes automatiquement. Aujourd’hui, j’avais besoin d’un petit script envoyant le contenu du fichier de log le plus récent d’un répertoire sur un serveur sous Windows Server 2003 par email.
Sous linux, poster un mail, pas de problème. Sous windows j’avais encore jamais essayé et je redoutais le « il faut acheter tel module, ça fera tant etc.« … Mais en fait non, grace à un petit executable open source appellé Blat !
Blat est un petit executable utilisable en ligne de commandes ultra léger proposant des fonctions relativement simples d’utilisation. (voir ici pour sa syntaxe ou encore là pour les exemples).
J’avais le programme pour envoyer les mails, il ne manquait plus que le petit script qui va bien pour récupérer le dernier fichier .log du répertoire et lancer la commande d’envoi de mail.
@echo off
set repertoire="C:\Mon repertoire\"
set emetteur=email.emmeteur@domaine.com
set eMail=email.destinataireg@domaine.com
set copie=-cc destinataire.copie@domaine.com
set subj=-s "Titre de mon message"
set server=-server smtp.domaine.com
set x=-x "X-Header-Test: header supplémentaire optionnel inséré dans le mail"
set debug=-debug -log envois-mails.log -timestamp
FOR /F "tokens=*" %%i IN ('DIR /B /O-D %repertoire%*.log') DO set fichier="%repertoire:"=%%%i" && GOTO DONE || GOTO DONE
: DONE
blat %fichier% -mime -8bitmime -to %eMail% %copie% -f %emetteur% %subj% %server% %debug% %x%
set repertoire="C:\Mon repertoire\"
Pas trop compliqué, on indique le chemin absolu vers le répertoire. Ne pas oublier l’anti slash à la fin, il sert ensuite pour la construction de l’adresse du fichier.
set emetteur=email.emmeteur@domaine.com
L’adresse email qui enverra le message
set eMail=email.destinataireg@domaine.com
L’adresse email qui recevra le message
set copie=-cc destinataire.copie@domaine.com
L’adresse email qui recevra le message en copie. A noter que l’option est présente aussi dans la variable. Si l’on ne veux pas de copie il suffit de remplacer cette ligne par :
set copie=
set subj=-s "Titre de mon message"
Le sujet du message expédié
set server=-server smtp.domaine.com
On précise quel serveur servira de serveur d’envoi de mail. J’avais mis le serveur d’envoi de mail de la société qui m’emploi, on peut très bien mettre le smtp de son FAI si on veux (smtp.orange.fr par exemple)
set x=-x "X-Header-Test: header supplémentaire optionnel inséré dans le mail"
On peut préciser des entetes personnalisés au mail via l’option -x. Celui là ne sert à rien, il est juste présent en démonstration. Si on ne veux rien mettre, remplacer cette ligne par :
set x=
set debug=-debug -log envois-mails.log -timestamp
Blat permet de gérer son propre log. Pratique en cas de debug. Ici, il génèrera un fichier « envois-mails.log » si celui-ci n’est pas présent ou rajoutera des lignes en fin de fichier si celui-ci existe déjà. (un log quoi
)
FOR /F "tokens=*" %%i IN ('DIR /B /O-D %repertoire%*.log') DO set fichier="%repertoire:"=%%%i" && GOTO DONE || GOTO DONE
: DONE
Cette ligne était la plus importante pour moi.
On fait défiler le fichiers .log du répertoire en les ordinant du plus récent au plus ancien. Une fois qu’on a récupéré le nom du premier de la liste, on génère une variable « fichier » contenant la concaténation de la variable « %repertoire% » et de la variable « %%i » et on sort de la boucle.
Petite note sur la concaténation : Normalement, pour concaténer, il suffit d’utiliser cette syntaxe :
%var1%%var2%
Là mon soucis c’est que le répertoire peut contenir des espaces dans son chemin (par exemple : « Documents and settings »). J’étais donc obligé d’encadrer le contenu de la variable %repertoire% avec des doubles quotes. Le problème que j’avais en faisant un simple %repertoire%%%i c’est que ça me ressortait systématiquement (et logiquement) un contenu de variable comme cela :
"C:\Mon repertoire\"fichier.log
J’ai donc utilisé cette syntaxe :
%repertoire:"=%
Syntaxe qui correspondrait à un str_replace() en PHP. Ici en l’occurence, je remplace les doubles quotes de ma variable par un vide, je les efface donc.
Donc, en faisant un :
set fichier="%repertoire:"=%%%i"
J’obtiens un retour propre avec doubles quotes au bon endroit :
"C:\Mon repertoire\fichier.log"
Enfin, la dernière commande du fichier :
blat %fichier% -mime -8bitmime -to %eMail% %copie% -f %emetteur% %subj% %server% %debug% %x%
La commande appelle l’executable « blat » qui est présent dans le même répertoire que mon .bat (sinon il aurait fallu mettre C:\mon-repertoire\blat.exe) et lui passe les différentes variables en paramètres ce qui provoque l’envoi du mail.
Mise à jour :
J’ai remarqué après avoir posté ce billet que les emails arrivaient avec un encodage de caractères particulier, l’UTF-7.
Sur mon Outlook 2007 je n’observais aucun problème. C’est un collègue lisant ses mails via gmail qui était envoyé en copie qui m’a remonté que ses mails étaient illisibles.
Après « un peu » de recherche et de tests (une heure quoi ^^) j’ai fini par trouver qu’il fallait ajouter les options « -mime » et « -8bitmime » dans la commande « blat » pour que l’entête de l’email passe de :
Content-Type: text/plain; charset=UTF-7
à celui là plus conventionnel :
Content-Type: text/plain; charset=UTF-8
L’encodage UTF-8 (unicode) est beaucoup plus conventionnel, surtout aux yeux de Gmail
J’ai mis les sources à disposition dans cette archive pour les flemmards qui veulent tester rapidement. ![]()
Batch d’envoi de contenu de fichier par mail
Voilou, ce fut plus long a expliquer qu’a coder
Bonjour,
j’ai un problème avec votre script il me met à chaque fois fichier introuvable.
Je ne sais pas pourquoi?
Pouvez-vous m’aider, Merci
Bonjour,
Avez-vous essayé de stocker le fichier a envoyer dans un répertoire « simple » (voir directement à la racine du C:\ ) ?
Le nom du fichier a envoyer contient t’il des espaces?
Est-ce bien un fichier avec l’extension en .log ?
C’est un script que j’ai monté il y a un bon moment, mais a ce jour il est toujours utilisé tous les jours sans bug. (vu le peu de code qu’il y a, pas étonnant) Par contre, je ne l’ai pas testé non plus dans tous les cas de figure possible et imaginable …
Dans une invite de commande, essayez de taper :
DIR /B /O-D « C:\mon repertoire\ »*.log
(en personnalisant bien sur).
Puis copiez/collez la commande ici que je la vois
C’est la même commande que celle du script, elle scanne le répertoire et ne ressort que les fichiers en .log
envois-mails.log
post-log-email.bat
Blat.bat
essai.vbs
fichier.log
blat.dll
blat.lib
blat.exe
Voila ce qu’elle me ressort et j’ai bien mon fichier.log, mais lorsque je lance le script il me trouve rien.
Voici le script :
@echo off
set repertoire= »C:Blat250\full\ »
set emetteur=passager@domaine.fr
set eMail=passager@domaine.fr
set copie=-cc destinataire.copie@domaine.com
set subj=-s « LOG »
set server=-server 192.168.1.1
set x=-x « X-Header-Test: header supplémentaire optionnel inséré dans le mail »
set debug=-debug -log envois-mails.log -timestamp
FOR /F « tokens=* » %%i IN (‘DIR /B /O-D %repertoire%*.log’) DO set fichier= »%repertoire: »=%%%i » && GOTO DONE || GOTO DONE
ONE
blat %fichier% -mime -8bitmime -to %eMail% %copie% -f %emetteur% %subj% %server% %debug% %x%
je penses que ça vient de là :
C:Blat250\full\
Il manque l’antislash après le « C: », ça devrait être :
C:\Blat250\full\
Ensuite, personnellement, je mettrai le fichier de log dans un autre répertoire que le répertoire de blat ; ça devrait fonctionner quand même vu qu’on prend le fichier .log le plus récent mais bon dans le doutes, j’éviterai.
Enfin, juste un détail, il doit y avoir un espace entre les deux points et le DONE juste avant la commande blat.
: DONE
Dans le commentaires, on voit un smiley, sous-entendu qu’il n’y a pas d’espace (après, ça peut très bien être les commentaires du blog qui font un rendu comme ça (on verra bien quand je posterai mon commentaire ^^)
Super c’était bien le \ qui n’était pas présent, je n’avais même pas vu.
J’aurais une autre petite question.
En faite je fais un robocopy qui me généré 3 logs :
- log1.log
- log2.log
- log3.log
Et j’aimerai que ses 3 log soit envoyé avec mon Blat mais le problème c’est qu’il m’envoi à chaque fois 1 seul log, surement le dernier reçu
Est-ce que c’est possible de recevoir les 3 ?
Merci pour votre aide
Est-ce que quelqu’un aurait une idée pour que je reçoive avec ce script mais 3 logs ?
Merci d’avance
Bonjour,
Désolé, j’ai peu de temps pour répondre donc je n’apporte pas le code directement mais la méthode que j’emploierai.
Ca se joue ici :
FOR /F « tokens=* » %%i IN (‘DIR /B /O-D %repertoire%*.log’) DO set fichier= »%repertoire: »=%%%i » && GOTO DONE || GOTO DONE
: DONE
La boucle tourne une seule fois puis le script va a l’emplacement : DONE qui s’en va executer la commande blat. Il faudrait que la commande blat soit elle aussi dans la boucle donc pour envoyer 3 mails (un par fichier log)
Il faudrait initialiser un compteur avant le départ de la boucle SET i=1
ONE
Dans la boucle, incrementer un +1 a la variable i
faire une condition « si i égal à 3 GOTO
: DONE serait simplement la fin du script
Désolé, pas le temps de coder là… peut être plus tard mais pas avant la fin du weekend