К сожалению, нет. Разрушающий синтаксис не поддерживает указание аннотаций типов. По этой теме есть выпуск , но он открыт и не особенно активен.
V2 по крайней мере содержит параметр -username
, который принимает строку [] и поддерживает подстановку.
V1 вы хотите расширить свой тест таким образом :
Get-EventLog Security | ?{$_.UserName -notlike "user1" -and $_.UserName -notlike "*user2"}
Или вы можете использовать "-notcontains" во встроенном массиве, но это будет работать только в том случае, если вы можете точно сопоставить имена пользователей.
... | ? {@ ("user1", "user2") -notcontains $ _. username}
Я думаю, что Питер правильно понял. Я бы использовал для этого регулярное выражение вместе с оператором -notmatch.
Get-EventLog Security | ?{$_.Username -notmatch '^user1$|^.*user$'}
Да, но вы должны поместить массив первым в выражение:
... | where { @("user1","user2") -notlike $_.username }
- Oisin
Для поддержки сценариев «соответствует любому из ...» я создал функцию, которую довольно легко читать. В моей версии гораздо больше возможностей, потому что это командлет 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 $_
}
$listOfUsernames = @("user1", "user2", "etc", "and so on")
Get-EventLog -LogName Security |
where { $_.Username -notmatch (
'(' + [string]::Join(')|(', $listOfUsernames) + ')') }
Это немного безумие, я согласен, и он не может экранировать имена пользователей (в маловероятном случае имя пользователя использует escape-символ регулярного выражения, например '\' или '('), но это работает.
В качестве "slipsec", упомянутого выше, по возможности используйте -notcontains.