Solution outlined below will help with identifying resource owners for Azure resources. Frequent issue in any Azure environment is to figure out why some resource exists and who created it. Unless Azure policy was enabled to enforce tagging rules there is no built in mechanism to find this information easily.
Create Azure Functions App
Azure function is used to react to Event Grid event tied to Azure Activity Log and hence a new function app shall be created as first. Use Powershell Core as runtime stack.

The rest of Functions requirements can be left at default. Once App is created we need to assign it managed identity (either System or User assigned). Assign role of Tag Contributor to this object to Azure subscription.
If using user assigned Identity modify file profile.ps1 to replace Connect-AzAccount -Identity
with below where $userID is client ID from User Managed Identity
Connect-AzAccount -Identity -AccountId <client ID>

Create function of type Azure Event Grid Trigger

Cut and paste following code into run.ps1
param($eventGridEvent, $TriggerMetadata)
Write-Output ($eventGridEvent.data | convertto-JSON -depth 50)
$caller = "{0} ({1})" -f $eventGridEvent.data.claims.name, $eventGridEvent.data.claims."http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
if ($null -eq $eventGridEvent.data.claims.name) {
if ($eventGridEvent.data.authorization.evidence.principalType -eq "ServicePrincipal") {
$caller = (Get-AzADServicePrincipal -ObjectId $eventGridEvent.data.authorization.evidence.principalId).DisplayName
if ($null -eq $caller) {
Write-Host "MSI may not have permission to read the applications from the directory"
$caller = $eventGridEvent.data.authorization.evidence.principalId
}
}
}
Write-Host "Caller: $caller"
$resourceId = $eventGridEvent.data.resourceUri
Write-Host "ResourceId: $resourceId"
if (($null -eq $caller) -or ($null -eq $resourceId)) {
Write-Host "ResourceId or Caller is null"
exit;
}
$ignore = @("providers/Microsoft.Resources/deployments", "providers/Microsoft.Resources/tags")
foreach ($case in $ignore) {
if ($resourceId -match $case) {
Write-Host "Skipping event as resourceId contains: $case"
exit;
}
}
$tags = (Get-AzTag -ResourceId $resourceId).Properties
if (!($tags.TagsProperty.ContainsKey('Creator')) -or ($null -eq $tags)) {
$tag = @{
'Creator' = $caller
}
Update-AzTag -ResourceId $resourceId -Operation Merge -Tag $tag
Write-Host "Added creator tag with user: $caller"
}
else {
Write-Host "Tag already exists"
}
Switch to Function overview and make sure it’s enabled

Edit requirements.psd1 file in Function to import powershell modules required for function to run (Az.Resources, Az.Accounts) and restart Function App for settings to take effect.
@{
# For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'.
# To use the Az module in your function app, please uncomment the line below.
# 'Az' = '6.*'
'Az.Accounts' = '2.*'
'Az.Resources' = '4.*'
}
Event Grid setup
Event Grid facilitates tying together event of resource creation to Azure resource creation event. Navigate to Event Subscription pane and create event subscription to Azure subscription.

Azure Active Directory setup
Azure Activity Log contains UPN name of who created resources for end users in Azure Active Directory but only object ID for resources created by service principal. You have to assign Global Reader role to managed identity of Function in Azure AD to be able to convert ObjectID into service principal name.

At this point you shall be able to test functionality by creating a new resources and monitoring function execution

