StraussKrone
StraussKrone

Reputation: 1

Delete personal contacts (stored) in an ExchangeOnline Mailbox using Powershell-Graph-API

until recently i used the following script (slightly modified...) to simply delete all contacts (...not just duplicates) in EXO mailboxes:

graph-Remove-Duplicate-Contacts.ps1

I am at a loss, because I fail to find the reason why.

I get tho following error:

Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.
At C:\...\bin\graph-Delete\POC-graph-DeleteExistingContacts.ps1:136 char:33 
+ ... eRequest = (Invoke-RestMethod -Headers @{Authorization = "Bearer $($T ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

I see error 401, which makes no sense, since i use a similar script to populate mailboxes with contacts (using same App registration and all).

If you also can not figure out the reason why or how this can be fixed, do you know any other methods to achieve the goal of clearing all personal contacts of a mailbox? (Where it is possible to do that automaticaly and unsupervised)

Thanks in advance

I checked

I expect that all contacts within the Mailbox (UPN:\Contacts) will be deleted.

Upvotes: 0

Views: 91

Answers (1)

Glen Scales
Glen Scales

Reputation: 22032

From the error your getting it look like this line if failing

$NextPageRequest = (Invoke-RestMethod -Headers @{Authorization = "Bearer $($Token)" } -Uri $NextPageURI -Method Get)

Mostly likely I would say that $NextPageURI is invalid but you don't do any error processing in your script so it could be the App itself isn't working at all and the token you sending is blank. If you can run the script through fiddler and look at the actual request that is being sent, this allows you to see the full error message as there are some extra details you might be getting with the 401.

other things to check

  • Is the Mailbox on Litigation hold
  • The access token your using has expired (doesn't look to be the case from the code but maybe in context)
  • Mailbox is over one of quota
  • Check the actually permission in the token being returned using jwt.io

Your script doesn't do an error handling so if it fails to delete one contact it fails the whole process. I would start with a simple try catch around your delete requests to see if it just a particular contact or all contacts it cant delete. While rare these days you can get corrupt items in a mailbox and the Graph isn't always able to return good errors in these type of edge cases.

You could look to use the PowerShell Graph SDK, some advantages of this is it will handle Token expiration and renewal and it will also do retries and handling throttling and will parse the Graph requests for you. eg a simple find and delete one contact example using client credentials

# Define the Application (Client) ID and Secret
$ApplicationClientId = '12928ba2-2b75-4d04-9916-xxxxxxxxxx' # Application (Client) ID
$ApplicationClientSecret = 'gxxxxQ' # Application Secret Value
$TenantId = '1c3a18bf-da31-4f6c-a404-xxxxxxxx' # Tenant ID

# Convert the Client Secret to a Secure String
$SecureClientSecret = ConvertTo-SecureString -String $ApplicationClientSecret -AsPlainText -Force

# Create a PSCredential Object Using the Client ID and Secure Client Secret
$ClientSecretCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ApplicationClientId, $SecureClientSecret
# Connect to Microsoft Graph Using the Tenant ID and Client Secret Credential
Connect-MgGraph -TenantId $TenantId -ClientSecretCredential $ClientSecretCredential

$ContactEmail = "[email protected]"
$Mailboxname = "[email protected]"

$Contacts = Get-mgusercontact -userid $Mailboxname -Filter "emailAddresses/any(a:a/address eq '$ContactEmail')"

foreach($contact in $Contacts){
    Write-host ("Deleting Contact " + $contact.DisplayName)
    Remove-MgUserContact -Userid $Mailboxname -contactid $contact.id
}

Upvotes: 0

Related Questions