2017-05-21 3 views
0

Ceci est mon script pour obtenir le journal des événements d'une heure spécifique.Un délai se produit lorsque je lance le script

$time = Get-WinEvent microsoft-windows-dns-client/operational -MaxEvents 1 | 
Select-Object @{name="time"; expression={$_.timecreated.tostring("yyyy-MM-dd hh:mm:ss")}} | 
Select-Object -ExpandProperty time 

Get-WinEvent microsoft-windows-dns-client/operational | 
Where-Object {$_.timecreated.tostring("yyyy-MM-dd hh:mm:ss") -eq "$time"} 

Si j'exécute le script, affiche les résultats.

Le script se ferme au bout de 60 secondes ou plus.

Quelle est mon erreur?

enter image description here

[deuxième question]

Est-ce bug Powershell?

Cette situation est que le script ne se ferme pas après l'affichage des résultats.

enter image description here

3 secondes sont nécessaires pour ce résultat de l'image ci-dessous.

enter image description here

Pourquoi si lent?

Est-ce que PowerShell a un bug sur l'état du temps?

Je pense avoir résolu ce problème. Merci à gms0ulman.

while($true) { 

    $QUERY = @" 
    <QueryList><Query><Select Path='Microsoft-Windows-DNS-Client/Operational'> 
     *[System/EventID = 3006] and 
     *[System/TimeCreated[timediff(@SystemTime) &lt;= 60000]] and 
     *[EventData/Data[@Name='QueryType'] != 28] 
    </Select></Query></QueryList> 
"@ 

    $CMD = (Get-WinEvent -FilterXml $QUERY).count 2>$null 

    if($CMD -ne 0) { 
     $LOG_LIST = Get-WinEvent -FilterXml $QUERY | Select-Object timecreated, processid, message | Sort-Object timecreated 

     foreach($LOG in $LOG_LIST) { 
      $TIMESTAMP = $LOG | Select-Object -ExpandProperty timecreated 
      $TIMESTAMP_SPLIT = $TIMESTAMP -split " " 
      $LOG_DATE = $TIMESTAMP_SPLIT[0] 
      $LOG_TIME = $TIMESTAMP_SPLIT[1] 
      $PROC_ID = $LOG | Select-Object -ExpandProperty processid 
      $PROC_NAME = Get-Process -id $PROC_ID | Select-Object -ExpandProperty processname 
      $MSG = $LOG | Select-Object -ExpandProperty message 
      $URL_1 = $MSG -replace '^\S{2}\s([^,]+).+','$1' 
      $URL_2 = $URL_1 -replace '^.*?([^.]+\.[^.]+\.?|[^.]+\.(ac|co|go|ne|nm|or|pe|re)\.[^.]+\.?)$','$1' 
      $LOG_SET = "$LOG_DATE`t$LOG_TIME`t$PROC_ID`t$PROC_NAME`t$URL_1`t$URL_2" 
      $LOG_SET >> C:\dns.csv 
      } 
     } 

    Start-Sleep 60 
    } 
+0

Considérez la commande suivante: '1..1e9 |? {$ _- lt10}'. Est-ce que vous vous attendez à ce qu'il revienne immédiatement à l'impression «9», car aucun autre numéro ne peut correspondre à la condition? Ou devrait-il traiter et rejeter tous les autres numéros, ce qui prendra du temps? – PetSerAl

+0

@PetSerAl Mon script affiche tous les résultats, mais ne sort pas immédiatement. Je veux quitter le script immédiatement après avoir affiché les résultats. –

+0

Mais, comment savez-vous que le script affiche déjà *** tous *** les résultats? Plus important encore, comment le script peut-il le savoir? – PetSerAl

Répondre

1

Je ne pense pas que la variable $time contient ce que vous attendez. Sur ma machine, les critères de sélection microsoft-windows-dns-client/operational ne sont pas valides.

Je crois que c'est ce que vous êtes après:

# Get event based on your criteria. Implicitly converted to datetime data type 
# You can check by running $time.GetType() or $time | gm 
[datetime]$time = (Get-WinEvent microsoft-windows-dns-client/operational -MaxEvents 1).TimeCreated 

# Get events where the TimeCreated field matches the previous time. 
Get-WinEvent microsoft-windows-dns-client/operational | Where-Object {$_.TimeCreated -eq "$time"} 

Edit - je me trompais, ce n'est pas ce que vous êtes après

Dans un premier temps, j'ai essayé de limiter les EventLogs à ceux au dernier jour. Puis la dernière minute. Mais j'ai toujours le décalage que vous mentionnez.

Pour moi, la solution était d'utiliser le paramètre -FilterXML comme décrit dans this article. Bien sûr, il faudra personnaliser les événements PowerShell pour qu'ils correspondent à vos besoins.

# xml source: https://blogs.msdn.microsoft.com/powershell/2011/04/14/using-get-winevent-filterxml-to-process-windows-events/ 
[xml]$filterXml = @" 
<QueryList> 
    <Query Id="0" Path="Windows PowerShell"> 
    <Select Path="Windows PowerShell">*[System[(Level=4 or Level=0)]]</Select> 
    </Query> 
</QueryList> 
"@ 

[datetime]$time = (Get-WinEvent -FilterXml $filterXml -MaxEvents 1).TimeCreated 

Get-WinEvent -FilterXml $filterXml | Where-Object {$_.TimeCreated -eq $time} 
+0

Powershell peut accéder au journal des événements uniquement enregistré dans le registre (HKLM \ SYSTEM \ CurrentControlSet \ Services \ EventLog). Et votre script affiche l'invite de commande en cours uniquement. Vous pouvez essayer un autre nom de journal d'événements comme système. merci :) –

+0

@ Mr.kang Merci - au départ, j'ai laissé le LogName particulier non spécifié, donc il vient d'obtenir la dernière entrée.Coulée explicite '$ time' à' [datetime] '= cela fonctionne dans ISE. En ce qui concerne la lenteur, s'il vous plaît voir la réponse mise à jour en utilisant '-FilterXML' – gms0ulman

+0

Merci. Et j'ai mis à jour ma question. –