Question Script qui sature la ram en lisant un fichier.

Plus d'informations
il y a 13 ans 6 mois #12676 par rodriguez
Bonjour a tous,
voici un script qui lit le journal d'évènement de sécurité qui met dans un fichier les event.id demandé et qui qui trie le contenu par des conditions de domaine.

La problèmatique c'est que le script sature la mémoire et plante lors de la phase du lecture du fichier.

je concois que le script est l'aborieux à lire mais je voudrais savoir comment optimiser la mise en mémoire.?

[code:1]

Remove-Item c:\systools\bat\temp\event.txt
Remove-Item c:\systools\bat\temp\login.txt
Remove-Item c:\systools\bat\temp\comptes.txt




$preevent= 00
#intervalle represente le nb de jour à examiner.. rétention du journal maxi est de 3 jours
$intervalle = 3
$logs = [System.Diagnostics.EventLog]::GetEventLogs('SMARS-NET04.***.fr')


#logs[7] représent lors du \"get-eventlog -list\" la place du security sur le serveur, ceci peut
#varier celon le serveur.
$colItems = $logs[8].entries


$Now = Get-Date
$lastWrite = $Now.AddDays(-$intervalle)

#numero des event à chercher.
$events529 = 529
$events672 = 672
$events675 = 675

foreach ($item in $colItems)
{

if (( $events529 -contains $item.EventID ) -and ($item.TimeWritten -ge $lastWrite))
{

if ($item.TimeWritten -notlike $preevent)
{
#“Serveur incriminé : ” + $item.MachineName
#”===================================================#=” >> c:\systools\bat\temp\event.txt

$preevent = “” + $item.TimeWritten
“Date de l'évènement: ” + $item.TimeWritten >> c:\systools\bat\temp\event.txt
$item.TimeGenerated

“Message: ” + $item.Message >> c:\systools\bat\temp\event.txt


}

}

if (( $events672 -contains $item.EventID ) -and ($item.TimeWritten -ge $lastWrite))
{

if ($item.TimeWritten -notlike $preevent)
{

$preevent = “” + $item.TimeWritten
“Date de l'évènement: ” + $item.TimeWritten >> c:\systools\bat\temp\event.txt



“Message: ” + $item.Message >> c:\systools\bat\temp\event.txt








}

}



if (( $events675 -contains $item.EventID ) -and ($item.TimeWritten -ge $lastWrite))
{

if ($item.TimeWritten -notlike $preevent)
{

$preevent = “” + $item.TimeWritten
“Date de l'évènement: ” + $item.TimeWritten >> c:\systools\bat\temp\event.txt
$item.TimeGenerated


“Message: ” + $item.Message >> c:\systools\bat\temp\event.txt


}

}

}







#
#Lecture du fichier Event.txt
#


