Question about Parameter usage.

This topic contains 4 replies, has 2 voices, and was last updated by Profile photo of Rob Simmers Rob Simmers 1 week, 3 days ago.

  • Author
    Posts
  • #61590
    Profile photo of Gorstag
    Gorstag
    Participant
    
        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.

  • #61599
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    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
    • #61603
      Profile photo of Gorstag
      Gorstag
      Participant

      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.

    • #61605
      Profile photo of Gorstag
      Gorstag
      Participant

      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!

  • #61681
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    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
    

You must be logged in to reply to this topic.