Skip to content

Commit

Permalink
Merge branch 'main' into improve-excel-recommendation-sheet
Browse files Browse the repository at this point in the history
  • Loading branch information
tksh164 authored Jul 16, 2024
2 parents 7cef7f4 + 22f5ea3 commit 8409be7
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 80 deletions.
9 changes: 5 additions & 4 deletions docs/content/tools/script-overviews/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,12 @@ The Collector PowerShell script is the first script to be run in the Azure Proac

- Parameters include:
- **TenantID**: *Optional* ; tenant to be used.
- **SubscriptionIds**: *Required (or ConfigFile)* ; Specifies Subscription(s) to be included in the analysis: /subscriptions/YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY,/subscriptions/AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA.
- **SubscriptionIds**: *Optional if ResourceGroup(s) are provided or a ConfigFile is used* ; Specifies Subscription(s) to be included in the analysis: "/subscriptions/YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY","/subscriptions/AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA".
- **RunbookFile**: *Optional* ; specifies the file with the runbook (selectors & checks) to be used.
- **ResourceGroups**: *Optional* ; specifies Resource Group(s) to be included in the analysis: /subscriptions/YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY/resourceGroups/ResourceGroup1,/subscriptions/YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY/resourceGroups/ResourceGroup2.
- **Tags**: *Optional* ; specifies tags to be used for filtering the resources: TagName1||TagName2||TagNameN==TagValue1||TagValue2, TagName1==TagValue1.
- **ResourceGroups**: *Optional if subscription(s) are provided or a ConfigFile is used* ; specifies Resource Group(s) to be included in the analysis: "/subscriptions/YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY/resourceGroups/ResourceGroup1","/subscriptions/YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY/resourceGroups/ResourceGroup2".
- **Tags**: *Optional* ; specifies tags to be used for filtering the resources: "TagName1==TagValue1","TagName2==TagValue2"
- **ConfigFile**: *Optional* ; specifies a file for advanced filtering, including: subscription, resourceGroup, resourceId, Tags.
- See ConfigFile.Example [here](../../../../tools/configfile.example)
- **AzureEnvironment**: *Optional* ; specifies the Azure Environment to used for the analysis: AzureCloud, AzureUSGovernment.
- **SAP**: *Optional* ; used for specialized workload analysis.
- **AVD**: *Optional* ; used for specialized workload analysis.
Expand All @@ -108,7 +109,7 @@ The Collector PowerShell script is the first script to be run in the Azure Proac
- **Debugging**: *Optional* ; Writes Debugging information of the script during the execution.
{{< figure src="../../img/tools/collector-8.png" width="100%" >}}

1. Authenticate with the account that has Reader permissions to the target subscription(s)
2. Authenticate with the account that has Reader permissions to the target subscription(s)
{{< figure src="../../img/tools/collector-9.png" width="40%" >}}

1. After script completes, the results will be saved to the same folder location.
Expand Down
Binary file modified docs/static/img/tools/collector-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/static/img/tools/collector-8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
122 changes: 47 additions & 75 deletions tools/1_wara_collector.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,6 @@ $Script:Runtime = Measure-Command -Expression {
[string]$query = 'Resources | project id, resourceGroup, subscriptionId, name, type, location'
)

if ($Debugging) {
Write-Host
Write-Host "[-Debugging]: Running resource graph query..." -ForegroundColor Magenta
Write-Host
Write-Host "$query" -ForegroundColor Magenta
Write-Host
}

$result = $subscriptionId ? (Search-AzGraph -Query $query -first 1000 -Subscription $subscriptionId) : (Search-AzGraph -Query $query -first 1000 -usetenantscope) # -first 1000 returns the first 1000 results and subsequently reduces the amount of queries required to get data.

# Collection to store all resources
Expand Down Expand Up @@ -277,11 +269,6 @@ $Script:Runtime = Measure-Command -Expression {
$IsValid = $false
}

if (!($SubscriptionIds) -and !($ConfigFile)) {
Write-Host "Subscription ID(s) (-SubscriptionIds) or configuration file (-ConfigFile) is required when not using a runbook file (-RunbookFile)." -ForegroundColor Red
$IsValid = $false
}

