0

At the moment I am loading in some data from an XML file to configure some parameters for my script to run, however the $keywords and $maxCounts are not getting the correct values when they are being sent to the CheckForKeywords function

function Main()
{

#### VARIABLES RELATING TO THE LOG FILE

#contains the log path and log file mask
$logPaths = @()
$logFileMasks = @()

# key value pair for the strings to match and the max count of matches before they are considered an issue
$keywords = @(,@())
$maxCounts = @(,@())


#### FUNCTION CALLS

LoadLogTailerConfig $logConfigPath ([ref]$logPaths) ([ref]$logFileMasks) ([ref]$keywords) ([ref]$maxCounts)

for ($i = 0; $i -lt $logPaths.Count; $i++)
{
    $tail = GetLogTail $numLinesToTail $logPaths[$i] $logFileMasks[$i]

    $tailIssueTable = CheckForKeywords $tail $keywords[$i] $maxCounts[$i]


}

}

# Loads in configuration data for the utility to use
function LoadLogTailerConfig($logConfigPath, [ref]$logPaths, [ref]$logFileMasks, [ref]$keywords, [ref]$maxCounts)
{
    Write-Debug "Loading config file data from $logConfigPath"

    [xml]$configData = Get-Content "C:\Testing\Configuration\config.xml"

    foreach ($log in $configData.Logs.Log) {

        $logPaths.Value += $log.FilePath
        $logFileMasks.Value += $log.FileMask

        $kwp = @()
        $kwc = @()

        foreach ($keywordSet in $log.Keywords.Keyword)
        {
            $kwp += $keywordSet.Pattern
            $kwc += $keywordSet.MaxMatches 
        }

        $keywords.Value += $kwp
        $maxCounts.Value += $kwc
    }
}

# Returns body text for email containing details on keywords in the log file and their frequency
function CheckForKeywords($tail, $keywords, $maxCounts)
{   
    $issuesFound = 0


    for ($i = 0; $i -lt $keywords.Count; $i++)
    {
        $keywordCount = ($tail | Select-String $keywords[$i] -AllMatches).Matches.Count

        Write-Debug $keywords.Count

        Write-Debug (("Match count for {0} : {1}" -f $keywords[$i], $keywordCount))

        if ($keywordCount -gt $maxCounts)
        {
            #do stuff
        }
    }

    return ""
}

Main
5
  • Much like you last question you need to declare your functions before you call them. CheckForKeywords needs to be before the line you call it from Commented Feb 3, 2015 at 13:35
  • just as in my last question that has already been done, I just simplified the code for the purposes of this question, I can assure you that the functions are declared and called correctly, it is merely the arrays that are behaving unexpectedly, I have edited for your peace of mind Commented Feb 3, 2015 at 22:48
  • 1
    Matthew Pigram, it's not the peace of mind. It's just it's easier for people to help you if they don't need to monkey around switching the order of lines of code to reproduce your issue. @matt Commented Feb 3, 2015 at 23:06
  • Could you please provide a) the definition of GetLogTail and b) sample of config.xml Commented Feb 3, 2015 at 23:11
  • @zespri GetLogTail is not necessary as it does not involve the variables in question. I would provide the config file however it would appear that applying the changes in your answer below got the desired result. Commented Feb 4, 2015 at 2:44

1 Answer 1

1

What you are doing is not a two dimensional array it's a nested array. By writing

$keywords = @(,@())
$maxCounts = @(,@())

you are creating an array with one element. This element is an array with zero elements. You don't need that. So change the above to:

$keywords = @()
$maxCounts = @()

Now when you do this:

$keywords.Value += $kwp
$maxCounts.Value += $kwc

powershell unravels the arrays on the right and concatinates element by element with arrays on the left. That's not what you want. So change this to

$keywords.Value += @(,$kwp)
$maxCounts.Value += @(,$kwc)

On a side note using by ref parameters is not idiomatic in powershell and it's not as easy to get help with that approach. I suggest changing your functions to pass the results via the pipeline, the powershell way, people who are going to support your script in future will appreciate that. You can model different type of values that you are wanting to return as properties on an object and return that object instead. Good luck.

Sign up to request clarification or add additional context in comments.

1 Comment

this was the correct way to get it working. Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.