sqlpadawan
sqlpadawan

Reputation: 305

having problems with a powershell where-object filter

I am trying to build a generic function that receives a list of services and executes the following snippet. If I send in one value, it works, if I try to send in more than one value, it fails.

Is there a better way to go about this or am I missing something simple?

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 

Upvotes: 0

Views: 6525

Answers (3)

Shay Levy
Shay Levy

Reputation: 126712

Another way would be to create WQL filter on the fly:

$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

Upvotes: 0

manojlds
manojlds

Reputation: 301077

First of all, if you want a set of values in $ary_param, do something like "sql","ftp" and not "sql,ftp" - in the latter case it is just one string. When you are assigning to services and you want to use the latter, you might have to do:

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

This will make sure $services is an array.

In the where-object, what you are doing is something like this:

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

The above will give true and this is the case when $ary_param has only one element.

But something like $services = "sql","ftp", will make the above return false.

You might want to pipe services and do what you want in a foreach-object:

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

}

Note that you need not use the Where-Object in the Get-WmiObject, you can filter directly:

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

You will also have to force the Get-WmiObject output into an array to avoid issues with one object or no object returning, like @Keith Hill suggest.

Upvotes: 0

Keith Hill
Keith Hill

Reputation: 201622

You might be hitting a classic PowerShell issue, wrap this call in an array subexpression:

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

If this isn't it, could you be more specific about where your script is failing?

Update: I would suggest that you use a simple regular expression with the -match operator e.g."

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

You can also optimize this command a bit by first filtering with Where-Object and then running Select-Object. In general, it is best to do the filtering as early as possible in the pipeline.

Upvotes: 4

Related Questions