Используйте -не нравится, чтобы отфильтровать несколько строк в PowerShell - PullRequest
25 голосов
/ 11 мая 2009

Я пытаюсь прочитать журнал событий для аудита безопасности для всех пользователей, кроме двух, но возможно ли это сделать с помощью оператора -notlike?

Это что-то вроде этого:

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

У меня это работает для одного пользователя, например:

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

Ответы [ 8 ]

33 голосов
/ 11 мая 2009

V2 по крайней мере содержит параметр -username, который принимает строку [] и поддерживает глобализацию.

V1, вы хотите расширить свой тест следующим образом:

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

Или вы можете использовать «-notcontains» во встроенном массиве, но это сработает только в том случае, если вы сможете точно сопоставить имена пользователей.

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

9 голосов
/ 12 мая 2009

Я думаю, у Питера правильная идея. Я бы использовал для этого регулярное выражение вместе с оператором -notmatch.

Get-EventLog Security | ?{$_.Username -notmatch '^user1$|^.*user$'}
7 голосов
/ 13 мая 2009

Для поддержки сценариев "соответствует любому из ..." я создал функцию, которая довольно легко читается. Моя версия имеет гораздо больше, потому что это командлет PowerShell 2.0, но версия, которую я вставил ниже, должна работать в 1.0 и не иметь излишеств.

Вы называете это так:

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 $_

}
4 голосов
/ 15 ноября 2016

не используйте -notLike, -notMatch с Regular-Expression работает в одной строке:

Get-MailBoxPermission -id newsletter | ? {$_.User -NotMatch "NT-AUTORIT.*|.*-Admins|.*Administrators|.*Manage.*"}
3 голосов
/ 13 декабря 2011

Самый простой способ найти несколько запросов - это передать их все (возможно, более интенсивное использование процессора), но для вашего примера пользователя:

Get-EventLog -LogName Security | where {$_.UserName -notlike "*user1"} |  where {$_.UserName -notlike "*user2"}
1 голос
/ 11 декабря 2013

Сценарий: Перечислите все компьютеры, начинающиеся с XX1, но не имена, где 4-й символ - это L или P

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

Вы также можете сосчитать их, заключив вышеприведенный скрипт в скобки и добавив метод .count следующим образом:

(Get-ADComputer -Filter {(name -like "XX1*")} | Select Name | Where {($_.name -notlike "XX1L*" -and $_.name -notlike "XX1P*")}).count
0 голосов
/ 11 мая 2009
$listOfUsernames = @("user1", "user2", "etc", "and so on")
Get-EventLog -LogName Security | 
    where { $_.Username -notmatch (
        '(' + [string]::Join(')|(', $listOfUsernames) + ')') }

Это немного сумасшествие, которое я вам предоставлю, и оно не может избежать имен пользователей (в непробиваемом случае имя пользователя использует escape-символ Regex, такой как '\' или '('), но это работает.

В качестве "slipsec", упомянутого выше, используйте -notcontains, если это возможно.

0 голосов
/ 11 мая 2009

Да, но вы должны поставить массив первым в выражении:

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

-Oisin

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...