2009-05-11 19 views
22

Estoy tratando de leer el registro de eventos para una auditoría de seguridad para todos los usuarios excepto dos, pero ¿es posible hacer eso con el operador -notlike?Uso -no me gusta filtrar varias cadenas en PowerShell

Es algo así:

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

tengo que trabajar para un solo usuario, como:

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

Respuesta

30

V2 al menos contiene el parámetro -username que toma una cadena [], y admite globbing.

V1 desea ampliar su prueba de este modo:

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

O usted podría utilizar "-notcontains" en la matriz en línea, pero esto sólo funcionaría si se puede hacer la coincidencia exacta de los nombres de usuario.

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

+0

La falta ___ se trató como marcado de wiki para cursiva;) – x0n

+1

Gracias .. ¡eso lo hizo! – Pascal

+1

También puede hacer referencia a la lista de nombres de usuario para filtrar a través de una variable:? {$ Users -notcontains $ _. Username} – JasonMArcher

-1

Sí, pero hay que poner la matriz primera en la expresión:

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

-Oisin

+0

he intentado, pero no lo hizo tienen los resultados exceptuados ... revise a continuación si hice algo estúpido, porque ambos usuarios aparecieron, junto con todos los demás: Get-EventLog -LogName Security | donde {@ ("* user1", "* user2") -notlike $ _. UserName} | Format-Table-Property EventID, Category, EntryType, TimeGenerated, UserName – Pascal

+0

Correcto, esto no funcionará porque no importa cuál sea el nombre de usuario, tampoco será como uno de los elementos de la lista. Entonces la condición es siempre verdadera. Estas comparaciones de matriz son siempre OR y no AND. – JasonMArcher

+0

tonto yo. me estaba concentrando en el error sintáctico en lugar de semántico. – x0n

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

Es un poco loco Yo te concedo, y no logra escapar de los nombres de usuario (en el improbable caso de un nombre de usuario utiliza un carácter de escape expresión regular como '\' o '(') , pero funciona.

Como "slipsec" mencionado anteriormente, el uso -notcontains si es posible.

+0

Gracias Peter ... ¡Esa también es una gran alternativa! – Pascal

8

creo que Peter tiene la idea correcta. me gustaría utilizar una expresión regular para este junto con el operador -notmatch.

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

Para soportar escenarios "concuerda con cualquiera de ...", creé una función que es bastante fácil de leer. Mi versión tiene mucho más que eso porque es un cmdlet de PowerShell 2.0, pero la versión que estoy pegando debajo debería funcionar en 1.0 y no tiene lujos.

Se llaman así:

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

Excelente script. ¡Gracias! – Pascal

2

manera más fácil que resulta para múltiples búsquedas es a la tubería a todos ellos (probablemente más pesado el uso de la CPU), sino por su ejemplo de usuario:

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

realizo esto es tarde para el juego, pero en v3 usted puede hacer esto:

Escenario: Lista de todas las computadoras que comienzan con XX1 pero no nombres donde el 4to carácter es L o P

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

También puede contarlos adjuntando la secuencia de comandos anterior en parens y agregando un.método de recuento de este modo:

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

-Gill

2

no utilice -notlike, -notmatch con las expresiones regulares que trabaja en una línea:

Get-MailBoxPermission -id newsletter | ? {$_.User -NotMatch "NT-AUTORIT.*|.*-Admins|.*Administrators|.*Manage.*"} 
Cuestiones relacionadas