If AD user is disabled, remove their corresponding AD contact.

Good Afternoon,

I’m trying to add a section to my Active Directory off-boarding script that will remove an AD contact if they have the same name as a disabled user.

Basically, we create AD contacts for all users with their personal email addresses assigned to them. We name the contacts as follows: firstname lastname- personal. So for example: Brandon Hernandez- personal. We have an issue where we are disabling users once they have been terminated, but forgetting to delete their AD contact. So my goals is to add to my off-boarding script a way for it to check if a user is disabled and if they have a corresponding contact, and if yes to delete the contact.

Below is what I have so far:

# If AD user is disabled, delete their corresponding Contact if found.

$DisabledUsers = Get-ADUser -Filter * -SearchBase "OU=Test Disabled Users,DC=Test,DC=local" | Select-Object -ExpandProperty Name
$Contacts = Get-ADObject -LDAPFilter “objectClass=Contact” -SearchBase "OU=Test Contacts,DC=Test,DC=local" | Select-Object -ExpandProperty Name | Foreach-Object { $_ -replace '- personal', '' }

if (Compare-Object $Contacts $DisabledUsers)
{
    Get-ADObject -LDAPFilter “objectClass=Contact” -SearchBase "OU=Test Contacts,DC=Test,DC=local" | Remove-ADObject -WhatIf
}

When I run the above code, it just tries to remove all contacts found in the contacts OU.

The result for my $DisabledUsers variable:

Test User2 Brandon Smith Test Account
The result for my $Contacts variable:
ALAINA TERVALON Brandon Smith Test Account
The result when I run the above script:
What if: Performing the operation "Remove" on target "CN=ALAINA TERVALON - personal,OU=Test Contacts,DC=Test,DC=local". What if: Performing the operation "Remove" on target "CN=Brandon Smith- personal,OU=Test Contacts,DC=Test,DC=local". What if: Performing the operation "Remove" on target "CN=Test Account- personal,OU=Test Contacts,DC=Test,DC=local".
So in order to get it to do what I want, it should only be removing "Brandon Smith" and "Test Account" contacts as those have disabled users with the similar names.

I’m sure I’m over complicating things and I’m missing something simple, but I’m still relatively new to PowerShell and I’m banging my head against the wall on this one.

Thanks for any help I can get on this!

-Brandon

There are a couple of options. Personally, I prefer to collect information first to validate. Not tested, but if you get the lookup working, then you would be able to see the user and the associated Contact.

$DisabledUsers = Get-ADUser -Filter {Enabled -eq $false} -SearchBase "OU=Test Disabled Users,DC=Test,DC=local" -Properties Mail | 
                 Select-Object -Property Name,
                 Mail,
                 Enabled,
                 @{Name='Contact';Expression={Get-ADObject -Filter {(objectClass -eq 'Contact') -and (Name -eq "$_.DisplayName-personal”)} -SearchBase "OU=Test Contacts,DC=Test,DC=local" | Select-Object -ExpandProperty DistinguishedName}}

This would be null for bad lookups and have the DN for the linked contact. Then you would be able to do something like:

foreach ($contact in ($DisabledUsers | Where{$_.Contact})) {
    Remove-AdObject -Identity $contact -WhatIf
}

You could also do the collection for ALL users. Then you have enable and disabled users with associated contacts. With that, then you can get ALL contacts and compare DN’s linked with not linked to clean up all contacts (e.g. Deltas) or adjust your logic to ensure your lookups are working. It would be prudent to use a contact attribute when you create it with a unique identifier like employeeId, SID, GUID or something to make a better link than a name lookup.

Hey Rob!

Thank you so much for the response! I tried your code with my script and unfortunately it’s not working either. Here is what I’m finding:

$DisabledUsers result:

Name Mail Enabled Contact
---- ---- ------- ------
Test User2 False
Brandon Smith False
Test Account False

As you can see, it’s not populating the Contacts. So I ran the line of code by itself to get the contacts and below is the error being received:

Get-ADObject : Error parsing query: '(objectClass -eq ‘Contact’) -and (Name -eq "$.DisplayName-personal”)’ Error Message: ‘syntax error’ at position: ‘44’.
At line:1 char:1
+ Get-ADObject -Filter {(objectClass -eq ‘Contact’) -and (Name -eq "$
. …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ParserError: (:slight_smile: [Get-ADObject], ADFilterParsingException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADFilterParsingException,Microsoft.ActiveDirectory.Management.Commands.GetADObject

I’m attempting to do some research on the error above but I’m not finding why we are getting this error. Any ideas?

The Active Directory filters can be a bit finicky. I tested this code on some contacts that were named the same as the user and did a like filter that should work in your case:

$users = Get-ADUser -Filter * -Properties Name, SamAccountName, Enabled, SurName, GivenName | 
         Select-Object -Property Name,
                                 SurName,
                                 GivenName,
                                 SamAccountName,
                                 Enabled,
                                 @{Name='ContactFilter';Expression={('*{0} {1}*' -f $_.GivenName, $_.SurName)}},
                                 @{Name='Contact';Expression={$filter = ('*{0} {1}*' -f $_.GivenName, $_.SurName);Get-ADObject -Filter {(objectClass -eq 'Contact') -and (Name -like $filter)} | Select -ExpandProperty ObjectGUID}}

Hey Rob!

So I tested the code from your last response and it lists out every user in my domain with the requested properties. Below is an example:

Name : Test Account
SurName : Account
GivenName : Test
SamAccountName : taccount
Enabled : False
ContactFilter : Test Account
Contact : 1fbaa67c-14b8-4125-bd1c-424dc3b3a9bb

Below is is the full code I’m running from what you suggested:

$users = Get-ADUser -Filter * -Properties Name, SamAccountName, Enabled, SurName, GivenName | 
         Select-Object -Property Name,
                                 SurName,
                                 GivenName,
                                 SamAccountName,
                                 Enabled,
                                 @{Name='ContactFilter';Expression={('*{0} {1}*' -f $_.GivenName, $_.SurName)}},
                                 @{Name='Contact';Expression={$filter = ('*{0} {1}*' -f $_.GivenName, $_.SurName);Get-ADObject -Filter {(objectClass -eq 'Contact') -and (Name -like $filter)} | Select-Object -ExpandProperty ObjectGUID}}

foreach ($Contact in ($users | Where{$_.Contact})) {
    Remove-AdObject -Identity $Contact -WhatIf
}

After I run the above code, I’m getting multiple of the error below:

Remove-ADObject : Cannot bind parameter ‘Identity’. Cannot create object of type “Microsoft.ActiveDirectory.Management.ADObject”. The adapter cannot set the value of property “Name”.
At C:\Zthernet\ContactsTest2.ps1:11 char:31
+ Remove-AdObject -Identity $Contact -WhatIf
+ ~~~~~~~~
+ CategoryInfo : InvalidArgument: (:slight_smile: [Remove-ADObject], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.ActiveDirectory.Management.Commands.RemoveADObject

After reading the error it seems that we need to replace the Identity after Remove-ADObject, but I’m not for sure what we can replace it with. Any ideas?

(Sorry to keep bugging you about this. I feel like a complete newb!)

 

Hey Rob,

I just wanted to make sure you received my last response. Do you have any other suggestions? Any further assistance with this would be greatly appreciated.

Thanks,
Brandon