Используйте-notlike для отфильтровывания нескольких строк в PowerShell

К сожалению, нет. Разрушающий синтаксис не поддерживает указание аннотаций типов. По этой теме есть выпуск , но он открыт и не особенно активен.

26
задан Peter Mortensen 20 January 2015 в 14:32
поделиться

5 ответов

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

V1 вы хотите расширить свой тест таким образом :

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

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

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

34
ответ дан 28 November 2019 в 06:48
поделиться

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

Get-EventLog Security | ?{$_.Username -notmatch '^user1$|^.*user$'}
10
ответ дан 28 November 2019 в 06:48
поделиться

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

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

- Oisin

-1
ответ дан 28 November 2019 в 06:48
поделиться

Для поддержки сценариев «соответствует любому из ...» я создал функцию, которую довольно легко читать. В моей версии гораздо больше возможностей, потому что это командлет 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 $_

}
7
ответ дан 28 November 2019 в 06:48
поделиться
$listOfUsernames = @("user1", "user2", "etc", "and so on")
Get-EventLog -LogName Security | 
    where { $_.Username -notmatch (
        '(' + [string]::Join(')|(', $listOfUsernames) + ')') }

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

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

0
ответ дан 28 November 2019 в 06:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: