0

I'm trying to build out a script that adds Exchange Online mailboxes that do not have an InPlaceHold property that matches the GUID of one of multiple Security and Compliance Retention Policies (this list needs to dynamically change as more and more employees are added, as you can only have 1000 mailboxes per policy).

However, I'm getting burned by the Where-Object statement. I've tried -notmatch, -notcontain, and -notin, and I always am returned the entire count of all the mailboxes in my $AllE3Mbxs.

$E3sNeedPolicy = $AllE3Mbxs | Where-Object {$_.InPlaceHolds -notmatch $E3PolicyGuidsClean}

I get the list of mailboxes as such:

$AllE3Mbxs = Get-EXOMailbox -PropertySets All -ResultSize Unlimited -Filter{(PersistedCapabilities -like "bpos_s_enterprise") -AND (PersistedCapabilities -notlike "bpos_s_o365pam")}

An example of the output (focusing on InPlaceHolds): InPlaceHold Property

The GUIDs from the Retention Policies as such:

$AllRetentionPolicies = Get-RetentionCompliancePolicy
$E3Policies = $AllRetentionPolicies | Where {$_.Name -like "Exchange Retention Policy*"} | Sort-Object -Property Name
$E3PolicyGuids = $E3Policies.GUID
$E3PolicyGuidsClean = @()
Foreach($GUID in $E3PolicyGuids.GUID){
    $E3PolicyGuidsClean += $GUID.Replace("-","")
}

The GUIDs are returned as such. I have to clean them up so they'll match the formatting of how the mailboxes store it.

Policy GUIDs

enter image description here

Josh B
  • 39
  • 6
  • Reg. how you obtain `$E3PolicyGuidsClean`, this process could be simplified doing: `$E3PolicyGuidsClean = $E3Policies.GUID.ForEach{ $_.ToString('N') }` then assuming `InPlaceHolds` contains an array of valid GUIDs, you would need to loop through it, right now you seem to be comparing an array against other array, instead you need to compare each element of one of those arrays against an array (hope that makes sense) – Santiago Squarzon Aug 22 '22 at 19:47
  • So, maybe this could work: `... | Where-Object { $_.InPlaceHolds.Where({ $_ -notin $E3PolicyGuidsClean }, 'First')` – Santiago Squarzon Aug 22 '22 at 19:50
  • Thank you! I'll look at cleaning that up later on. I don't understand the 'First' part of your suggestion. It's also missing a closing }, so I'm assuming that should be at the end, but I got the same result - the 1863 users that I have in my $E3sNeedPolicy array.. – Josh B Aug 22 '22 at 19:56
  • Could you add an example of how does `$AllE3Mbxs[0].InPlaceHolds` look like to your question ? by looking at the screenshot it seems it does not contain valid GUIDs – Santiago Squarzon Aug 22 '22 at 19:59
  • 1
    Added. I was trying to sanitize the GUIDs, but missed them in one of the screenshots... That might be why it doesn't look right? – Josh B Aug 22 '22 at 20:11
  • Yeah you need to trim `mbx` from the start and `:[0-9]+` from the end of those strings. That's clearly the issue – Santiago Squarzon Aug 22 '22 at 20:12
  • But shouldn't my where-object still work because I'm asking it to look inside the objects to see if that clean GUIDs match anything inside? It should be able to look between the mbx and :[0-9]? – Josh B Aug 22 '22 at 20:14
  • To be clear on the intent of your script, you're looking to find all mailboxes (contained in `$AllE3Mbxs`) where ANY of the GUIDs contained in their `.InPlaceHolds` property is not contained in the `$E3PolicyGuidsClean` right ? – Santiago Squarzon Aug 22 '22 at 20:16
  • Yup, you are correct. – Josh B Aug 22 '22 at 20:23
  • I feel this should work: `.. | Where-Object { $_.InPlaceHolds.Where({ $_ -replace '^mbx|:\d+$' -notin $E3PolicyGuidsClean }, 'First') }` (bit of guessing here) – Santiago Squarzon Aug 22 '22 at 20:30
  • Somehow the count is now 1687 out of 1863... I'm thinking I might need a foreach loop using the $E3PolicyGuidsClean comparing it against what the users have in their InPlaceHold property, as that will likely be a shorter list than the other way around..? – Josh B Aug 22 '22 at 21:44
  • No, I believe the logic you have right now is sound. If you're expecting less results than what you have right now then you need to re-look into your filtering condition. Currently the filtering condition I posted before will return __any mailbox that has at least 1 GUID in their `InPlaceHolds` that does not exist in the `$E3PolicyGuidsClean` array__ – Santiago Squarzon Aug 22 '22 at 21:48
  • I might have misunderstood your clarification request. I'm looking for mailboxes that do not have any value that is inside $E3PolicyGuidsClean. This is so that the script knows it needs to add them to a retention policy. At this time, I'm expecting the result of any filtering to be 0. If we were to flip the logic to "in" instead of "notin", I should get 1863, as all the users inside $AllE3Mbxs have been added to a retention policy, of whose GUID is inside $E3PolicyGuidsClean. – Josh B Aug 22 '22 at 21:54
  • Ok I think I understand now what you meant by your previous comment. It should be like this: `.. | Where-Object { $guids = $_.InPlaceHolds -replace '^mbx|:\d+$'; $E3PolicyGuidsClean.Where({ $_ -notin $guids }, 'First') }` though if this is what you're looking for I would use a different / more efficient code – Santiago Squarzon Aug 22 '22 at 22:01
  • Now that the userbase has changed (1866 now instead of 1863, 3 users should need to be added), it's a little easier to see results. However, using this bit of code, I'm getting the full 1866 still for some reason... – Josh B Aug 23 '22 at 12:39

0 Answers0