Welcome › Forums › General PowerShell Q&A › Where-Object – Matching any integer in an array
- This topic has 21 replies, 4 voices, and was last updated 2 months, 2 weeks ago by
Participant.
-
AuthorPosts
-
-
November 12, 2020 at 8:36 am #270997
Hi PS.org! Looking forward to getting involved here!
Am trying to write a fairly simple script to pull out specific Event IDs from a set of System event logs (on domain controllers), but I can’t quite figure out how to get it to match any of the values within an array that holds the event IDs I want.
I have a variable ($EventIDs) that is an array of 5 or 6 integers, and one for the domain controller objects ($DCs):
When I do something simple, such as search for { $_.EventID -eq ‘1234’), it works fine. However, I can’t figure out how to get this to search for any ID that is in the array $EventIDs:
PowerShell12345Invoke-Command -ComputerName $DCs.Name -ScriptBlock {Get-EventLog -LogName System | Where-Object { $_.EventID -in $EventIDs } | Select-Object machinename,eventid,timegenerated}(I know the above is wrong as it stands!)
I’ve gone through a number of articles today about this and can’t seem to work it out. Would really appreciate a pointer or two!
Best to all,
J
-
November 12, 2020 at 8:46 am #271000
In your script $_.EventID is NOT an integer. It is an EventLogEntry object. If you run the following you will see what I mean:
PowerShell123Get-EventLog -LogName System | select -First 1 | GMGet-EventLog -LogName System | select -First 1 | Select EventID | GMYou will also see that EventLogEntry objects have a property of EventID that is an integer and what you are trying to filter. So you would actually need to re-write as:
PowerShell1Get-EventLog -LogName System | where {$_.EventID.EventID -in $EventIDs}Having said all that it is more efficient to just use the InstanceID parameter of the Get-EventLog command so you are not paying the performance penalty of a pipe. Like this:
PowerShell1Get-EventLog -LogName System -InstanceId $EventIDs -
November 12, 2020 at 8:51 am #271003
The code looks OK to me and works locally. I think this might be a scoping problem. If you’re declaring $EventIDs outside of your ScriptBlock you need to make sure it’s passed through to Invoke-Command.
PowerShell12345Invoke-Command -ComputerName $DCs.Name -ScriptBlock {Get-EventLog -LogName System | Where-Object { $_.EventID -in $Using:EventIDs } | Select-Object machinename,eventid,timegenerated} -
November 12, 2020 at 8:55 am #271006
Hi Mike,
I know $_.EventID is not an integer, I meant that my array is an array of integers (suppose I could have just said ‘numbers’!)
Thanks for that, I’ll give it a try.
J
-
November 12, 2020 at 8:59 am #271009
Hi Matt,
Ah, that makes sense! I’ve done that and it works perfectly!
Do you think it’s best practice to put an array/variable like this within the script block itself, or does it not really matter if you just use $USING: ?
Many thanks,
J
-
November 12, 2020 at 8:59 am #271012
What I meant is you were comparing <EventLogEntry> to <Int> in your script and not <int> to <int> like you might think. Also, I forgot you are doing this in a script block for Invoke-Command so Matt is right about scoping. Local variables in your script are not accessible inside the Invoke-Command script block unless you force it with $using: or pass it in as a parameter value.
-
November 12, 2020 at 9:00 am #271015
What I meant is you were comparing <EventLogEntry> to <Int> in your script and not <int> to <int> like you might think. Also, I forgot you are doing this in a script block for Invoke-Command so Matt is right about scoping. Local variables in your script are not accessible inside the Invoke-Command script block unless you force it with $using: or pass it in as a parameter value.
I see what you mean!
-
November 12, 2020 at 9:34 am #271024
Do you think it’s best practice to put an array/variable like this within the script block itself, or does it not really matter if you just use $USING: ?
I think either way is acceptable as long as your code is consistent.
I’m aware of problems with $Using if you’re developing with Pester but in most (all?) other cases passing local variables with $Using should be fine.
-
November 12, 2020 at 10:03 am #271039
Thanks to you both for your input and help!
J
-
November 12, 2020 at 10:14 am #271051
One more question on this:
I’ve been using a particular event ID/set of IDs that I know exist to test this; the script is actually going to be used to check for events that don’t generally exist but we need to know if they get logged.
When I change the variable $EventIDs to the actual numbers I want to search for, it fails. Why would this be? I’m not sure which ‘-‘ operator the error is referring to – nothing in the syntax has changed, only the contents of the array I am using…
You must provide a value expression on the right-hand side of the ‘-‘ operator.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : ExpectedValueExpression
+ PSComputerName : TESTSERVERPowerShell12345Invoke-Command -ComputerName $DCs.Name -ScriptBlock {Get-EventLog -LogName System | Where-Object { $_.EventID -in $Using:EventIDs } | Select-Object machinename,eventid,timegenerated} | Format-Table -OutVariable EventResults-
This reply was modified 2 months, 2 weeks ago by
Jon Adams.
-
This reply was modified 2 months, 2 weeks ago by
-
November 12, 2020 at 10:40 am #271063
What OS and PS version is your TESTSERVER? I am unable to duplicate your results using Server 2019 / Windows PS Version 5.1 as a target machine. This error is on the remote machine which is why you don’t see line numbers and a PSCOMPUTERNAME property in the error.
-
November 12, 2020 at 10:52 am #271066
Hi Mike,
The test server is Server 2008 R2 and version info is as follows:
PowerShell123456789Name Value---- -----CLRVersion 2.0.50727.8806BuildVersion 6.1.7601.23403PSVersion 2.0WSManStackVersion 2.0PSCompatibleVersions {1.0, 2.0}SerializationVersion 1.1.0.1PSRemotingProtocolVersion 2.1This only occurs when I put the actual IDs I want to use into the array. If I change the array contents back to the values I was using to test with (i.e. event IDs I know for certain are present in the logs), it runs through all machines’ logs fine with zero errors.
Many thanks,
J
-
November 12, 2020 at 11:02 am #271072
That is a very old version of PS. If you can upgrade, I would. Since I can’t duplicate it in my environment, my guess is that version of PS does not handle piping a null value across the pipe to where-object or could be it can’t handle $null -in EventIDs. Do you have another host with at least PS version 3 that you can try?
-
November 12, 2020 at 11:08 am #271075
Hi Mike,
There are other servers I COULD use, but as the purpose of it is to search domain controller logs, it probably doesn’t matter whether it works without errors on another machine!
The thing is: it brings up that above error for 2 machines (DCs), and then continues on its merry way, and actually then finds some of those events on some other machines – so it’s not a critical failure that leads to the script stopping or anything.
I’m just confused as to why simply changing the values in the array would cause the error on the same machine(s)? If it’s able to make a remote connection using Invoke-Command to the machine, and find one set of event IDs, why would another set of IDs be any different?
Many thanks,
J
-
November 12, 2020 at 11:31 am #271093
I agree with Mike that you should try and upgrade those servers. The -in operator was introduced in version 3.0 so this is likely to be version related.
-
November 12, 2020 at 11:33 am #271096
Those will be upgraded at some point. However, I’m just trying to understand (from a learning perspective), why one number in an array doesn’t produce the error, but another one DOES? Surely that can’t be to do with that version it’s on, right?
-
November 12, 2020 at 11:36 am #271099
Also, the other DCs are the same, and they don’t error – which is why I’m confused!
-
November 12, 2020 at 11:42 am #271102
Also, the other DCs are the same, and they don’t error – which is why I’m confused!
Interesting. To troubleshoot, I would probably start an interactive session (ISE) with the server that causes the errors to troubleshoot. Once established you can try the commands one at a time to narrow down and perhaps generate a more helpful error message.
-
November 12, 2020 at 1:25 pm #271120
Are you sure the PS version on the other servers is the same?
A quick check running powershell -version 2.0 confirms that the error is the same. I can’t get it to return anything different.
PowerShell12345678PS E:\temp> powershell -version 2.0Windows PowerShellCopyright (C) 2009 Microsoft Corporation. All rights reserved.PS E:\temp> '1' -in '1','2','3'- : You must provide a value expression on the right-hand side of the '-' operator.+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException+ FullyQualifiedErrorId : ExpectedValueExpression -
November 12, 2020 at 1:47 pm #271135
I rarely run into terminating errors with the standard cmdlets, most errors are non-terminating, so it makes since that it keeps working. If -in was not introduced until PS version 3 then the error message makes perfect sense because the interpreter would recognize the – but not the in. If you just use the -InstanceID parameter in your Get-EventLog call this would be moot since you wouldn’t need to pipe the output to where-object. The -InstanceID parameter will take an array of integers and will filter for EventID. Just change you code to this:
PowerShell1234Invoke-Command -ComputerName $DCs.Name -ScriptBlock {Get-EventLog -LogName System -InstanceID $Using:EventIDs |Select-Object machinename,eventid,timegenerated} | Format-Table -OutVariable EventResults -
November 12, 2020 at 4:09 pm #271174
You can have an integer array of id’s in get-winevent with the filterhashtable. There’s some annoying problems with it over invoke-command in all powershell versions. This worked for me at an elevated prompt.
PowerShell123$eventids = 5,7invoke-command localhost { [int[]]$eventids = $using:eventids;get-winevent @{logname='system';id=$eventids } } -
November 13, 2020 at 4:57 am #271297
Are you sure the PS version on the other servers is the same?
A quick check running powershell -version 2.0 confirms that the error is the same. I can’t get it to return anything different.
PowerShell
<textarea class=”urvanov-syntax-highlighter-plain print-no” style=”tab-size: 4; font-size: 14px !important; line-height: 18px !important; z-index: 0; opacity: 0;” readonly=”readonly” data-settings=”dblclick”>PS E:\temp> powershell -version 2.0
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.PS E:\temp> ‘1’ -in ‘1’,’2′,’3′
– : You must provide a value expression on the right-hand side of the ‘-‘ operator.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ExpectedValueExpression</textarea>12345678PS E:\temp> powershell -version 2.0Windows PowerShellCopyright (C) 2009 Microsoft Corporation. All rights reserved.PS E:\temp> ‘1’ -in ‘1’,‘2’,‘3’– : You must provide a value expression on the right-hand side of the ‘-‘ operator.+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException+ FullyQualifiedErrorId : ExpectedValueExpressionHi Matt,
You’re absolutely right – I had wrong info. These 2 servers only are 2008R2, the others are 2012.
That explains it then as I have tested with -match and it works OK.
Sorry to you and Mike for the confusion and thanks for your input and assistance!
J
-
-
AuthorPosts
- You must be logged in to reply to this topic.