Skip to content

Instantly share code, notes, and snippets.

@rcabr
Last active September 10, 2019 17:34
Show Gist options
  • Save rcabr/25df1e68c08838d698ae7bd415e70500 to your computer and use it in GitHub Desktop.
Save rcabr/25df1e68c08838d698ae7bd415e70500 to your computer and use it in GitHub Desktop.
Tag resource group creator: Automation script
<#
.Synopsis
Searches for resource groups that don't have the 'creator' tag,
searches their Activity Log history for a 'Created' event substatus,
and tags the resource group with a creator tag using the event's Caller as the tag value.
.Description
For resources created more than 90 days ago, no user information will be available.
*The Automation Connection's Service Principal needs to have read/write permissions on Resource Group resources.*
*The Automation Connection's Service Principal needs to be a 'Directory reader' in Azure AD.*
.NOTES
AUTHOR: Reuben Cabrera <reuben.cabrera@gmo.com>
LASTEDIT: 2019-09-09
Inspired by: https://gallery.technet.microsoft.com/scriptcenter/Automatically-Azure-fc5f1443
#>
Param(
[Parameter(Mandatory = $false, HelpMessage = "Names of the subscriptions to operate on. If omitted, all subscriptions will be used.")]
[String[]] $SubscriptionNames
)
$connectionName = "AzureRunAsConnection"
If (!(Get-Module AzureAD)) { Import-Module AzureAD }
If (!(Get-Module Az.Accounts)) { Import-Module Az.Accounts }
If (!(Get-Module Az.Monitor)) { Import-Module Az.Monitor }
If (!(Get-Module Az.Resources)) { Import-Module Az.Resources }
try {
# Get the connection "AzureRunAsConnection "
Write-Output "Getting Automation connection..."
$servicePrincipalConnection = Get-AutomationConnection -Name $connectionName
Write-Output "Logging in to Azure..."
Add-AzAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
Write-Output "Logging in to Azure AD..."
Connect-AzureAD `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection) {
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
}
else {
Write-Error -Message $_.Exception
throw $_.Exception
}
}
if (-not ($SubscriptionNames)) {
Write-Warning "No subscriptions specified; will operate on all subscriptions."
$SubscriptionNames = Get-AzSubscription | Select-Object -ExpandProperty Name
}
Write-Output "Subscriptions:"
$SubscriptionNames
Write-Output " "
# get all resource groups missing the "creator" tag
$resourceGroups = `
$SubscriptionNames | `
ForEach-Object {
$ctx = Set-AzContext -Subscription $_;
(Get-AzResourceGroup | Where-Object { -not ($_.Tags.creator) });
}
Write-Output "Resource Groups missing tag:"
$resourceGroups | Select-Object -ExpandProperty ResourceId
Write-Output " "
$resourceGroups | ForEach-Object {
# look at the resource group's log to identify who may have created it
$creator = Get-AzLog -ResourceId $_.ResourceId -StartTime (Get-Date).AddDays(-90) -EndTime (Get-Date) -WarningAction SilentlyContinue | `
Where-Object { $_.Caller -and ($_.Caller -ne "System") -and ($_.subStatus.value -eq "Created") } | `
Sort-Object -Property EventTimestamp | `
Select-Object -ExpandProperty Caller -First 1
if ($creator) {
if ($creator -notlike "*@*") {
# look up the service principal's name (from the object id)
try {
$servicePrincipal = Get-AzureADServicePrincipal -ObjectId $creator
if ($servicePrincipal) { $creator = $servicePrincipal.DisplayName }
}
catch { }
}
# tag the resource group
Write-Warning "Tagging Resource Group $($_.ResourceGroupName) for creator $creator"
$newTags = $_.Tags += @{ creator = $creator }
$_ | Set-AzResourceGroup -Tag $newTags
}
else {
Write-Output "No activity found for Resource Group $($_.ResourceId)"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment