Michal Checinski

Delete multiple Azure Service Principals except

April 27, 2020 , posted under Azure
Delete multiple Azure Service Principals except

I wanted to delete all service principals matching a pattern. Nothing exciting and complicated right? But I wanted to exclude two service principals that matched pattern.

I will use AzPowershell module just for convenience. Of course, deleting service principals via Azure Portal is not an option.

To query all service principals we can use Get-AzADServicePrincipal. To get all service principals with name matching a pattern just use DisplayName parameter with string containing an asterix char *:

But as I said at the beginning of this post I need to exclude a few service principals that match pattern. To do that I will simply use PowerShell built-in function Where-Object. That function gets the logical statement and returns only objects that matches it:

Get-AzADServicePrincipal -DisplayName "DashboardDevInstance*" | `
Where-Object { $_.DisplayName -ne "DashboardDevInstance77" `
-and $_.DisplayName -ne "DashboardDevInstanceqa" }

But there is one downside of using Where-Object function. I can’t just pipe the output to AzPowershell function that removes service principal. The reason behind that is the following:

Remove-AzADServicePrincipal : Could not find a service principal with the name .

So apparently the Remove-AzADServicePrincipal function (which removes service principal from AAD) says that the service principal with empty name could not be removed. Maybe the error occured because of somewhat bad service principal configuration, but I don’t have time and need to investigate what is wrong as I want to delete those service principals anyways.

So I used a workaround. After using a Where-Object I used a ForEach-Object function. This function does what it says: apply operation for each object that is piped in it. After it’s name we need to put a cmdlet that will be run for each of objects. Also we have access to properties that object that comes in has. So I piped output of Where-Object to ForEach-Object function as follows:

Get-AzADServicePrincipal -DisplayName "DashboardDevInstance*" `
| Where-Object { $_.DisplayName -ne "DashboardDevInstance77" `
   -and $_.DisplayName -ne "DashboardDevInstanceqa" } `
| ForEach-Object { Remove-AzADServicePrincipal -ObjectId $_.Id -Force }

As you can see the Remove-AzADServicePrincipal gets ObjectId parameter, and Force flag. The object Id of service principal is present as a property called Id on object received from the Get-AzADServicePrincipal piped through Where-Object function. The Force flag is needed to be set, otherwise we will be asked every time if we want to delete service principal. But be careful. Before executing this mini script, just make sure that you receive all proper service principals that you want to remove. So first query for them with the second script in this post, and then check it once again. If you are sure that you want to delete all of them add the lines from the last script. There is not enough checking if you do potentially disasterous operations.