возникли проблемы с фильтром где-объекта PowerShell - PullRequest
0 голосов
/ 18 января 2012

Я пытаюсь создать универсальную функцию, которая получает список служб и выполняет следующий фрагмент. Если я отправляю одно значение, оно работает, если я пытаюсь отправить более одного значения, оно не выполняется.

Есть ли лучший способ сделать это или я упускаю что-то простое?

cls

$host_name = "."
    #works
$ary_param = "sql"
    #fails
#$ary_param = "sql,ftp"

$services = @($ary_param)

$colItems = Get-WmiObject -Class Win32_Service -ComputerName $host_name | 
            Select-Object Name, DisplayName, State, ProcessID, StartMode, StartName  | 
            Where-Object{$_.Name -like '*' + $services + '*'}

$ServiceInfo = @()

foreach ($objItem in $colItems)
{       
    $tempServiceInfo = "" | Select Name, DisplayName, State, ProcessID, PriorityClass, StartMode, StartName

    [string]$tempServiceInfo.Name = $objItem.Name.ToString()
    [string]$tempServiceInfo.DisplayName = $objItem.DisplayName.ToString()
    [string]$tempServiceInfo.State = $objItem.State.ToString()
    [string]$tempServiceInfo.ProcessID = $objItem.ProcessID.ToString()
    [string]$tempServiceInfo.StartMode = $objItem.StartMode.ToString()
    [string]$tempServiceInfo.StartName = $objItem.StartName.ToString()

    $svc_pid = $objItem.ProcessID
    $priority_class = Get-Process -ComputerName $host_name | Select Id, PriorityClass | Where-Object{$_.Id -eq $svc_pid }
    [string]$tempServiceInfo.PriorityClass = $priority_class.PriorityClass

    $ServiceInfo += $tempServiceInfo        
}

$ServiceInfo | Format-Table 

Ответы [ 3 ]

4 голосов
/ 18 января 2012

Возможно, вы столкнулись с классической проблемой PowerShell, заключите этот вызов в подвыражение массива:

$colItems = @(Get-WmiObject -Class Win32_Service -ComputerName $host_name | 
              Select-Object Name, DisplayName, State, ProcessID, StartMode, StartName  | 
              Where-Object{$_.Name -like '*' + $services + '*'})

Если это не так, не могли бы вы более точно указать, где ваш скрипт не работает?

Обновление: я бы посоветовал вам использовать простое регулярное выражение с оператором -match, например. "

$services = "ftp|sql"
$colItems = @(Get-WmiObject -Class Win32_Service -ComputerName $host_name | 
              Where-Object{$_.Name -match $services} |
              Select-Object Name, DisplayName, State, ProcessID, StartMode, StartName)

Вы также можете немного оптимизировать эту команду, сначала отфильтровав с помощью Where-Object, а затем запустив Select-Object. В общем, лучше всего выполнять фильтрацию как можно раньше в конвейере.

0 голосов
/ 19 января 2012

Другой способ - создать WQL-фильтр на лету:

$services = 'ftp','sql','iis'
$filter=($services | foreach { "Name LIKE '%$_%'" }) -join ' OR '
#$filter
#Name LIKE '%ftp%' OR Name LIKE '%sql%' OR Name LIKE '%iis%'

Get-WmiObject -Class Win32_Service -ComputerName $host_name -Filter $filter | `
Select-Object Name, DisplayName, State, ProcessID, StartMode, StartName
0 голосов
/ 19 января 2012

Прежде всего, если вам нужен набор значений в $ary_param, сделайте что-то вроде "sql","ftp", а не "sql,ftp" - в последнем случае это всего лишь одна строка. Когда вы присваиваете услуги и хотите использовать последние, вам, возможно, придется сделать следующее:

$services = $ary_param.split(",")

Это позволит убедиться, что $ services является массивом.

В where-object то, что вы делаете, выглядит примерно так:

 "sql server" -like "*" + $services + "*"

Выше приведено значение true, и это тот случай, когда $ary_param имеет только один элемент.

Но что-то вроде $ services = "sql","ftp" сделает приведенный выше возврат false.

Возможно, вы захотите направить службы и делать то, что вы хотите, в объекте foreach:

$services | %{
#logic goes here
#use $_ to represent each service type and use it in the Where-Object

}

Обратите внимание, что вам не нужно использовать Where-Object в Get-WmiObject, вы можете фильтровать напрямую:

Get-WmiObject -Class Win32_Service -Filter "Name LIKE '$_'" -ComputerName $host_name

Вам также придется принудительно выводить Get-WmiObject в массив, чтобы избежать проблем с возвратом одного объекта или без него, как рекомендует @Keith Hill.

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