2009-05-11 12 views
22

Próbuję odczytać dziennik zdarzeń dla audytu bezpieczeństwa dla wszystkich użytkowników z wyjątkiem dwóch, ale czy jest to możliwe z operatorem -notlike?Użyj -nie podobnych do filtrowania wielu ciągów w PowerShell

To coś takiego:

Get-EventLog -LogName Security | where {$_.UserName -notlike @("*user1","*user2")} 

mam to działa dla pojedynczego użytkownika, jak:

Get-EventLog -LogName Security | where {$_.UserName -notlike "*user1"} 

Odpowiedz

30

V2 przynajmniej zawiera parametr -username, który pobiera ciąg [] i obsługuje globbing.

V1 chcesz poszerzyć swoją próbę tak:

Get-EventLog Security | ?{$._UserName -notlike "user1" -and $_.UserName -notlike "*user2"} 

Lub można użyć „-notcontains” na tablicy inline ale to będzie działać tylko wtedy, gdy można zrobić dokładne dopasowanie na nazwy użytkowników.

... | ?{@("user1","user2") -notcontains $_.username}

+0

Brakujący ___ został potraktowany jako znacznik wiki dla kursywy;) – x0n

+1

Dzięki .. to zrobiło! – Pascal

+1

Możesz także odwoływać się do listy nazw użytkowników, aby odfiltrować je za pomocą zmiennej:? {$ Users -notcontains $ _. Username} – JasonMArcher

-1

Tak, ale trzeba umieścić tablicę pierwszy w wyrażeniu:

... | where { @("user1","user2") -notlike $_.username } 

-Oisin

+0

próbowałem, ale nie mieć wyjątkowe wyniki. Sprawdź poniżej, jeśli zrobiłem coś głupiego, ponieważ pojawili się obaj użytkownicy, wraz ze wszystkimi innymi: Get-EventLog -LogName Bezpieczeństwo | gdzie {@ ("* użytkownik1", "* użytkownik2") - nie tak jak $ _. Nazwa użytkownika} | Format-Table -Property EventID, Category, EntryType, TimeGenerated, UserName – Pascal

+0

W porządku, to przyniesie efekt, ponieważ bez względu na nazwę użytkownika, nie będzie tak jak jedna z pozycji na liście. Tak więc warunek jest zawsze prawdziwy. Te porównania tablic są zawsze OR, a nie AND. – JasonMArcher

+0

Głupia mnie. koncentrowałem się raczej na błędach składniowych niż semantycznych. – x0n

0
$listOfUsernames = @("user1", "user2", "etc", "and so on") 
Get-EventLog -LogName Security | 
    where { $_.Username -notmatch (
     '(' + [string]::Join(')|(', $listOfUsernames) + ')') } 

To trochę szalone cię przyznać, a nie uciekać nazwy użytkownika (w unprobable przypadku nazwa użytkownika używa regex znak escape jak '\' lub '(') , ale to działa.

Jako „slipsec” wspomniano powyżej, stosowanie -notcontains jeśli to możliwe.

+0

Dzięki Peter .. To także świetna alternatywa! – Pascal

8

myślę Peter ma rację. Chciałbym użyć wyrażenia regularnego do tego wraz z operatorem -notmatch.

Get-EventLog Security | ?{$_.Username -notmatch '^user1$|^.*user$'} 
6

W celu obsługi scenariuszy "pasuje do każdego ...", stworzyłem funkcję, która jest dość łatwa do odczytania. Moja wersja ma o wiele więcej, ponieważ jest to cmdlet programu PowerShell 2.0, ale wersja, którą wklejam poniżej, powinna działać w wersji 1.0 i nie może zawierać żadnych dodatków.

to nazwać tak:

Get-Process | Where-Match Company -Like '*VMWare*','*Microsoft*' 
Get-Process | Where-Match Company -Regex '^Microsoft.*' 

filter Where-Match($Selector,[String[]]$Like,[String[]]$Regex) { 

    if ($Selector -is [String]) { $Value = $_.$Selector } 
    elseif ($Selector -is [ScriptBlock]) { $Value = &$Selector } 
    else { throw 'Selector must be a ScriptBlock or property name' } 

    if ($Like.Length) { 
     foreach ($Pattern in $Like) { 
      if ($Value -like $Pattern) { return $_ } 
     } 
    } 

    if ($Regex.Length) { 
     foreach ($Pattern in $Regex) { 
      if ($Value -match $Pattern) { return $_ } 
     } 
    } 

} 

filter Where-NotMatch($Selector,[String[]]$Like,[String[]]$Regex) { 

    if ($Selector -is [String]) { $Value = $_.$Selector } 
    elseif ($Selector -is [ScriptBlock]) { $Value = &$Selector } 
    else { throw 'Selector must be a ScriptBlock or property name' } 

    if ($Like.Length) { 
     foreach ($Pattern in $Like) { 
      if ($Value -like $Pattern) { return } 
     } 
    } 

    if ($Regex.Length) { 
     foreach ($Pattern in $Regex) { 
      if ($Value -match $Pattern) { return } 
     } 
    } 

    return $_ 

} 
+0

Świetny scenariusz. Dzięki! – Pascal

2

Najłatwiej znaleźć dla wielu wyszukiwań jest do rury nich wszystkich (prawdopodobnie cięższy użycie CPU), ale dla przykładu użytkownik:

Get-EventLog -LogName Security | where {$_.UserName -notlike "*user1"} | where {$_.UserName -notlike "*user2"} 
0

Zdaję sobie sprawę, jest to spóźnione, ale w wersji 3 można to zrobić:

Scenariusz: Lista wszystkich komputerów zaczynających się od XX1, ale bez nazw, gdzie 4. znak to L lub P

Get-ADComputer -Filter {(name -like "XX1*")} | Select Name | Where {($_.name -notlike "XX1L*" -and $_.name -notlike "XX1P*")} 

Można je również liczyć, zamykając powyższy skrypt w parens i dodając.metoda zliczania tak:

(Get-ADComputer -Filter {(name -like "XX1*")} | Select Name | Where {($_.name -notlike "XX1L*" -and $_.name -notlike "XX1P*")}).count 

-Gill

2

nie używać -notLike, -notMatch z wyrażeń regularnych działa w jednym wierszu:

Get-MailBoxPermission -id newsletter | ? {$_.User -NotMatch "NT-AUTORIT.*|.*-Admins|.*Administrators|.*Manage.*"} 
Powiązane problemy