Question [Résolu] Optimisation et gestion des erreurs

Plus d'informations
il y a 15 ans 9 mois #7204 par sebastien
Bonjour à tous,

Débutant en PS, je suis en train de réaliser mon premier script PS. Cependant, je me heurte à certains problèmes que je n'arrive pas à résoudre. Je viens donc prendre conseil auprès de pro.

Le script que je dois réaliser doit effectuer les taches suivantes sur 3 serveurs à 10 minutes d'intervalle:

> Copie d'un fichier depuis le serveur principal vers un serveur secondaire SI le fichier est différent.
> Redémarrage d'un service sur le serveur secondaire.
> Envoie d'un mail si problème ( fichier non copié en cas de différence ou démarrage du service impossible).

Voici le code, mes questions se trouveront à la fin ;) (je sais que le code doit être mauvais, mais comme je le répète, je débute. Merci de votre indulgence) :

[code:1]function Sendmail
{param ($problem)
$expediteur = \"xxx@xxx.com\"
$destinataire = \"xxx@xxx.com\"
$serveur = \"x.x.x.x\"
$objet = \"LSRESERV UPDATE PROBLEM\"
$texte = $problem
$message = new-object System.Net.Mail.MailMessage $expediteur, $destinataire, $objet, $texte
$client = new-object System.Net.Mail.SmtpClient $serveur
$client.Credentials = [System.Net.CredentialCache]::«»DefaultNetworkCredentials
$client.Send($message)
}
function restart_service
{param ($server)
if (!(Get-WmiObject -computer $server Win32_Service -Filter \"Name='Themes'\"«»).InvokeMethod(\"StopService\",$null) -eq 0)
{add-content $logfile \"$Tdate`:Failed to stop service on $server\"}
else
{add-content $logfile \"$Tdate`:«»Service stopped on $server\"}
if (!(Get-WmiObject -computer $server Win32_Service -Filter \"Name='Themexs'\"«»).InvokeMethod(\"StartService\",$null) -eq 0)
{add-content $logfile \"$Tdate`:Failed to start service on $server\";$needmail=1;$problem=$problem + \"Service not started on $server\"}
else
{add-content $logfile \"$Tdate`:«»Service started on $server\"}
}

###################-Declaration-###################
$needmail=0
$servers=@(\"serv2\",\"serv1\",\"serv3\"«»)
$YMDdate=get-date -uformat \"%Y_%m_%d\"
$lsreserv_source = \"C:\aspentech\resa\lsreserv\"
$logfile=\"C:\aspentech\resa\logs\Duplication_log_\"+$YMDdate+\".txt\"
\"==============================\" | add-content $logfile
get-date | add-content $logfile
$Tdate=get-date -uformat \"%T\"
add-content $logfile \"$Tdate`:«»Starting Script\"

###################-Main-###################
#Check if lsreserv exists
if(!(test-path -path $lsreserv_source -pathtype leaf))
{
add-content $logfile \"$Tdate`:lsreserv not found !`r$Tdate`:EXITING.\"
exit
}
else
{
$lsreserv_source=Get-Item $lsreserv_source
add-content $logfile \"$Tdate`:$lsreserv_source found!\"
}
#Copying file & restarting service
foreach ($server in $servers)
{
add-content $logfile \"$Tdate`:$server!\"
$lsreserv_destination=\"\\\"+$server+\"\resa\lsreserv\"
if(!(test-path -path $lsreserv_destination -pathtype leaf))
{
if ($lsreserv_source.CopyTo($lsreserv_destination, $true))
{add-content $logfile \"$Tdate`:$lsreserv_destination not found, copying\";restart_service $server}
else
{$needmail=1;$problem=$problem+\"Error copying file to server $server\";add-content $logfile \"$Tdate`:Error copying file on $server\"}
}
else
{
$lsreserv_destination=Get-item $lsreserv_destination
if (($lsreserv_source.LastWriteTime.CompareTo($lsreserv_destination.LastWriteTime) -eq 0) -and ($lsreserv_source.Length.CompareTo($lsreserv_destination.Length) -eq 0))
{
add-content $logfile \"$Tdate`:Files are the same, skipping.\"
}
else
{
if ($lsreserv_source.CopyTo($lsreserv_destination, $true))
{add-content $logfile \"$Tdate`:File are different, replacing.\" ; restart_service $server}
else
{$needmail=1;$problem=$problem+\"Error copying file to server $server\";add-content $logfile \"$Tdate`:Error copying file on $server\"}}
}
If ($needmail -eq 1)
{sendmail($problem)}
$needmail=0
Start-Sleep -s 600
}
add-content $logfile \"$Tdate`:Exiting\"[/code:1]


1) Le code retour de :
[code:1]if (!(Get-WmiObject -computer $server Win32_Service -Filter \"Name='Themexs'\"«»).InvokeMethod(\"StartService\",$null) -eq 0)[/code:1]
Si le service redémarre, le code retour est 0
Mais, si comme dans l'exemple ci-dessus, j'appelle un service qui n'existe pas, il y a un message d'erreur mais le code retour est toujours 0.
Le message d'erreur est le suivant : You cannot call a method on a null-valued expression.
Aucun log d'erreur ne se font

2) La syntaxe de cette ligne est, je pense, fausse :
[code:1]{add-content $logfile \"$Tdate`:Failed to start service on $server\";$needmail=1;$problem=$problem + \"Service not started on $server\"}[/code:1]

Quel est la bonne syntaxe ?

3) comment loguer le résultat de l'envoie du mail dans le fichier de log ?

Merci à ceux qui prendrons le temps de me lire et de m'éclairer sur le chemin long et sinueux du PS scripting.

@+
Sebastien

Message édité par: sebasti1, à: 21/06/10 12:32<br><br>Message édité par: Arnaud, à: 25/06/10 14:39

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 15 ans 9 mois #7206 par Laurent Dardenne
Salut,
sebasti1 écrit:

Mais, si comme dans l'exemple ci-dessus, j'appelle un service qui n'existe pas, il y a un message d'erreur mais le code retour est toujours 0.

Dans ce cas le mieux est de décomposer les appels, ainsi tu peux tester si le service existe.
sebasti1 écrit:

Aucun log d'erreur ne se font

Oui il y a une exception pour le bloc if else, c'est une des difficultés du dynamisme.
sebasti1 écrit:

2) ...

Quel est la bonne syntaxe ?

Quel est le pb et quel est le résultat attendu ?

sebasti1 écrit:

3) comment loguer le résultat de l'envoie du mail dans le fichier de log ?

Déjà lire la doc de la méthode Send .
Tu peux insérer ton appel à SendMail dans un bloc de gestion d'exception (trap en v1 try/catch en v2).

Sinon il y a un soucis dans la forme d'appel :
[code:1]{sendmail $problem}[/code:1]
Les fonctions PS ne nécessitent pas de parenthéses, les autres oui( dotnet, PSscriptMethod, méthod WMI).

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 15 ans 9 mois #7209 par sebastien
Merci de ces réponses, je vais creuser dans les directions données :)

J'essayerais d'être un peu plus clair aussi la prochaine fois car je me rend compte que c'était fouillis ce que j'ai posté.

Merci !

Sébastien

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 15 ans 9 mois #7221 par sebastien
Bonjour à tous,

Après avoir creusé dans les directions proposées, j'ai bien avancé puisque le script est maintenant opérationnel. Je n'ai cependant pas encore testé la partie d'envoie de mail mais elle devrait fonctionner sans probleme. J'ai entierement repris la partie de gestion des services a distance, la méthode fournie par Microsoft générée des erreurs à cause de l'utililsation de $null. Vous pouvez retrouver la méthode microsoft ici blogs.technet.com/b/heyscriptingguy/arch...remote-computer.aspx . Je ne retrouve malheureusement plus le site sur lequel je me suis appuyé pour modifier la gestion des services. Je poste le code entier pour ceux qui auraient les meme problemes que moi et qui voudraient s'en insiprer. Je l'ai commenté pour un peu plus de clarté. Pour ce qui est des try/catch, je n'ai pas le temps de me pencher sur la question, la mise en prod du script étant assez urgente.

Voici le code :

[code:1]function Sendmail
{param ($problem)
$expediteur = \&quot;xxxxx@xxxx.com\&quot;
$destinataire = \&quot;xxxxx@xxxx.com\&quot;
$serveur = \&quot;xx.xx.xx.xx\&quot;
$objet = \&quot;LSRESERV UPDATE PROBLEM\&quot;
$texte = $problem
$message = new-object System.Net.Mail.MailMessage $expediteur, $destinataire, $objet, $texte
$client = new-object System.Net.Mail.SmtpClient $serveur
$client.Credentials = [System.Net.CredentialCache]::«»DefaultNetworkCredentials
$client.Send($message)
}

function restart_service
{param ($server)
$x=get-wmiobject win32_service -ComputerName $server | where-object { $_.name -match \&quot;Sentinel RMS License Manager\&quot;}
If ($x -eq $null){
#Service not found
$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:«»Service Sentinel RMS License Manager not found on $server, can't restart\&quot;
$needmail=1
$problem=$problem+ \&quot;$Tdate`:«»Service Sentinel RMS License Manager not found on $server, can't restart\&quot;}
else
#service found
{ if ($x.Started -eq $true)
#Service is Running
{$x.stopservice()}
else
#Service is Stopped
{$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:«»Service Sentinel RMS License Manager already down on $server\&quot;}
Start-Sleep -s 10
#Reloading service state
$x=get-wmiobject win32_service -ComputerName $server | where-object { $_.name -match \&quot;Sentinel RMS License Manager\&quot;}
if ($x.Started -eq $true)
#Service is Running even if it should be down by now
{$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:«»Service Sentinel RMS License Manager can't be downed on $server\&quot;
$needmail=1
$problem=$problem+ \&quot;$Tdate`:«»Service Sentinel RMS License Manager can't be downed on $server\&quot;}
else
#Service is down and ready to be started
{$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:«»Service Sentinel RMS License Manager Stopped!\&quot;
$x.StartService()
#Reloading service state
$x=get-wmiobject win32_service -ComputerName $server | where-object { $_.name -match \&quot;Sentinel RMS License Manager\&quot;}
if ($x.Started -eq $true)
#Service has restarted
{$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:«»Service Sentinel RMS License Manager Started!\&quot;}
else
#Service has not restarted
{$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:«»Service Sentinel RMS License Manager NOT Started!\&quot;
$problem=$problem+ \&quot;$Tdate`:«»Service Sentinel RMS License Manager can't be started on $server\&quot;}
}
}
}

###################-Declaration-###################
$needmail=0
$servers=@(\&quot;serv1\&quot;,\&quot;serv2\&quot;,\&quot;serv3\&quot;,\&quot;serv4\&quot;,\&quot;serv5\&quot;«»)
$YMDdate=get-date -uformat \&quot;%Y_%m_%d\&quot;
$lsreserv_source = \&quot;C:\aspentech\resa\lsreserv\&quot;
$logfile=\&quot;C:\aspentech\resa\logs\Duplication_log_\&quot;+$YMDdate+\&quot;.txt\&quot;
\&quot;==============================\&quot; | add-content $logfile
get-date | add-content $logfile
$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:«»Starting Script\&quot;

###################-Main-###################
#Check if lsreserv exists
if(!(test-path -path $lsreserv_source -pathtype leaf))
{$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:lsreserv not found !`r$Tdate`:EXITING.\&quot;
exit}
else
{$lsreserv_source=Get-Item $lsreserv_source
$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:$lsreserv_source found!\&quot;}
#Copying file &amp; restarting service
foreach ($server in $servers)
{$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:$server!\&quot;
$lsreserv_destination=\&quot;\\\&quot;+$server+\&quot;\resa\lsreserv\&quot;
if(!(test-path -path $lsreserv_destination -pathtype leaf))
{
if ($lsreserv_source.CopyTo($lsreserv_destination, $true))
{$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:$lsreserv_destination not found, copying\&quot;;restart_service $server}
else
{$needmail=1;$problem=$problem+\&quot;Error copying file to server $server\&quot;;$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:Error copying file on $server\&quot;}
}
else
{
$lsreserv_destination=Get-item $lsreserv_destination
if (($lsreserv_source.LastWriteTime.CompareTo($lsreserv_destination.LastWriteTime) -eq 0) -and ($lsreserv_source.Length.CompareTo($lsreserv_destination.Length) -eq 0))
{
$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:Files are the same, skipping.\&quot;
}
else
{
if ($lsreserv_source.CopyTo($lsreserv_destination, $true))
{$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:File are different, replacing.\&quot; ; restart_service $server}
else
{$needmail=1;$problem=$problem+\&quot;Error copying file to server $server\&quot;;$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:Error copying file on $server\&quot;}}
}
If ($needmail -eq 1)
{sendmail $problem}
$needmail=0
Start-Sleep -s 6
}
$Tdate=get-date -uformat \&quot;%T\&quot; ; add-content $logfile \&quot;$Tdate`:Exiting\&quot;[/code:1]

Merci de l'aide apportée !
@ +

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 15 ans 9 mois #7240 par sebastien
Je trouvais que la partie gestion des services était un peu ... lourde. Après réflexion ceci semble bcp mieux :

[code:1]function restart_service
{param ($service,$server)
$x=get-wmiobject win32_service -ComputerName $server | where-object { $_.name -match $service}
if ($x -eq $null) {echo \&quot;Service not found\&quot;;return}
Elseif ($x.StopService().ReturnValue -eq 0){Echo \&quot;service stopped successfully\&quot;}
Else {$state1=$x.state;Echo \&quot;Service can't be downed. Current status is $state1\&quot;}
if ($x.StartService().ReturnValue -eq 0){Echo \&quot;service started successfully\&quot;}
Else {$state2=$x.state;Echo \&quot;Service can't be started. Current status is $state2\&quot;}
}[/code:1]

Message édité par: sebasti1, à: 23/06/10 15:22<br><br>Message édité par: sebasti1, à: 23/06/10 15:29

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 15 ans 8 mois #7258 par Arnaud Petitjean
Bonjour,

Juste 2 remarques :
1. Pour l'envoi de mail, il existe depuis PowerShell v2 la commande Send-MailMessage, vraiment très pratique.
2. Je te recommande dans un script d'éviter l'utilisation des alias (Echo -&gt; Write-OutPut). C'est une bonne pratique.

Si tu ne sais pas quelle commande native se cache derrière un alias, utilise Get-Alias.

Exemple :

[code:1]PS &gt; get-alias echo

CommandType Name Definition
----
Alias echo Write-Output[/code:1]

Arnaud

MVP PowerShell et créateur de ce magnifique forum :-)
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.050 secondes
Propulsé par Kunena