Byron Madison
Byron Madison

Reputation: 33

Finding an item in an array

$LogsPath = '\\someserver\somepath\*'
$LogsProperties = Get-ChildItem -Path $LogsPath -recurse |
Select-String -Pattern '[a-z]' |
Select-Object -Property Filename, Path, Line

$Array = @()
$LogsProperties | foreach {
$Array += $LogsProperties
}

The query above will create an array with the following values

(dashes are tabs/columns)

Filename--------------------------Path--------------------------------------------------------------Line

FName1 LName1.txt-----------\\someserver\somepath\FName1 LName1.txt-----------XXX Value
FName2 LName2.txt-----------\\someserver\somepath\FName1 LName1.txt-----------YYY Value
FName3 LName3.txt-----------\\someserver\somepath\FName1 LName1.txt-----------ZZZ Value

$Array[0]

Returns:

FName1 LName1.txt-----------\\someserver\somepath\FName1 LName1.txt-----------XXX Value

Can someone tell me how to search for the index of an element using a value

The function below doesn't work for me

$array.indexof('XXX Value')
0 <-- expected result, index of the array

and will return the error below

Method invocation failed because [System.Object[]] doesn't contain a method named 'indexof'. At line:20 char:15 + $array.indexof <<<< ('XXX Value') + CategoryInfo : InvalidOperation: (indexof:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound

Upvotes: 1

Views: 3202

Answers (2)

mklement0
mklement0

Reputation: 437933

As pointed out in Maximilian Burszley's answer, $LogsProperties is already an array, whose elements are [pscustomobject] instances with properties FileName, Path, and Line.

(Your attempt to create $Array from $LogsProperties is not only unnecessary, but also broken, because the elements of $Array all end up referencing the array referenced by $LogsProperties as a whole.)

In order to use the .IndexOf() method on array instances[1], PSv3+ is required. PSv3+ also allows you to use member-access enumeration, so you can apply .IndexOf() to $LogsProperties.Line in order to search the array of .Line property values:

$LogsProperties.Line.IndexOf('XXX Value') # -> 0

In PSv2 you can use a foreach loop to determine the index:

$i = 0
foreach ($obj in $LogsProperties) { if ($obj.Line -eq 'XXX Value') { break }; ++$i }
if ($i -eq $LogsProperties.Count) { $i = -1 }
# $i now contains the index of the matching element or -1, if not found.

[1] Type System.Array, the base type for all arrays, also has a static .IndexOf() method that is available in PSv2 too. However, given the need to search the .Line property values of the array elements of $LogProperties, that won't help here, unless a separate array with just the .Line property values is constructed first.

Upvotes: 1

Maximilian Burszley
Maximilian Burszley

Reputation: 19664

So your $logsProperties is already an array. You can filter using Where-Object or the Where array method:

$logsProperties = Get-ChildItem -Path \\someserver\somepath\* -Recurse |
    Select-String -Pattern '[a-z]' |
    Select-Object -Property FileName, Path, Line

Filtering:

$logsProperties | Where-Object Line -like '*xxx value*'

or:

$logsProperties.Where{$_.Line -like '*xxx value*'}

Upvotes: 1

Related Questions