$comptes = get-content c:\systools\bat\temp\event.txt
for ($i=0; $i -lt $comptes.length; $i++)
{
if (($comptes[$i] -match \" Nom de l'utilisateur : \") -or ($comptes[$i] -match \" Utilisateur : \"))
{
#récuperation du nom situé avec le terme Nom de l'utilisateur
$user = $comptes[$i].Split()[-1]



}

#if ($comptes[$i] -match \"Package d'authentification :\")
if (($comptes[$i] -match \"Domaine :\") -or ($comptes[$i] -match \"Nom du service :\") -or ($comptes[$i] -match \"Nom de domaine Kerberos fourni :\"))
{
$result = $comptes[$i].split()[-1]
# protocole definissant que les ouverture de sessions.

if (($result -eq \" ****\" ) -or ($result -eq \"krbtgt/****\" ) -or ($result -eq \"krbtgt/****\" ))
{





#Initialisation des paramètres de l'active directory
$ldapquery = [ADSI] 'LDAP://OU=Utilisateurs,DC=fr,DC=****,DC=local'
$objrechercher = New-object system.directoryservices.directorysearcher($ldapQuery)
$objrechercher.filter='(&(objectCategory=person)(objectClass=user))'



$boucle = $objrechercher.findall()


foreach ($utilisateur in $boucle)
{


#recherche du login de l'utilisateur ainsi que son nom afin de rechercher les propriétés
# de l'utilisateur dans l'AD
$login = $utilisateur.properties.samaccountname
$name = $utilisateur.properties.name

# Write-Host AD $login

if ($login -eq $user)
{

$name >> c:\systools\bat\temp\login.txt
}

}
}



}



}
#compte le nombre fois que le login apparait
get-content c:\systools\bat\temp\login.txt | group-object >> c:\systools\bat\temp\comptes.txt

[/code:1]

Merci pour votre aide.

Message édité par: noxyde, à: 12/09/12 12:44

Message édité par: noxyde, à: 12/09/12 12:47

Message édité par: noxyde, à: 13/09/12 09:43<br><br>Message édité par: noxyde, à: 13/09/12 09:46

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

Plus d'informations
il y a 13 ans 6 mois #12680 par Laurent Dardenne
Salut,
utilise les balises code, stp.
Ainsi, ton code est illisible.

Je suis toujours surpris du peu de considération que vous avez de vos lecteurs :pinch:

Tutoriels PowerShell

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

Plus d'informations
il y a 13 ans 6 mois #12683 par Laurent Dardenne
Salut,
merci pour l'usage de balises code.
Avant tout combien d'event peux-tu traiter ?

Concernant la première partie du code, factorise le en testant une seule fois la variable lastWrite
[code:1]
$Id=$item.EventID
$isTimeWritten=$item.TimeWritten -ge $lastWrite

if ( $Id -eq $events529 ) -and ($isTimeWritten))
etc...
[/code:1]
Pour la gestion des logs utilise une collection d'objet afin de la traiter en une seule fois et pas ouvrir/placer le curseur en fin de fichier/insérer la ligne/fermer le fichier, ouf !
[code:1]
$Result|Set-Content file.log
[/code:1]

Ensuite il faut optimiser partie par partie.

Pour finir, il doit y avoir d'autres points, tu pourrais utiliser des alternatives dans les expressions régulières, mais là il faut connaitre le contexte.

Une astuce, les accès indéxés peuvent être accélérés en récupérant la valeur une seule fois :
[code:1]
$Current=$comptes[$i]
#ou $Current=$Object.Inner.Comptes[$i]
if ($Current -match ' Nom de l'utilisateur : | Utilisateur : ')
[/code:1]
Tu pourrais aussi reconstruire ton code en utilisant le pipeline, puisque tu traites tjr le même objet. Mais ce sera pour la v2 ;-)

Tutoriels PowerShell

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

Plus d'informations
il y a 13 ans 6 mois #12687 par rodriguez
Merci Laurent pour ton retour,

j'ai enfait actuellement 3 event.id à surveiller.

je vais essayé d'appliquer tes morceaux de codes.

Par contre je ne me suis jamais servis de la commande

[code:1]
$Result|Set-Content file.log
[/code:1]

pour le moment je ne vois pas comment l'intégrer pour coursicuiter l'ecriture du fichiers.
de meme pour :

[code:1]
if ($Current -match ' Nom de l'utilisateur : | Utilisateur : ')
[/code:1]

je ne l'avais jamais vu.
A peaufiner, entre deux pb de prods.

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

Plus d'informations
il y a 13 ans 6 mois #12688 par SiSMik
Salut,

Si ton traitement de fichier est trop important, pourquoi en utiliser un

essayes de passer uniquement par des objets tu seras bien plus performant.

[code:1]$Start = Get-Date
$End = $Now.AddDays(-3)

$Logs = Get-EventLog -ComputerName \&quot;SMARS-NET04.***.fr\&quot; -logname `
\&quot;Security\&quot; -After $Start -before $End | where {$_.eventID -match '[529]|[672]|[675]'}

Foreach ( $Error in $Logs ) {
...
}[/code:1]

Ce code n'a pas été testé :p
Pour avoir déjà travailler avec des eventlog, ça peut prendre beaucoup de ressources, tout dépend du nombre d'erreurs dans les journaux ;)

++

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

Plus d'informations
il y a 13 ans 6 mois #12690 par Matthew BETTON
Bonjour,

Pour la performance, préférer si possible la Cmdlet 'Get-WinEvent' :

PowerShell: Get-WinEvent vs. Get-EventLog

Use PowerShell Cmdlet to Filter Event Log for Easy Parsing

... Voir avec un moteur de recherche, Internet est rempli d'articles sur ce sujet ;)

J'écris 'si possible' car comme indiqué dans l'aide :

Remarque : Get-WinEvent requiert Windows Vista, Windows Server 2008 R2 ou des versions ultérieures de Windows. De p
lus, elle requiert Microsoft .NET Framework 3.5 ou une version ultérieure.


Voir notamment les paramètres de filtres : '-FilterHashTable', '-FilterXPath' et 'FilterXML'.

[code:1]Get-Help Get-WinEvent -Parameter filter*[/code:1]

Afin de ne pas prendre de ressources sur le serveur source, enregistrer le journal des évènements dans un fichier .evt / .evtx (si sous 2003, ré importer ensuite le fichier .evt depuis un serveur 2008R2 pour ensuite l'exporter de nouveau au format .evtx... ouf ! Mais cela peut aussi se scripter ;) ).

La Cmdlet 'Get-winEvent' peut effectivement s'utiliser sur un fichier .evtx : voir paramètre '-path'.

Plus d'informations et d'exemples sur cette Cmdlet, en ligne :

technet.microsoft.com/fr-FR/library/dd367894.aspx

Ou dans la console :

[code:1]Get-Help Get-WinEvent
Get-Help Get-WinEvent -Detailled
Get-Help Get-WinEvent -Full
Get-Help Get-WinEvent -Examples
Help Get-WinEvent -Full
Get-Help Get-WinEvent -Online
[/code:1]

@ +

Matthew

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

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