I'm struggling with this code:
Get-Sensor -Name Ping | where {$_.Tags -like "Kat.A" -or $_.Tags -like "Kat.B" -or $_.Tags -like "Kat.C" -or $_.Tags -like "Kat.D"} | Select-Object Device, Tags
I get these values via. Connect-PrtgServer. The output data for this is:
DEVICENAME {Kat.C}
DEVICENAME {Kat.B, C_OS_Win}
DEVICENAME {Kat.A, pingsensor}
DEVICENAME {Kat.A}
DEVICENAME {Kat.A, pingsensor} DEVICENAME {Kat.D}
DEVICENAME {Kat.D, pingsensor} DEVICENAME {Kat.B}
In this case, I want the other way around. I want to use -notlike to get all object, which doesn't have a "Kat.A, Kat.B, Kat.C or Kat.B" Tag. So I changed the code to:
Get-Sensor -Name Ping | where {$_.Tags -notlike "Kat.A" -or $_.Tags -notlike "Kat.B" -or $_.Tags -notlike "Kat.C" -or $_.Tags -notlike "Kat.D"} | Select-Object Device, Tags
But here is problem, that I get more values than needed:
DEVICENAME {Kat.D, test}
DEVICENAME {Kat.C, sql}
DEVICENAME {Kat.D, domaincontroller}
DEVICENAME {pingsensor, memberserver}
DEVICENAME {pingsensor, memberserver}
DEVICENAME {pingsensor, memberserver}
DEVICENAME {pingsensor, memberserver}
DEVICENAME {Kat.C}
I only need those four devices/tags which starts with pingsensor, because they don't contain a Kat.
Thank you for your upcoming help guys.
Best regards :)
If this works:
and you want to negate it, enclose the expression in
(...)and prepend-not:However, since you're not using actual wildcard characters in your comparison patterns, there is no need for
-like-just use-eq- or, preferably, given that$_.Tagsseems to contain an array of values, use the-containsoperatorNote, however, that if wildcard matching were truly needed,
-containswouldn't work.Note:
Switching from
... -like ... -or ...to... -notlike ... -and ...(analogously for-eqand-ne) is not the equivalent negation if the LHS operands are arrays, which seems to be the case for you.The reason is that PowerShell's comparison operators act as filters with array-valued (list-like) LHS operands:
That is, with an array as the LHS, they return the sub-array of matching items rather than a Boolean (
$trueor$false).Using an array as if it were a Boolean - which PowerShell lets you do implicitly, because it can quietly coerce any data type to a Boolean[1] - can have surprising results - see the example below.
Somewhat counterintuitively, this outputs
yestwice.That is, the results of the array-filtering operations, when interpreted as Booleans, were both true, because in effect the two
ifconditionals were equivalent to:[bool] @('Kat.A')->$true[bool] @('Kat.B')-> also$trueBy contrast, the containment operators,
-containsand its operands-reversed counterpart,-in, whose very purpose is to operate on arrays (list-like collections), always return a Boolean ($trueor$false), so it is possible to properly negate... -contains ... -or ...as... -notcontains ... -and ...[1] See the bottom section of this answer for a summary of the to-Boolean conversion rules.