The reason you see the Get-Members method is because powershell is trying to be useful and expand the collection. If you have an array with several types of elements, it shows you members for each type (for example, if you are ls (Get-ChildItem), and the directory you are in has FileInfos and DirectoryInfos, and you use ls | gm, it will show you the members of FileInfos, as well as another group of DirectoryInfos members):
(7) C:\ -» ls Directory: C:\ Mode LastWriteTime Length Name ---- ------------- ------ ---- d---- 5/28/2010 8:19 AM .hg d---- 5/13/2010 3:37 PM Build … -a--- 4/22/2010 11:21 AM 2603 TODO.org (8) C:\ -» ls | gm TypeName: System.IO.DirectoryInfo Name MemberType Definition ---- ---------- ---------- Mode CodeProperty System.String Mode{get=Mode;} Create Method System.Void Create(System.Security.AccessControl.Direct... … TypeName: System.IO.FileInfo Name MemberType Definition ---- ---------- ---------- Mode CodeProperty System.String Mode{get=Mode;} AppendText Method System.IO.StreamWriter AppendText() …
What I usually do to make sure that I don't look at the expanded members is try $ s.GetType (). Call it first to find out what I mean. In your case, this is clear and an array, since you initialized it as "$ s = @ (Invo" (@ = its array.)
To find out if an array contains an element, you can use the -contains operator:
(9) C:\ -» @(1,2,3) -contains 1 True
I think you have an array of strings, so you can use a string literal, for example:
(10) C:\ -» @("Stuff","you've","got","might have","Expired") -contains "Expired" True
But if expired is not an exact match (you were looking for the item you are looking for, for example, “Connection Expired 1/1/2010”), you need to find matches and check the quantity, I think:
(23) C:\ -» @("Stuff","you've","got","might have","Connection Expired 1/1/2010") -contains "Expired" False (24) C:\ -» @("Stuff","you've","got","might have","Connection Expired 1/1/2010") | ?{$_.Contains("Expired")} Connection Expired 1/1/2010 (33) C:\ -» $xs = @("Stuff","you've","got","might have","Connection Expired 1/1/2010") | ?{$_.Contains("Expired")} (34) C:\ -» $xs.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True String System.Object (35) C:\ -» $xs Connection Expired 1/1/2010
In this case, there is only one match, so powershell expands it into a string. Moron. If there are more than 1 matches, then:
(36) C:\ -» $xs = @("Stuff","you've","got","might Expired have","Connection Expired 1/1/2010") | ?{$_.Contains("Expired")} (37) C:\ -» $xs.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array (38) C:\ -» $xs might Expired have Connection Expired 1/1/2010
Now its an array.
Fortunately, both the string and the array have the length property:
(39) C:\ -» $xs.Length 2 (40) C:\ -» "Bob".Length 3
So, you can check the length of your results that contain "Expired" to find out if the validity period has expired:
(41) C:\ -» $xs = @("Stuff","you've","got","might Expired have","Connection Expired 1/1/2010") | ?{$_.Contains("Expired")} (42) C:\ -» if ($xs.Length -gt 0) { Write-Host "Whoas, stuff expired, dog." } Whoas, shit expired, dog.
(maybe someone has a better way to check if the collection contains an element that satisfies some predicates (e.g. LINQ Any)?)