Question A propos du script Get-Audit
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 68
il y a 16 ans 2 mois #5934
par Laurent Dardenne
Tutoriels PowerShell
A propos du script Get-Audit a été créé par Laurent Dardenne
Olivier, voici quelques remarques sur le script suivant :
Get-Audit.ps1
Il me semble que tu utilises Write-Output au lieu de Write-Host, je me tompe ?
Tu envisageais qu'il \"soit accessible en plusieurs \"format\" qui pour l'instant est juste \"HTML\".
Dans ce cas, il faut, à mon avis, découpler l'action d'inventaire de sa présentation, qq chose comme:
[code:1]
Get-Audit|Format-AuditHtml|Out-Html
[/code:1]
Tu peux formater le nom de fichier avec l'opérateur -F :
[code:1]
$date=get-date
$Filename = $(\".\$Target {0:HH}h{0:mm} - {0:dd}.{0:MM}.{0:yyyy}.htm\" -f $Date)
$Filename
[/code:1]
La dernière ligne provoque une exception dans le cas suivant :
[code:1]
PS Env:\> &\"G:\temp\Get_Audit\Get-Audit.ps1\"
No list specified, using xxx
...
..Installed Software
Out-File : Impossible d'ouvrir le fichier, car le fournisseur actuel (Microsoft.PowerShell.Core\Environment) ne permet
pas cette opération.
Au niveau de G:\temp\Get_Audit\Get-Audit.ps1 : 821 Caractère : 19
+ $Report | out-file <<<< -encoding UNICODE -filepath $Filename
+ CategoryInfo : InvalidArgument: (:«») [Out-File], PSInvalidOperationException
+ FullyQualifiedErrorId : ReadWriteFileNotFileSystemProvider,Microsoft.PowerShell.Commands.OutFileCommand
[/code:1]
C'est du au fait que tu références le chemin courant $FileName; sous PS la notion de chemin est différente des shells habituels.
Un PsPath référence tout type de provider pas seulement le file system :
[code:1]
cd env:
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($pwd)
# chaine vide
cd c:
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($pwd)
#chemin courant sur c:
cd env:
$ExecutionContext.SessionState.Path.CurrentProviderLocation(\"filesystem\"«»)
#chemin courant du provider filesystem
[/code:1]
Et si c'est l'utilisateur qui précise le chemin, il y aurait d'autres contrôles à faire.
J'aurais plutot vu le type du paramètre comme un tableau de string, si par exemple les noms de pc proviennent d'AD cela impose de les écrire dans un fichier pour les réimporter.
Dans une version évoluée, tu pourrais aussi utiliser le pipeline :
[code:1]
Get-Machines|Get-audit
[/code:1]
Si les ordinateurs n'existe pas ou ne sont pas connectés le script génére pas mal d'erreurs WMI :
[code:1]
Get-WmiObject : Le serveur RPC n'est pas disponible.
[/code:1]
Il serait bien d'ajouter une gestion des erreurs WMI.
Pour les codes du type suivant, tu peux utiliser un switch ou des elseif :
[code:1]
If ($objService.StartMode -eq \"Auto\"«»)
[/code:1]
Tu concaténes beaucoup de chaînes autour de la variable $Report, l'usage d'un objet StringBuilder serait préférable.
Je constate des redondance dans les chaînes de type :
[code:1]
$Report+= \" <td width='20%'><font color='#FF0000'>$($objService.State)</font></td>\"
[/code:1]
Une approche comme celle-ci peut aider à éclaircir le code :
[code:1]
function New-tdHtmlBalise($width,$Color,[string]$ObjectProperty)
{\" <td width='{0}%'><font color='#{1}'>{2}</font></td>\" -F $width,$Color,$Object $ObjectProperty
New alias td New-tdHtmlBalise
$Report+= td 20 FF0000 $objService.State
#$Report.Add( (td 20 FF0000 $objService.State) )
[/code:1]
Et enfin pour ce type de code :
[code:1]
$Report+= \" <tr>\"
$Report+= \" <td width='25%'>$($objQuickFix.HotFixID)</font></td>\"
$Report+= \" <td width='75%'>$($objQuickFix.Description)</font></td>\"
$Report+= \" </tr>\"
[/code:1]
Tu peux utiliser une here-string :
[code:1]
$Report+=@\"
<tr>
<td width='25%'>$($objQuickFix.HotFixID)</font></td>
<td width='75%'>$($objQuickFix.Description)</font></td>
</tr>
\"@
[/code:1]
C'est tout
Il me semble que tu utilises Write-Output au lieu de Write-Host, je me tompe ?
Tu envisageais qu'il \"soit accessible en plusieurs \"format\" qui pour l'instant est juste \"HTML\".
Dans ce cas, il faut, à mon avis, découpler l'action d'inventaire de sa présentation, qq chose comme:
[code:1]
Get-Audit|Format-AuditHtml|Out-Html
[/code:1]
Tu peux formater le nom de fichier avec l'opérateur -F :
[code:1]
$date=get-date
$Filename = $(\".\$Target {0:HH}h{0:mm} - {0:dd}.{0:MM}.{0:yyyy}.htm\" -f $Date)
$Filename
[/code:1]
La dernière ligne provoque une exception dans le cas suivant :
[code:1]
PS Env:\> &\"G:\temp\Get_Audit\Get-Audit.ps1\"
No list specified, using xxx
...
..Installed Software
Out-File : Impossible d'ouvrir le fichier, car le fournisseur actuel (Microsoft.PowerShell.Core\Environment) ne permet
pas cette opération.
Au niveau de G:\temp\Get_Audit\Get-Audit.ps1 : 821 Caractère : 19
+ $Report | out-file <<<< -encoding UNICODE -filepath $Filename
+ CategoryInfo : InvalidArgument: (:«») [Out-File], PSInvalidOperationException
+ FullyQualifiedErrorId : ReadWriteFileNotFileSystemProvider,Microsoft.PowerShell.Commands.OutFileCommand
[/code:1]
C'est du au fait que tu références le chemin courant $FileName; sous PS la notion de chemin est différente des shells habituels.
Un PsPath référence tout type de provider pas seulement le file system :
[code:1]
cd env:
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($pwd)
# chaine vide
cd c:
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($pwd)
#chemin courant sur c:
cd env:
$ExecutionContext.SessionState.Path.CurrentProviderLocation(\"filesystem\"«»)
#chemin courant du provider filesystem
[/code:1]
Et si c'est l'utilisateur qui précise le chemin, il y aurait d'autres contrôles à faire.
J'aurais plutot vu le type du paramètre comme un tableau de string, si par exemple les noms de pc proviennent d'AD cela impose de les écrire dans un fichier pour les réimporter.
Dans une version évoluée, tu pourrais aussi utiliser le pipeline :
[code:1]
Get-Machines|Get-audit
[/code:1]
Si les ordinateurs n'existe pas ou ne sont pas connectés le script génére pas mal d'erreurs WMI :
[code:1]
Get-WmiObject : Le serveur RPC n'est pas disponible.
[/code:1]
Il serait bien d'ajouter une gestion des erreurs WMI.
Pour les codes du type suivant, tu peux utiliser un switch ou des elseif :
[code:1]
If ($objService.StartMode -eq \"Auto\"«»)
[/code:1]
Tu concaténes beaucoup de chaînes autour de la variable $Report, l'usage d'un objet StringBuilder serait préférable.
Je constate des redondance dans les chaînes de type :
[code:1]
$Report+= \" <td width='20%'><font color='#FF0000'>$($objService.State)</font></td>\"
[/code:1]
Une approche comme celle-ci peut aider à éclaircir le code :
[code:1]
function New-tdHtmlBalise($width,$Color,[string]$ObjectProperty)
{\" <td width='{0}%'><font color='#{1}'>{2}</font></td>\" -F $width,$Color,$Object $ObjectProperty
New alias td New-tdHtmlBalise
$Report+= td 20 FF0000 $objService.State
#$Report.Add( (td 20 FF0000 $objService.State) )
[/code:1]
Et enfin pour ce type de code :
[code:1]
$Report+= \" <tr>\"
$Report+= \" <td width='25%'>$($objQuickFix.HotFixID)</font></td>\"
$Report+= \" <td width='75%'>$($objQuickFix.Description)</font></td>\"
$Report+= \" </tr>\"
[/code:1]
Tu peux utiliser une here-string :
[code:1]
$Report+=@\"
<tr>
<td width='25%'>$($objQuickFix.HotFixID)</font></td>
<td width='75%'>$($objQuickFix.Description)</font></td>
</tr>
\"@
[/code:1]
C'est tout
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Olivier
- Hors Ligne
- Membre elite
-
Réduire
Plus d'informations
- Messages : 182
- Remerciements reçus 0
il y a 16 ans 2 mois #5936
par Olivier
Réponse de Olivier sur le sujet Re:A propos du script Get-Audit
salut Laurent !!
waouww t'a déjà tout digéré mon script ...
et en plus avec plein de proposition d'améliorations !
Merci infiniment pour cette analyse !!
Actuellement, suis sur un autre projet mais sitôt terminé, je vais remettre en place un AD et quelques stations pour suivre tes suggestion et tester dans un environnement Server 2008 R2 avec AD et tout ...
L'idée de pouvoir restituer le résultat dans un autre format reste une idée et n'était pas l'objtectif lors de mon travail sur ce script. Le principal but était de pouvoir mettre en pratique avec un cas concret un script PowerShell.
Il est bien entendu que y reste pas mal d'améliorations à faire
Merci encore pour tout !
À très bientôt
Olivier
waouww t'a déjà tout digéré mon script ...
Merci infiniment pour cette analyse !!
Actuellement, suis sur un autre projet mais sitôt terminé, je vais remettre en place un AD et quelques stations pour suivre tes suggestion et tester dans un environnement Server 2008 R2 avec AD et tout ...
L'idée de pouvoir restituer le résultat dans un autre format reste une idée et n'était pas l'objtectif lors de mon travail sur ce script. Le principal but était de pouvoir mettre en pratique avec un cas concret un script PowerShell.
Il est bien entendu que y reste pas mal d'améliorations à faire
Merci encore pour tout !
À très bientôt
Olivier
Connexion ou Créer un compte pour participer à la conversation.
- Arnaud Petitjean
-
- Hors Ligne
- Modérateur
-
il y a 16 ans 2 mois #5949
par Arnaud Petitjean
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 ?
Réponse de Arnaud Petitjean sur le sujet Re:A propos du script Get-Audit
Salut,
Je n'ai pas encore eu le temps de regarder le code, j'ai juste testé le script...
Les suggestions d'amélioration que je propopose sont les suivantes :
1. Mettre la feuille de style dans un fichier CSS externe
2. Pouvoir exporter le résultat sous Word et/ou sous Excel
3. Effectivement comme le propose Laurent, faire un test si la machine distante est joignable (Test-Connection) avant de tenter l'execution du script.
Arnaud
Je n'ai pas encore eu le temps de regarder le code, j'ai juste testé le script...
Les suggestions d'amélioration que je propopose sont les suivantes :
1. Mettre la feuille de style dans un fichier CSS externe
2. Pouvoir exporter le résultat sous Word et/ou sous Excel
3. Effectivement comme le propose Laurent, faire un test si la machine distante est joignable (Test-Connection) avant de tenter l'execution du script.
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.
- Olivier
- Hors Ligne
- Membre elite
-
Réduire
Plus d'informations
- Messages : 182
- Remerciements reçus 0
il y a 16 ans 2 mois #5967
par Olivier
Réponse de Olivier sur le sujet Re:A propos du script Get-Audit
Bonjour à tous !
Pour tester la présence des stations ou serveurs à partir d'un fichier texte, j'ai ce code :
[code:1]$PingMachines = Get-Content \"D:\Windows\PowerShell\Scripts\Working.txt\"
if ({Test-Path D:\Windows\PowerShell\Scripts\Working.txt} -eq \"true\")
{Clear-Content D:\Windows\PowerShell\Scripts\Result.txt}
ForEach($MachineName In $PingMachines)
{$PingStatus = Gwmi Win32_PingStatus -Filter \"Address = '$MachineName'\" | Select-Object StatusCode
If ($PingStatus.StatusCode -eq 0)
{$MachineName | Out-File -Append D:\Windows\PowerShell\Scripts\Result.txt}
}[/code:1]
En plus, j'ai fais en sorte que ça me crée le fichier qui sera utilisé pour le script d'audit ...
Je ferai un \"préselction\" pour que le script puisse aussi s'utiliser sans paramètres donc, sur la machine locale ...
Maintenant, je voudrais limiter le nombre de requêtes d'echo à 1 car pour un grand nombre de stations non connectée, le script prendra des plombes ...
Avec le code en version Test-Connection, j'ai des souci pour gérer les erreur pour les stations qui ne sont pas branchées ... et en plus, le paramètre -count ne fonctionne pas, ça met des plombes pour me dire que pas de PC (Serveur rpc non dispo ...)
Si quelqu'un peut me mettre sur une piste ...
Autrement, pour le reste, ça avance très gentiment
Merci d'avance et à +
Olivier<br><br>Message édité par: Olivier, à: 18/01/10 03:12
Pour tester la présence des stations ou serveurs à partir d'un fichier texte, j'ai ce code :
[code:1]$PingMachines = Get-Content \"D:\Windows\PowerShell\Scripts\Working.txt\"
if ({Test-Path D:\Windows\PowerShell\Scripts\Working.txt} -eq \"true\")
{Clear-Content D:\Windows\PowerShell\Scripts\Result.txt}
ForEach($MachineName In $PingMachines)
{$PingStatus = Gwmi Win32_PingStatus -Filter \"Address = '$MachineName'\" | Select-Object StatusCode
If ($PingStatus.StatusCode -eq 0)
{$MachineName | Out-File -Append D:\Windows\PowerShell\Scripts\Result.txt}
}[/code:1]
En plus, j'ai fais en sorte que ça me crée le fichier qui sera utilisé pour le script d'audit ...
Je ferai un \"préselction\" pour que le script puisse aussi s'utiliser sans paramètres donc, sur la machine locale ...
Maintenant, je voudrais limiter le nombre de requêtes d'echo à 1 car pour un grand nombre de stations non connectée, le script prendra des plombes ...
Avec le code en version Test-Connection, j'ai des souci pour gérer les erreur pour les stations qui ne sont pas branchées ... et en plus, le paramètre -count ne fonctionne pas, ça met des plombes pour me dire que pas de PC (Serveur rpc non dispo ...)
Si quelqu'un peut me mettre sur une piste ...
Autrement, pour le reste, ça avance très gentiment
Merci d'avance et à +
Olivier<br><br>Message édité par: Olivier, à: 18/01/10 03:12
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 68
il y a 16 ans 2 mois #5968
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:A propos du script Get-Audit
Salut,
tu peux consulter ce post
powershell-scripting.com/index.php?optio...=749&catid=5#749
Sinon pour ce type de test
[code:1]({Test-Path D:\Windows\PowerShell\Scripts\Working.txt} -eq \"true\"«»)[/code:1]
Il n'est pas nécessaire d'utiliser un scriptblock, des parenthèses suffisent :
[code:1]
((Test-Path D:\Windows\PowerShell\Scripts\Working.txt))[/code:1]
Par défaut Test-Path renvoi $True si le test réussi.
On utilise -eq $true dans certains cas pour préciser/documenter le code, mais ici c'est redondant.
tu peux consulter ce post
powershell-scripting.com/index.php?optio...=749&catid=5#749
Sinon pour ce type de test
[code:1]({Test-Path D:\Windows\PowerShell\Scripts\Working.txt} -eq \"true\"«»)[/code:1]
Il n'est pas nécessaire d'utiliser un scriptblock, des parenthèses suffisent :
[code:1]
((Test-Path D:\Windows\PowerShell\Scripts\Working.txt))[/code:1]
Par défaut Test-Path renvoi $True si le test réussi.
On utilise -eq $true dans certains cas pour préciser/documenter le code, mais ici c'est redondant.
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Olivier
- Hors Ligne
- Membre elite
-
Réduire
Plus d'informations
- Messages : 182
- Remerciements reçus 0
il y a 16 ans 2 mois #5972
par Olivier
Réponse de Olivier sur le sujet Re:A propos du script Get-Audit
Merci bien pour tes conseils !
Voilà à quoi ressemble mon script :
[code:1]$PingMachines = Get-Content \"D:\Windows\PowerShell\Scripts\Working.txt\"
if (Test-Path D:\Windows\PowerShell\Scripts\Result.txt)
{Clear-Content D:\Windows\PowerShell\Scripts\Result.txt}
ForEach($MachineName In $PingMachines)
{$PingStatus = Test-Connection $MachineName -ErrorAction \"SilentlyContinue\" -count 1 | Select-Object statuscode
If ($PingStatus.StatusCode -eq 0)
{$MachineName + \" OK\" | Out-File -Append D:\Windows\PowerShell\Scripts\Result.txt}
else
{$MachineName + \" KO\" | Out-File -Append D:\Windows\PowerShell\Scripts\Result.txt}
}[/code:1]
Maintenant, faut que je trouve une astuce pour isoler le nom des stations qui se trouve pas en ligne ... Je vais chercher et si besoin, je reviens demander de prestigieux conseils ici
À +
Olivier
Voilà à quoi ressemble mon script :
[code:1]$PingMachines = Get-Content \"D:\Windows\PowerShell\Scripts\Working.txt\"
if (Test-Path D:\Windows\PowerShell\Scripts\Result.txt)
{Clear-Content D:\Windows\PowerShell\Scripts\Result.txt}
ForEach($MachineName In $PingMachines)
{$PingStatus = Test-Connection $MachineName -ErrorAction \"SilentlyContinue\" -count 1 | Select-Object statuscode
If ($PingStatus.StatusCode -eq 0)
{$MachineName + \" OK\" | Out-File -Append D:\Windows\PowerShell\Scripts\Result.txt}
else
{$MachineName + \" KO\" | Out-File -Append D:\Windows\PowerShell\Scripts\Result.txt}
}[/code:1]
Maintenant, faut que je trouve une astuce pour isoler le nom des stations qui se trouve pas en ligne ... Je vais chercher et si besoin, je reviens demander de prestigieux conseils ici
À +
Olivier
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.058 secondes
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Contributions à la communauté
- A propos du script Get-Audit