Windows_PowerShell_iconscenariusz

rozjechały się skrzynki na exchange. trzeba posprawdzać bazy oraz zreperować, co się da, z podglądem tego, co się dzieje w danym momencie.

podstawa

do weryfikacji i naprawy mailboxów online służy New-MailboxRepairRequest. problem polega na tym, że to polecenie nie generuje logu tylko wrzuca informacje do eventvwr. ta zmiana jest określana miałem ‘alleluja, teraz jest zajebiście’ ale przeglądanie eventvwr, zwłaszcza na żywym systemie nie jest przyjemna – ani nie wiadomo kiedy co się kończy, co zaczyna, zdarzeń jest od groma, żądanie zrobione z linii poleceń, a weryfikacja w taki sposób… no generalnie słabe.

cel

byłoby fajnie móc mieć podgląd life na konsoli tego, jak przebiegają testy. zwłaszcza, jeśli chcemy co jakiś czas zapuścić weryfikację kolejnej ‘podejrzanej’ skrzynki.

rozwiązanie

znalazłem w netcie kilka lamerskich skryptów, do podglądu eventvwr na żywo (-> keyword ‘tail eventvwr’). czemu lamerskich? ponieważ działają na zasadzie nieskończonej pętli while($true) co już samo w sobie jest bolesne. w tej pętli co 1 sek pobierane jest ostatnie zdarzenie z logu aplikacji. czyli jeśli system jest na prawdę dociążony (a exchange potrafi taki być), może się okazać, że nie zobaczymy tego, na co czekamy. krótko mówiąc – DA SIĘ LEPIEJ (:

rozwiązaniem jest zastawienie pułapki – to nie my pytamy się logu o ostatni event, tylko niech log nam powie, że takowy się pojawił. kwestie wydajności pomijam bo nie badałem – na pewno trzeba pamiętać o wyrejestrowaniu pułapki, żeby nie dociążać systemu. mechanizmem, który to realizuje jest ‘register-ObjectEvent‘, który rejestruje pułapkę na przechwycenie zdarzenia dla obiektów .NET.

oczywiście nie każde polecenie zdarzenia generuje /: aby to sprawdzić, wystarczy zwykły get-member. sprawdźmy dla get-eventlog:

[PS] C:\Windows\system32>Get-EventLog -LogName application -Newest 1 |gm


   TypeName: System.Diagnostics.EventLogEntry#application/MSExchange ADAccess/1074006048

Name                      MemberType     Definition
----                      ----------     ----------
Disposed                  Event          System.EventHandler Disposed(System.Object, System.EventArgs)
CreateObjRef              Method         System.Runtime.Remoting.ObjRef CreateObjRef(type requestedTyp
Dispose                   Method         System.Void Dispose()
Equals                    Method         bool Equals(System.Diagnostics.EventLogEntry otherEntry), boo
GetHashCode               Method         int GetHashCode()
GetLifetimeService        Method         System.Object GetLifetimeService()
GetType                   Method         type GetType()
InitializeLifetimeService Method         System.Object InitializeLifetimeService()
ToString                  Method         string ToString()
Category                  Property       System.String Category {get;}
CategoryNumber            Property       System.Int16 CategoryNumber {get;}
Container                 Property       System.ComponentModel.IContainer Container {get;}
Data                      Property       System.Byte[] Data {get;}
EntryType                 Property       System.Diagnostics.EventLogEntryType EntryType {get;}
Index                     Property       System.Int32 Index {get;}
InstanceId                Property       System.Int64 InstanceId {get;}
MachineName               Property       System.String MachineName {get;}
Message                   Property       System.String Message {get;}
ReplacementStrings        Property       System.String[] ReplacementStrings {get;}
Site                      Property       System.ComponentModel.ISite Site {get;set;}
Source                    Property       System.String Source {get;}
TimeGenerated             Property       System.DateTime TimeGenerated {get;}
TimeWritten               Property       System.DateTime TimeWritten {get;}
UserName                  Property       System.String UserName {get;}
EventID                   ScriptProperty System.Object EventID {get=$this.get_EventID() -band 0xFFFF;}

no i słabo – niby jest ‘disposed’ ale to nic nie daje. a to dla tego, że obiektem, który jest zwrócony, jest konkretny ‘event’. jest jednak wywołanie polecenia, które ‘podłącza się’ do eventlogu a nie do jego zawartości:

[PS] C:\Windows\system32>get-eventlog -List|gm


   TypeName: System.Diagnostics.EventLog

Name                      MemberType Definition
----                      ---------- ----------
Disposed                  Event      System.EventHandler Disposed(System.Object, System.EventArgs)
EntryWritten              Event      System.Diagnostics.EntryWrittenEventHandler EntryWritten(System.Object, System....
BeginInit                 Method     System.Void BeginInit()
Clear                     Method     System.Void Clear()
Close                     Method     System.Void Close()
CreateObjRef              Method     System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
Dispose                   Method     System.Void Dispose()
EndInit                   Method     System.Void EndInit()
Equals                    Method     bool Equals(System.Object obj)
GetHashCode               Method     int GetHashCode()
GetLifetimeService        Method     System.Object GetLifetimeService()
GetType                   Method     type GetType()
InitializeLifetimeService Method     System.Object InitializeLifetimeService()
ModifyOverflowPolicy      Method     System.Void ModifyOverflowPolicy(System.Diagnostics.OverflowAction action, int ...
RegisterDisplayName       Method     System.Void RegisterDisplayName(string resourceFile, long resourceId)
ToString                  Method     string ToString()
WriteEntry                Method     System.Void WriteEntry(string message), System.Void WriteEntry(string message, ...
WriteEvent                Method     System.Void WriteEvent(System.Diagnostics.EventInstance instance, Params System...
Container                 Property   System.ComponentModel.IContainer Container {get;}
EnableRaisingEvents       Property   System.Boolean EnableRaisingEvents {get;set;}
Entries                   Property   System.Diagnostics.EventLogEntryCollection Entries {get;}
Log                       Property   System.String Log {get;set;}
LogDisplayName            Property   System.String LogDisplayName {get;}
MachineName               Property   System.String MachineName {get;set;}
MaximumKilobytes          Property   System.Int64 MaximumKilobytes {get;set;}
MinimumRetentionDays      Property   System.Int32 MinimumRetentionDays {get;}
OverflowAction            Property   System.Diagnostics.OverflowAction OverflowAction {get;}
Site                      Property   System.ComponentModel.ISite Site {get;set;}
Source                    Property   System.String Source {get;set;}
SynchronizingObject       Property   System.ComponentModel.ISynchronizeInvoke SynchronizingObject {get;set;}

bingo! tu pojawia się ‘entryWritten’! a więc zarejestrujmy pułapkę, przefiltrujmy zdarzenia, które nas interesują – i jeśli takowe się pojawi, wyświetlmy na ekran. opis eventów, jakie generuje new-mailboxrepairrequset można znaleźć na technecie. poniżej draft skryptu, który można sobie dowolnie rozbudować. dla czytelności zapisany w kilq linijkach.

$evtlog=Get-EventLog -list|?{$_.log -eq 'application'}

Register-ObjectEvent -InputObject $evtlog -EventName EntryWritten -SourceIdentifier EventTrap -Action{
  $id=$event.SourceEventArgs.Entry.EventID;
  if($id -gt 10041 -and $id -lt 10062) {
    write-host "$id -> $($event.SourceEventArgs.Entry.Message)"
  }
}

na początq podłączamy się do konkretnego logu – logu aplikacji. następnie dla tego logu rejestrujemy pułapkę na pojawienie się nowych zdarzeń i definiujemy akcję. ponieważ na poziomie rejestracji nie ma możliwości zdefiniowania żadnych filtrów, wszystko trzeba zdefiniować wewnątrz ciała skryptu. po dokonaniu rejestracji, w konsoli będą się pokazywać wszystkie logi pomiędzy 10041-10062. oczywiście warto je ładniej wyświetlić i zrobić pełną obsługę… aby tego dokonać, kluczowym jest obiekt $event.SourceEventArgs.Entry, który jest de facto eventem pojawiającym się w logu, czyli można dostać się do wszystkich parametrów takich jak przy ‘ Get-EventLog -LogName application -Newest 1 |gm’.

na koniec trzeba pamiętać o wyrejestrowaniu!! na skróty, wyrejestrowanie wszystkich:

get-event|unregister-event

eN.

 

 

 

Spread the love

Zostaw komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Time limit is exhausted. Please reload CAPTCHA.