Question
Powershell, les tableaux et les fichiers CSV
- Evea
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
- Messages : 11
- Remerciements reçus 0
J'en suis donc au point ou mon script est censé envoyer un mail aux adresses présentes dans le fichier.
Pour faciliter la tâche, je n'ai mis qu'une seule adresse dans le fichier.
[code:1]### Choix du fichier à utiliser ###
### /!\ only CSV file ###
$objForm = New-Object System.Windows.Forms.OpenFileDialog
$objForm.InitialDirectory = \"C:\Users\nom_user\Documents\"
$objForm.Filter = \"csv files (*.csv)|*.csv\"
$objForm.Title = \"Veuillez sélectionner un fichier...\"
$Show = $objForm.ShowDialog()
$fichier = Import-Csv $objForm.FileName -Delimiter \";\"
### Parametres mail ###
$serveurSMTP = \"x.x.x.x\"
$mailFrom = \"blabla@paris.fr\"
$pj = \"C:\cal2015atp.pdf\"
$mailSubject = \"Test\"
$fichier | foreach {
$body = \"Bonjour $($_.qualite) $($_.nom) $($_.prenom)\"
$mailTo = $_.mail
Send-MailMessage -to \"$mailTo\" -subject \"$mailSubject\" -body \"$body\" -SmtpServer \"$serveurSMTP\" -from \"$mailFrom\" -Attachments \"$pj\"
}
[/code:1]
Or, quand j'exécute ça, j'ai une multitude d'erreurs !!
[code:1]Send-MailMessage : Impossible de valider l'argument sur le paramètre « To ». L'argument est null ou vide. Indiquez un argument qui n'est pas null ou vide et réessayez.
Au niveau de ligne : 22 Caractère : 25
+ Send-MailMessage -to <<<< \"$mailTo\" -subject \"$mailSubject\" -body \"$body\" -SmtpServer \"$serveurSMTP\" -from \"$mailFrom\" -Attachments \"$pj\"
+ CategoryInfo : InvalidData: (: ) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
Send-MailMessage : Impossible de valider l'argument sur le paramètre « To ». L'argument est null ou vide. Indiquez un argument qui n'est pas null ou vide et réessayez.
Au niveau de ligne : 22 Caractère : 25
+ Send-MailMessage -to <<<< \"$mailTo\" -subject \"$mailSubject\" -body \"$body\" -SmtpServer \"$serveurSMTP\" -from \"$mailFrom\" -Attachments \"$pj\"
+ CategoryInfo : InvalidData: (: ) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
Send-MailMessage : Impossible de valider l'argument sur le paramètre « To ». L'argument est null ou vide. Indiquez un argument qui n'est pas null ou vide et réessayez.
Au niveau de ligne : 22 Caractère : 25
+ Send-MailMessage -to <<<< \"$mailTo\" -subject \"$mailSubject\" -body \"$body\" -SmtpServer \"$serveurSMTP\" -from \"$mailFrom\" -Attachments \"$pj\"
+ CategoryInfo : InvalidData: (: ) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
[/code:1]
Erreurs que je ne comprends pas, puisque dans le \"-To\", il y a le \"$_.mail\" qui contient lui-même l'adresse mail présente dans le fichier...
Edit (oui, encore...) : ça commence à me fatiguer
Malgré les erreurs, le mail a bien été envoyé... et je l'ai bien reçu.
Je viens donc de tester avec deux adresses dans le fichier, et pareil, les mails ont été envoyés...
Ma question est donc : pourquoi toutes ces erreurs ??
De plus, le texte du mail se trouve dans un fichier .txt .
Mon $body est déjà \"rempli\"... donc comment faire pour spécifier mon fichier .txt ? J'ai essayé de l'ajouter à la suite, entre \"\", sans \"\", mais ça n'a pas vraiment réussi.
J'ai créé une deuxième variable, mais ça n'a pas été très concluant non plus
Connexion ou Créer un compte pour participer à la conversation.
- Philippe
- Hors Ligne
- Modérateur
-
- Messages : 1778
- Remerciements reçus 21
attention l'envoie de mail peut etre longue parfois suivant la charge du serveur !Edit (oui, encore...) : ça commence à me fatiguer
Malgré les erreurs, le mail a bien été envoyé... et je l'ai bien reçu.
normalement rien de grave, tu doit avoir des lignes vide dans ton fichier csvMa question est donc : pourquoi toutes ces erreurs ??
fais cette modif qui devrait résoudre le problème :
[code:1]$fichier | where {$_.mail -ne $null} | foreach {[/code:1]
tu peut faire çà :De plus, le texte du mail se trouve dans un fichier .txt .
Mon $body est déjà \"rempli\"... donc comment faire pour spécifier mon fichier .txt ? J'ai essayé de l'ajouter à la suite, entre \"\", sans \"\", mais ça n'a pas vraiment réussi.
J'ai créé une deuxième variable, mais ça n'a pas été très concluant non plus
[code:1]$body = \"Bonjour $($_.qualite) $($_.nom) $($_.prenom)\"
$body += Get-Content -Path c:\body.txt[/code:1]
Connexion ou Créer un compte pour participer à la conversation.
- Evea
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
- Messages : 11
- Remerciements reçus 0
attention l'envoie de mail peut etre longue parfois suivant la charge du serveur !
Effectivement, il m'est arrivé de recevoir plusieurs mails d'un coup
Bon, de ce côté, pas de soucis à me faire alors
Ce \"souci\" est réglé !
normalement rien de grave, tu doit avoir des lignes vide dans ton fichier csv
fais cette modif qui devrait résoudre le problème :
[code:1]$fichier | where {$_.mail -ne $null} | foreach {[/code:1]
Ca, en revanche, n'a pas résolu mon problème de messages d'erreur
[code:1]$body = \"Bonjour $($_.qualite) $($_.nom) $($_.prenom)
$body += Get-Content -Path c:\body.txt\"[/code:1]
En attendant ta réponse, j'avais bidouillé mon code et fait :
[code:1]-body \"$body + $body2\"[/code:1]
qui avait fonctionné
Mais ta méthode est probablement plus propre, alors je pense que je vais l'adopter
Maintenant, il ne me reste plus que deux choses à programmer... et ça non plus, ça ne va pas être chose facile : programmer l'envoi de mail par bloc de 50, avec une pause d'une seconde entre chaque bloc
J'essaye de poser un algo sur l'instruction que je dois faire, mais j'ai du mal XD
Je me demande si un truc comme ça fonctionnerait...
[code:1]for ($i = $fichier[0] ; $i -le $fichier[50]; i++) {
$fichier | where {$_.mail -ne $null} | foreach {
$body = \"Bonjour $($_.qualite) $($_.nom),`n`n\"
$body += Get-Content \"C:\Users\nom_user\Documents\programme\test.txt\"
$mailTo = $_.mail
Send-MailMessage -to \"$mailTo\" -subject \"$mailSubject\" -body \"$body\" -SmtpServer \"$serveurSMTP\" -from \"$mailFrom\" -Attachments \"$pj\"
Start-sleep -seconds 1
write-host \"PAUSE\"
}
}
[/code:1]
Edit (
En fait, je me demande vraiment comment retranscrire dans mon script :
- tant qu'il y a des des adresses mail : envoie des mails aux adresses qui vont de la ligne 0 à la ligne 49
- fait une pause d'une seconde
- tant qu'il y a des adresses : envoie des mails aux adresses qui vont de la ligne 50 à 99...
Ou alors, il faudrait que je trouve un moyen de découper le fichier csv en bloc de 50 lignes, et ensuite que je fasse une boucle... pfiou
Message édité par: Callypso, à: 12/02/15 17:52<br><br>Message édité par: Callypso, à: 12/02/15 18:04
Connexion ou Créer un compte pour participer à la conversation.
- Philippe
- Hors Ligne
- Modérateur
-
- Messages : 1778
- Remerciements reçus 21
peut tu me confirmé la présence de ligne vide dans le fichier CSVCa, en revanche, n'a pas résolu mon problème de messages d'erreur
et aussi vérifié le contenue au passage
avec les variables il faut effectivement pas mettre de guillemetsil fallait mettre les \"\"... je pensais qu'avec les variables, il ne fallait pas mettre les \"\"
maintenant que ca fonctionne peut tu faire un essai sans les guillemets et voir si tu a plus es erreurs
un sleep 1 par exemple ? dans la boucle juste après send-mailmessageEn fait, je me demande vraiment comment retranscrire dans mon script :
- tant qu'il y a des des adresses mail : envoie des mails aux adresses qui vont de la ligne 0 à la ligne 49
- fait une pause d'une seconde
- tant qu'il y a des adresses : envoie des mails aux adresses qui vont de la ligne 50 à 99...
quelque chose comme :
[code:1]
$i = 0
$fichier | where {$_.mail -ne $null} | foreach {
.
.
.
if (!($i % 5)) {
sleep 1
}
$i++
}
[/code:1]
je ne fait pas de commentaire sur ta boucleEdit ( ) : après réflexion, je ne pense pas que ma boucle for puisse fonctionner...
Connexion ou Créer un compte pour participer à la conversation.
- Evea
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
- Messages : 11
- Remerciements reçus 0
peut tu me confirmé la présence de ligne vide dans le fichier CSV
et aussi vérifié le contenue au passage
Effectivement, j'avais bien un problème de lignes vides
C'est résolu !
maintenant que ca fonctionne peut tu faire un essai sans les guillemets et voir si tu a plus es erreurs
Plus de problèmes de ce côté là aussi !
[code:1]$i = 0
$fichier | where {$_.mail -ne $null} | foreach {
.
.
.
if (!($i % 5)) {
sleep 1
}
$i++
}[/code:1]
J'ai testé et je ne suis pas sûre que cela me donne l'effet recherché, en revanche...
Je n'arrive pas à comprendre la signification de la ligne
[code:1]if (!($i % 5))[/code:1]
Ce que je constate avec le script que j'ai actuellement, c'est que son exécution est assez longue...
J'ai essayé de réfléchir à un algo (dans une forme plus ou moins conventionnelle :/ )
[code:1]POUR ($i = 0 ; $i différent de $null (= si la ligne n'est pas vide) ; $i++)
{ ENVOYER MAIL
SI (le résultat de la division $i/50 vaut 0)
{
FAIRE une pause de x secondes/minutes
AFFICHER \"pause x minutes/secondes avant le traitement du prochain bloc\"
}
}[/code:1]
Ce que j'ai retranscrit de cette manière
[code:1]for ($i = 0 ; $i -ne $null ; $i++) {
if ($i%50 -eq 0) {
start-sleep -s 120
write-host \"Pause de x avant traitement du prochain bloc\"
}
$fichier | where {$_.mail -ne $null} | foreach {
$body = \"Bonjour $($_.qualite) $($_.nom),`n`n\"
$body += Get-Content \"C:\Users\nom_user\Documents\programme\test.txt\"
$mailTo = $_.mail
Send-MailMessage -to $mailTo -subject $mailSubject -body $body -SmtpServer $serveurSMTP -from $mailFrom -Attachments $pj
}
}[/code:1]
Edit (je ne m'arrête jamais d'éditer !) : en fait, je me demande si mon histoire de % respectera ma contrainte
Puisque je veux traiter mes lignes par bloc de 50. Donc de la ligne 0 à 49 au début, puis de 50 à 99...
Avec quelque chose disant \"if ($i%50 = 0)\", c'est au bout de 51 lignes que le script s'arrêtera et affichera mon texte...
En attendant, je viens de tester ma boucle for, et y a un truc qui va pas...
J'ai, dans mon fichier, mis une adresse sur les 50 premières lignes, et une autre adresse sur les 50 suivantes. Donc, je devrais recevoir 50 mails sur la 1ère adresse, et 50 mails sur la 2ème. Or, j'ai reçu plus de 100 mails sur la 1ère adresse !
Message édité par: Callypso, à: 13/02/15 15:46
Message édité par: Callypso, à: 13/02/15 16:03
Message édité par: Callypso, à: 13/02/15 16:17
Message édité par: Callypso, à: 13/02/15 16:27<br><br>Message édité par: Callypso, à: 13/02/15 16:30
Connexion ou Créer un compte pour participer à la conversation.
- Philippe
- Hors Ligne
- Modérateur
-
- Messages : 1778
- Remerciements reçus 21
c'est la même chose que ton :Je n'arrive pas à comprendre la signification de la ligne
[code:1]if (!($i % 5))[/code:1]
[code:1]if ($i%50 -eq 0) {[/code:1]
mais moi j'ai oublié le zero de 50
ta boucle n'est pas bonne.
tu doit faire la pause dans la boucle qui liste le fichier et pas en dehors !
avec ta boucle tu envoi 50 fois les mails a tous le fichier !!!!!!x50
essai çà :
[code:1]$fichier | where {$_.mail -ne $null} | foreach {
$body = \"Bonjour $($_.qualite) $($_.nom),`n`n\"
$body += Get-Content \"C:\Users_CRLF_om_user\Documents\programme\test.txt\"
$mailTo = $_.mail
Send-MailMessage -to $mailTo -subject $mailSubject -body $body -SmtpServer $serveurSMTP -from $mailFrom -Attachments $pj
if (!($i % 50)) {
write-host \"Pause syndicale pour les serveurs !\"
write-host \"pause x minutes/secondes avant le traitement du prochain bloc\"
start-sleep -s 120
}
$i++
}
[/code:1]
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- Powershell, les tableaux et les fichiers CSV