Last active
July 14, 2020 17:46
-
-
Save ciphertxt/277b03b9a6137d4d4618184dbd4c3991 to your computer and use it in GitHub Desktop.
Enumerates resources in a subscription and finds diagnostic settings for resources that support them
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$currentContext = Get-AzContext | |
$currentSub = $(Get-AzContext).Subscription.Name | |
$token = $currentContext.TokenCache.ReadItems() | Where-Object {$_.tenantid -eq $currentContext.Tenant.Id} | |
$GetScanDetails = @{ | |
Headers = @{ | |
Authorization = "Bearer $($token.AccessToken)" | |
'Content-Type' = 'application/json' | |
} | |
Method = 'Get' | |
UseBasicParsing = $true | |
} | |
# Get unique resources in subscription | |
$uniqueResources = Get-AzResource | Sort-Object ResourceType -Unique | |
# Enumerate each resource | |
foreach ($resource in $uniqueResources) { | |
Write-Output "ResourceId: $($resource.ResourceId)" | |
$resourceIdSplit = $resource.ResourceId.Split("/") | |
# Determine the resource provider for the current resource | |
$resourceProvider = $resource.ResourceType.ToString().Split("/")[0] | |
Write-Output "ResourceProvider: $resourceProvider" | |
$rp = (Get-AzResourceProvider -ProviderNamespace $resourceProvider) | |
# Retrieve the resource types supported by the resource provider | |
$rpTypes = $rp.ResourceTypes | |
# Resource providers have many resource types. | |
# Based on the current resource ID, drop the resource type and resource name (we'll append the other resource types we find later) | |
$strToReplace = $resourceIdSplit[$resourceIdSplit.Count - 2] + "/" + $resource.Name | |
# Enumerate each resource type in the resource provider | |
Write-Host "Evaluating resource types..." | |
foreach ($rpType in $rpTypes) { | |
$tempResourceId = "" | |
# Build a string for a unique resource ID for each resource type found in the resource provider | |
if ($rpType.ResourceTypeName -like "*/*") { | |
$tempResourceId = $resource.ResourceId.Replace($strToReplace, "") | |
$rpTypeSplit = $rpType.ResourceTypeName.Split("/") | |
for ($i = 0; $i -lt $rpTypeSplit.Count; $i++) { | |
if ($i -eq ($rpTypeSplit.Count - 1)) { | |
$tempResourceId = $tempResourceId + $resource.Name + "/" + $rpTypeSplit[$i] | |
} else { | |
$tempResourceId = $tempResourceId + $rpTypeSplit[$i] + "/" | |
} | |
} | |
} else { | |
$tempResourceId = $resource.ResourceId.Replace($strToReplace, $rpType.ResourceTypeName + "/" + $resource.Name) | |
} | |
# Build a string to perform an HTTP get against the management API using the latest API version for the current resource type | |
$getResourceUri = "https://management.azure.com$($tempResourceId)?api-version=$($rpType.ApiVersions[0])" | |
Write-Host "`tChecking $($getResourceUri)" | |
try { | |
$getResourceStatus = Invoke-WebRequest -Uri $getResourceUri @GetScanDetails | |
if ($getResourceStatus.StatusCode -eq 200) { | |
# valid response - parse the resource ID | |
# all these gets return different schema as it is not standard across RPs :( | |
if (($getResourceStatus.Content.Length -gt 0) -and ($getResourceStatus.Content -like "*""id"":*")) { | |
$idStartString = $getResourceStatus.Content.Substring($getResourceStatus.Content.IndexOf("""id"":")) | |
$idString = $idStartString.Substring(0, $idStartString.IndexOf(",")).Replace("""id"":", "").Replace("""", "").Trim() | |
# Some RPs return the ID field for non-Azure resources so we'll do a quick check to see if string the string has "subscriptions" in it | |
if ($idString -like "*/subscriptions/*") { | |
# Check for diagnostics settings | |
$getDiagUri = "https://management.azure.com$($idString)/providers/microsoft.insights/diagnosticSettingsCategories/?api-version=2017-05-01-preview" | |
Write-Host "`t`tChecking $($getDiagUri)" | |
try { | |
$getDiagStatus = Invoke-WebRequest -Uri $getDiagUri @GetScanDetails | |
if ($getDiagStatus.StatusCode -eq 200) { | |
$Invalid = $False | |
} | |
} catch { | |
# Uncomment below to see actual error. Certain resources are not ResourceTypes that can support Logs and Metrics so the host error is being muted | |
#write-host $Error[0] -ForegroundColor Red | |
$Invalid = $True | |
$Logs = $False | |
$Metrics = $False | |
$ResponseJSON = "" | |
} | |
if (!($Invalid)) { | |
$responseDiagJson = $getDiagStatus.Content | ConvertFrom-Json -ErrorAction SilentlyContinue | |
} | |
If ($responseDiagJson) { | |
foreach ($value in $responseDiagJson.value) { | |
# Throw the response back | |
$value | |
} | |
} | |
} | |
} | |
} | |
} catch { | |
# resource has no properties or the call 404'd | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment