Author Posts

January 9, 2017 at 7:26 pm


    foreach ($key in $MyInvocation.BoundParameters.Keys) {
        if ($key -eq "ScanDurationSeconds") {

           $logoutput | Where-Object ScanDurationSeconds -GT $ScanDurationSeconds

        }

Okay, so if I do the above it outputs the value specified in the parameter. However, If I want to do something like:

$test = $logoutput | Where-Object ScanDurationSeconds -GT $ScanDurationSeconds

Test ends up being a blank result.

Are you unable to map a result created in a parameter to a variable for later usage? I am obviously missing something fundamental here.

January 9, 2017 at 8:22 pm

Two things:

  • No need to loop through the keys, you can use the .ContainsKey method for the hash table:
    function Test-It {
        [CmdLetBinding()]
        param (
            $ScanDurationSeconds
        )
        begin{}
        process{
            if ($PSBoundParameters.ContainsKey("ScanDurationSeconds")) {
                Write-Verbose ("Doing something with {0} ScanDurationSeconds" -f $ScanDurationSeconds)
            }
        }
        end{}
    }
    
    Test-It -ScanDurationSeconds 23 -Verbose
    
  • $logoutput | Where-Object $_.ScanDurationSeconds -GT $ScanDurationSeconds

January 9, 2017 at 9:49 pm

Thank you very much for response.

I guess I was not super clear. I am trying to make a "search" function to search a CSV. I want to be able to search against each of the columns. Manually, I can do this fine, however I am trying to make a parameter that can replicate/standardize the process to make it easier for someone else to use the script.

So with some help this was the result (As I couldn't figure out another way to do something with multiple parameters without a ridiculous else chain)


function Get-LogData
    (
    [Parameter(Mandatory=$false)][string]$Filename,
    [Parameter(Mandatory=$false)][string]$Event,
    [Parameter(Mandatory=$false)][string]$EventSeverityLevel,
    [Parameter(Mandatory=$false)][int]$ResultID,
    [Parameter(Mandatory=$false)][string]$SymantecProtectionEngineIPAddress,
    [Parameter(Mandatory=$false)][string]$ClientIP,
    [Parameter(Mandatory=$false)][string]$ContainerViolation,
    [Parameter(Mandatory=$false)][int]$ScanDurationSeconds
    
    )
{
    $Where = @()

    foreach ($key in $MyInvocation.BoundParameters.Keys) {
        if ($key -ne "ScanDurationSeconds") {
            $Where += "`$_.$key -like '*$(Get-Variable -Name $key -ValueOnly)*'"
        }
    }

    if ($Where) {
        $WhereFilter = [scriptblock]::Create(($Where -join " -and "))
    } else {
        $WhereFilter = [scriptblock]::Create($true)
    }

    

    $logoutput| ? -FilterScript $WhereFilter

}

The Best possible solution would be figuring out how to build a script block "And" run on depending on the parameters that were utilized.

So Like:

 $logoutput| ? -FilterScript $WhereFilter

Would expand where filter out to something like:

$logoutput | Where-Object {$_.Filename -like *"Somefile"* -and $_.ScanDurationSeconds -gt 30}

But I am not really sure how to accomplish this.

Edit: May have found something. Looking into it now.

January 10, 2017 at 12:53 am

Okay, So here is what I have now. Problem is that it ends up loosing the variable values... not sure why.

Results:
Where-Object { $_.FileName -like $Filename -and $_.ScanDurationSeconds -gt $ScanDurationSeconds }

function Get-LogData
    (
    [Parameter(Mandatory=$false)][string]$FileName,
    [Parameter(Mandatory=$false)][string]$Event,
    [Parameter(Mandatory=$false)][string]$EventSeverityLevel,
    [Parameter(Mandatory=$false)][int]$ResultID,
    [Parameter(Mandatory=$false)][string]$ClientIP,
    [Parameter(Mandatory=$false)][string]$ContainerViolation,
    [Parameter(Mandatory=$false)][int]$ScanDurationSeconds
    
    )
{

    #Build Where array.  
    $Where = @()

    #Evaluate Parameter response, If exists, add to Where array

        if ($PSBoundParameters.ContainsKey("FileName")) {$Where += '$_.FileName -like $Filename'}
        if ($PSBoundParameters.ContainsKey("Event")) {$Where += '$_.Event -like $Event'}
        if ($PSBoundParameters.ContainsKey("EventSeverityLevel")) {$Where += '$_.EventSeverityLevel -like $Event'}
        if ($PSBoundParameters.ContainsKey("ResultID")) {$where += '$_.ResultID -like $ResultID'}
        if ($PSBoundParameters.ContainsKey("ClientIP")) {$Where += '$_.ClientIP -like $ClientIP'}
        if ($PSBoundParameters.ContainsKey("ContainerViolation")) {$Where += '$_.ContainerViolation -like $ContainerViolation'}
        if ($PSBoundParameters.ContainsKey("ScanDurationSeconds")) {$Where += '$_.ScanDurationSeconds -gt $ScanDurationSeconds'}
        
#  Join each objects in Where array into a string seperated by -And

$WhereString = $Where -join " -and "

#  Create script block with script string.
$WhereBlock =  [scriptblock]::Create( $WhereString )
  
  write-host "Where-Object { $WhereBlock }"

    #$logoutput | Where-Object { $WhereBlock }

}


*** EDIT ***

Okay, fixed it. I was using ' instead of " which prevented the variables from expanding out. Duh!

Thanks a bunch. Your layout is leading me to figuring this one out. Almost there. Still not working properly but is building the array!

January 11, 2017 at 4:05 am

With your additional explanation, I would use a for loop. However, you are severely limiting the ability to query the because there are more operators than -and (such as -or) and comparison operators such as -like, -ne and many more. It would be better to teach the other user basic query syntax than trying to modularize into a function IMHO. Here is how I would update your code above:

function Get-LogData {
    param (
    [Parameter(Mandatory=$false)][string]$FileName,
    [Parameter(Mandatory=$false)][string]$Event,
    [Parameter(Mandatory=$false)][string]$EventSeverityLevel,
    [Parameter(Mandatory=$false)][int]$ResultID,
    [Parameter(Mandatory=$false)][string]$ClientIP,
    [Parameter(Mandatory=$false)][string]$ContainerViolation,
    [Parameter(Mandatory=$false)][int]$ScanDurationSeconds
    
    )

    $Where = @()
    if ($PSBoundParameters) {
        foreach ($param in $PSBoundParameters.GetEnumerator()) {
            $Where += '$_.{0} = ${0}' -f $param.Key
        }
        
        $where
    }
}

Get-LogData -Event "Blue" -ResultID 123