Fabricating a custom -Filter in my Advanced Function

I have an Advanced Function that is designed to stream packets to me and they come into my NIC, similar to Wireshark. The problem is that I want to implement a -Filter parameter in my function rather than piping the whole function to Where-Object.

At first glance, I thought I would get away with setting a a $filter paramater as a scriptblock and where I am streaming the object in one at a time, piping THAT object to Where-Object like this:
$Packet Where-Object -FilterScript $Filter

This however didn’t work as I had planned. I am going to spare the long explanation of trial and error for the time being. Does anyone know of resources out there for implementing my own -Filter Parameter? I have searched for the last hour and a half and had no luck.

So, I am completely not understanding what you’re asking. I think you probably need to share some code snippets of what you’re doing.

As far as implementing your own -Filter parameter… that’s easy. Doing something with it depends entirely on what your code is doing. I mean, there’s no built-in “here’s how to write a filter.” For example,

function foo {
  Get-Something | Where-Object -Filter $filter

Essentially works, but I’ve no idea if that’s meaningful in what you’re trying to do. And I should point out that this is not functionally all that different from piping the whole function to Where-Object, if your function is normally outputting one object at a time to the pipeline. A filter is really only meaningful in a function if it can prevent data from entering PowerShell at all, a la the -Filter on Get-WmiObject. Once you’re “filtering using PowerShell,” it doesn’t necessarily matter where you do it (again, all things being equal - not seeing your code it’s hard to make definitive statements).

I doubt the performance will be any better than using Where-Object, but you can do something like this:

function YourFunction
    param (


        if ($null -eq $Filter -or $Filter.Invoke($InputObject))
            # Object passed your filter (or no filter was specified); do something here

With the code written like that, the two following commands would produce identical results:

$strings = '1','22','333','4444','55555'

$strings | YourFunction | Where-Object { $_.Length -gt 3 }
$strings | YourFunction -Filter { $_.Length -gt 3 }

Never Mind. I tried an additional test and it succeeded. So the Fundamental question that I was asking has been solved. This is the test that I ran and succeeded with:

Function Test { [CmdletBinding()] param ( [scriptblock]$Filter )
Begin {
Process {

    $Packet = New-Object PSObject -Property @{
        Name = "MyStuff"
        Address = ""
        Port = 135
        Notes = "This is a test."

    If ($Filter) {
        $Packet | Select-Object Name,Address,Port,Notes | Where-Object $Filter
    Else {
        $Packet | Select-Object Name,Address,Port,Notes
End {


Test -Filter {$_.Name -like “Stuff”}

No Results

Test -Filter {$_.Name -like “Stuff”}


I lied… There is a followup question that comes to mind. With the -filter in Get-ADUser, I can specify
{SamAccountName -eq “MyUserName”}
Rather than
{$_.SamAccountName -eq “MyUserName”}

Does anyone have an idea on how I can mimic that functionality in the test code above?

Get-ADUser’s filter is much more complex. It accepts a string, not a ScriptBlock, and it has code to parse that string and turn it into an LDAP filter behind the scenes. Writing your own code to parse a complex expression and evaulate it against an input object would be a lot of work, with the only real benefit being that the user can save three characters of typing by eliminating $_.

I understand. I guess the bigger concern of mine is that trying to remember several different -filter syntax’s for different commands might be a little too much with their already high stress from a heavy workload. I am just trying to match it to AD because it is what they are used to. Now that I know there is no “easy” way to do it, I will likley go on a glorious adventure developing a code snippet to handle it in the way that I desire.

Thanks for all your help!