if ($ConfigFile -and !(Test-Path $ConfigFile -PathType Leaf)) {
Write-Host "Configuration file (-ConfigFile) not found: [$ConfigFile]" -ForegroundColor Red
$IsValid = $false
Expand Down Expand Up @@ -571,6 +558,10 @@ $Script:Runtime = Measure-Command -Expression {
$ScopeQuery = "resources | where id =~ '$ScopeWithoutParameter' | project id, resourceGroup, subscriptionId, name, type, location"
}
#Filter out the Supported Types
if($Debugging.IsPresent)
{
Write-Host $ScopeQuery -ForegroundColor Cyan
}
$ScopeResources = Get-AllAzGraphResource -query $ScopeQuery -subscriptionId $Subid
foreach ($Resource in $ScopeResources)
{
Expand Down Expand Up @@ -727,6 +718,11 @@ $Script:Runtime = Measure-Command -Expression {
function Invoke-QueryExecution {
param($type, $Subscription, $query, $checkId, $checkName, $selector, $validationAction)

if ($Debugging.IsPresent)
{
Write-Host $query -ForegroundColor Yellow
}

try {
$ResourceType = $Script:AllResourceTypes | Where-Object { $_.Name -eq $type}
if (![string]::IsNullOrEmpty($resourceType)) {
Expand Down Expand Up @@ -783,6 +779,7 @@ $Script:Runtime = Measure-Command -Expression {
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Low')]
param($Scope)

$TempResult = @()
if ($PSCmdlet.ShouldProcess('')) {
$Scope = $Scope.split(" -")[0]

Expand Down Expand Up @@ -1067,16 +1064,25 @@ $Script:Runtime = Measure-Command -Expression {
if ($query -match 'development') {
Write-Host "Query $checkId under development - Validate Recommendation manually" -ForegroundColor Yellow
$query = "resources | where type =~ '$type' | project name,id"
$Script:results += Invoke-QueryExecution -type $type -Subscription $Subid -query $query -checkId $checkId -checkName $checkName -selector $selector -validationAction 'IMPORTANT - Query under development - Validate Resources manually'
$TempResult += Invoke-QueryExecution -type $type -Subscription $Subid -query $query -checkId $checkId -checkName $checkName -selector $selector -validationAction 'IMPORTANT - Query under development - Validate Resources manually'
} elseif ($query -match 'cannot-be-validated-with-arg') {
Write-Host "IMPORTANT - Recommendation $checkId cannot be validated with ARGs - Validate Resources manually" -ForegroundColor Yellow
$query = "resources | where type =~ '$type' | project name,id"
$Script:results += Invoke-QueryExecution -type $type -Subscription $Subid -query $query -checkId $checkId -checkName $checkName -selector $selector -validationAction 'IMPORTANT - Recommendation cannot be validated with ARGs - Validate Resources manually'
$TempResult += Invoke-QueryExecution -type $type -Subscription $Subid -query $query -checkId $checkId -checkName $checkName -selector $selector -validationAction 'IMPORTANT - Recommendation cannot be validated with ARGs - Validate Resources manually'
} else {
$Script:results += Invoke-QueryExecution -type $type -Subscription $Subid -query $query -checkId $checkId -checkName $checkName -selector $selector -validationAction 'APRL - Queries'
$TempResult += Invoke-QueryExecution -type $type -Subscription $Subid -query $query -checkId $checkId -checkName $checkName -selector $selector -validationAction 'APRL - Queries'
}
}

if (![string]::IsNullOrEmpty($ResourceGroup))
{
$script:results += Get-ResourceGroupsByList -ObjectList $TempResult -FilterList $ResourceGroups -KeyColumn "id"
}
else
{
$script:results += $TempResult
}

# Unless we're using a runbook...
if (!($Script:RunbookChecks -and $Script:RunbookChecks.Count -gt 0)) {
# Store all resourcetypes not in APRL
Expand Down Expand Up @@ -1131,28 +1137,8 @@ $Script:Runtime = Measure-Command -Expression {
checkName = $Temp.checkName
selector = $Temp.selector
}
$result
} else {
$TempDetails = ($Script:AllResources | Where-Object { $_.id -eq $Temp.id } | Select-Object -First 1)
$result = [PSCustomObject]@{
validationAction = $Temp.validationAction
recommendationId = $Temp.recommendationId
name = $Temp.name
id = $Temp.id
location = $TempDetails.location
subscriptionId = $TempDetails.subscriptionId
resourceGroup = $TempDetails.resourceGroup
param1 = $Temp.param1
param2 = $Temp.param2
param3 = $Temp.param3
param4 = $Temp.param4
param5 = $Temp.param5
checkName = $Temp.checkName
selector = $Temp.selector
tagged = $false
}
$result
}
}
$result
}

$Script:OutOfScope += foreach ($ResIID in $Script:PreOutOfScopeResources)
Expand Down Expand Up @@ -1207,10 +1193,10 @@ $Script:Runtime = Measure-Command -Expression {
function Invoke-AdvisoryExtraction {
Param($Subid,$ResourceGroup)
if (![string]::IsNullOrEmpty($ResourceGroup)) {
$advquery = "advisorresources | where type == 'microsoft.advisor/recommendations' and tostring(properties.category) in ('HighAvailability','Performance','OperationalExcellence') | where resourceGroup =~ '$ResourceGroup' | order by id"
$advquery = "advisorresources | where type == 'microsoft.advisor/recommendations' and tostring(properties.category) in ('HighAvailability') | where resourceGroup =~ '$ResourceGroup' | order by id"
$queryResults = Get-AllAzGraphResource -Query $advquery -subscriptionId $Subid
} else {
$advquery = "advisorresources | where type == 'microsoft.advisor/recommendations' and tostring(properties.category) in ('HighAvailability','Performance','OperationalExcellence') | order by id"
$advquery = "advisorresources | where type == 'microsoft.advisor/recommendations' and tostring(properties.category) in ('HighAvailability') | order by id"
$queryResults = Get-AllAzGraphResource -Query $advquery -subscriptionId $Subid
}

Expand Down Expand Up @@ -1319,25 +1305,14 @@ $Script:Runtime = Measure-Command -Expression {
param()

if ($PSCmdlet.ShouldProcess('')) {
<# if($ResourceGroupFile){
$ResourceExporter = @{
Resource = $(Get-ResourceGroupsByList -ObjectList $Script:results -FilterList $resourcegrouplist -KeyColumn "id")
}
else{
$ResourceExporter = @{
Resource = $Script:results
}
} #>
Write-Host $ResourceGroups -ForegroundColor Yellow

#Ternary Expression If ResourceGroupFile is present, then get the ResourceGroups by List, else get the results
$ResourceExporter = @{
ImpactedResources = $ResourceGroupList ? $(Get-ResourceGroupsByList -ObjectList $Script:ImpactedResources -FilterList $resourcegrouplist -KeyColumn "id") : $Script:ImpactedResources
ImpactedResources = $Script:ImpactedResources
}
$OutOfScopeExporter = @{
OutOfScope = $Script:OutOfScope
}

$ResourceTypeExporter = @{
ResourceType = $Script:AllResourceTypesOrdered
}
Expand Down Expand Up @@ -1402,16 +1377,10 @@ $Script:Runtime = Measure-Command -Expression {


#Call the functions
$Script:Version = '2.0.13'
$Script:Version = '2.0.14'
Write-Host 'Version: ' -NoNewline
Write-Host $Script:Version -ForegroundColor DarkBlue

if ($SAP.IsPresent) {
Write-Host "We caught it here..."
Get-Help -Name "./1_wara_collector.ps1" -Detailed
Exit
}

Write-Debug "Checking parameters..."

if (!(Test-ScriptParameters)) {
Expand All @@ -1429,29 +1398,32 @@ $Script:Runtime = Measure-Command -Expression {
$locations = $ConfigData.locations
$RunbookFile = $ConfigData.RunbookFile
$Tags = $ConfigData.Tags
$ResourceGroups = $ConfigData.ResourceGroups
}
else {
$Scopes = @()
if ($ResourceGroups)
if ($SubscriptionIds)
{
$Scopes += foreach ($RG in $ResourceGroups)
{
$RG
$Scopes += foreach ($Sub in $SubscriptionIds)
{
$_guid = [Guid]::NewGuid()

if ([Guid]::TryParse($Sub, [ref]$_guid)) {
$SubId = "/subscriptions/$Sub"
Write-Host "[-SubscriptionIds]: Fixed '$Sub' >> '$SubId'" -ForegroundColor Yellow
"/subscriptions/$Sub" # Fixed!
} else {
Write-Host "[-SubscriptionIds]: $Sub" -ForegroundColor Cyan
$Sub
}
}
}
else
if ($ResourceGroups)
{
$Scopes += foreach ($Sub in $SubscriptionIds)
$Scopes += foreach ($RG in $ResourceGroups)
{
$_guid = [Guid]::NewGuid()

if ([Guid]::TryParse($Sub, [ref]$_guid)) {
$SubId = "/subscriptions/$Sub"
Write-Host "[-SubscriptionIds]: Fixed '$Sub' >> '$SubId'" -ForegroundColor Yellow
"/subscriptions/$Sub" # Fixed!
} else {
$Sub
}
Write-Host "[-ResourceGroups]: $RG" -ForegroundColor Cyan
$RG
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tools/Version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"Collector": "2.0.13",
"Collector": "2.0.14",
"Analyzer": "2.0.11",
"Generator": "2.0.5"
}
Expand Down
12 changes: 12 additions & 0 deletions tools/configfile.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[tenantid]
tenantid

[subscriptions]
/subscription/<subid>

[resourcegroups]
/subscriptions/<subid>/resourceGroups/Demo1-RG

[tags]
env==prod
application==demoapp1

0 comments on commit 8409be7

Please sign in to comment.