Run-ReportAzureSummary.ps1
<#PSScriptInfo
.VERSION 0.0.1.0 .GUID 4258516b-09a1-4912-b317-86178c0afcb1 .AUTHOR Matthew Quickenden .COMPANYNAME Avanade / ACE .COPYRIGHT .TAGS Report HTML Azure AD .LICENSEURI https://github.com/azurefieldnotes/Reports .PROJECTURI https://github.com/azurefieldnotes/Reports .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .DESCRIPTION A report collecting a wide range of data from Azure. This is a prototype, but also awesome. #> #REQUIRES -Version 5 -Modules @{ModuleName='Avanade.AzureAD';ModuleVersion="1.2.3"},Avanade.AzureReports using module Avanade.AzureReports [CmdletBinding(DefaultParameterSetName='ReportParameters')] param ( [Parameter(Mandatory=$false,ParameterSetName='ReportParameters')] [Parameter(Mandatory=$false,ParameterSetName='ReportParametersObject')] [string] $TenantDomain="", [Parameter(Mandatory=$false,ParameterSetName='ReportParameters')] [Parameter(Mandatory=$false,ParameterSetName='ReportParametersObject')] [string] $SubscriptionName="", [Parameter(Mandatory=$false,ParameterSetName='ReportParameters')] [string] $LeftLogo ='https://azurefieldnotesblog.blob.core.windows.net/wp-content/2017/02/YourLogoHere.png', [Parameter(Mandatory=$false,ParameterSetName='ReportParameters')] [string] $RightLogo ='https://azurefieldnotesblog.blob.core.windows.net/wp-content/2017/02/ReportHTML.png', [Parameter(Mandatory=$false,ParameterSetName='ReportParameters')] [string] $reportPath, [Parameter(Mandatory=$false,ParameterSetName='ReportParameters')] [string] $ReportName='Azure Active Directory Report', [Parameter(Mandatory=$false,ParameterSetName='ReportParameters')] [Parameter(Mandatory=$false,ParameterSetName='ReportParametersObject')] [switch] $UseExistingData=$false, [Parameter(Mandatory=$false,ParameterSetName='ReportParametersObject')] [PSObject] $ReportParameterObject ) Import-Module -Name Avanade.Azure.Models -MinimumVersion 1.0.1 -ErrorAction SilentlyContinue -ErrorVariable ErrorMsg if ($ErrorMsg) { Install-Module -Name Avanade.Azure.Models -MinimumVersion 1.0.1 -Force } Import-Module -Name Avanade.ArmTools -MinimumVersion 1.6 -ErrorAction SilentlyContinue -ErrorVariable ErrorMsg if ($ErrorMsg) { Install-Module -Name Avanade.ArmTools -MinimumVersion 1.6 -Force } Import-Module -Name Avanade.AzureAD.Graph -MinimumVersion 1.0.1 -ErrorAction SilentlyContinue -ErrorVariable ErrorMsg if ($ErrorMsg) { Install-Module -Name Avanade.AzureAD.Graph -MinimumVersion 1.0.1 -Force } Import-Module -Name Avanade.AzureAD -MinimumVersion 1.2.3 -ErrorAction SilentlyContinue -ErrorVariable ErrorMsg if ($ErrorMsg) { Install-Module -Name Avanade.AzureAD -MinimumVersion 1.2.3 -Force } Import-Module -Name Avanade.AzureReports -MinimumVersion 1.0.2 -ErrorAction SilentlyContinue -ErrorVariable ErrorMsg if ($ErrorMsg) { Install-Module -Name Avanade.AzureReports - 1.0.2 -Force } Get-InstalledScript -Name export-azurereports -MinimumVersion 1.0 -ErrorAction SilentlyContinue -ErrorVariable ErrorMsg if ($ErrorMsg) { install-script Export-AzureReports -MinimumVersion 1.0 } Import-Module -Name ReportHTML -MinimumVersion 1.3.1.1 -ErrorAction SilentlyContinue -ErrorVariable ErrorMsg if ($ErrorMsg) { Install-Module -Name ReportHTML -MinimumVersion 1.3.1.1 -Force } if (!($UseExistingData)) { if ([string]::IsNullOrEmpty($TenantDomain)) { $TenantDomain = read-host -Prompt "enter your tenant domain, eg my.domain.com" } if ([string]::IsNullOrEmpty($SubscriptionName)) { $SubscriptionName = read-host -Prompt "enter your SubscriptionName domain, eg Enterprise" } $SubscriptionFilter={$_.DisplayName -EQ $SubscriptionName} $AzureReports = Export-AzureReports -instancedata -GraphTenants $tenantDomain -TenantEvents -OAuthPermissionGrants -SubscriptionFilter $SubscriptionFilter $SubscriptionData =$AzureReports | ? {$_.SubscriptionDisplayName -eq "$SubscriptionName" } $TenantData = $AzureReports | ? {$_.ReportType -eq 'Tenant'} $AzureRates = $SubscriptionData.RateCards $RateData = $AzureRates | select MeterId ,MeterCategory,Unit, EffectiveDate ,MeterName,@{n='MeterRates';E={$_.MeterRates.replace('0=','')}} , MeterRegion,MeterSubCategory #| ? {$_.MeterRegion -ne ''} $MeterCategories = ($RateData | group MeterCategory).name $ResourceLocks = $SubscriptionData.ResourceLocks $Advisor = $SubscriptionData.AdvisorRecommendations $TagNameUsage = $SubscriptionData.TagNameUsage $EventsLog = $SubscriptionData.EventLogEntries $PolicyDefinitions = $SubscriptionData.PolicyDefinitions $PolicyAssignments = $SubscriptionData.PolicyAssignments $SubscriptionRoles= $SubscriptionData.RoleDefinitions $tenantRoles = $TenantData.Roles $groups = $TenantData.Groups $users = $TenantData.Users $RoleTemplates = $TenantData.RoleTemplates $RoleAssignments = $SubscriptionData.RoleAssignments $AuditEvents = $TenantData.AuditEvents $ComputeQuotaUsage = $SubscriptionData.ComputeQuotaUsage $StorageQuotaUsage = $SubscriptionData.StorageQuotaUsage $SigninEvents = $TenantData.SigninEvents $OauthPermissionGrants =$TenantData.OauthPermissionGrants $VMSizes = $SubscriptionData.AvailableVmSizes $UsageAggregates = $SubscriptionData.UsageAggregates } else { Write-Warning "Using Existing Data" } #region Resource Locks $tab = 'Resource Locks' $rptRL =@() $rptRL += Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptRL += Get-HTMLContentOpen -HeaderText 'Resource Lock Records' $rptRL += Get-HTMLContentTable ( $ResourceLocks | select @{n='Resource';e={("URL01NEW" + $PortalLink + $_.Id + "URL02Goto ResourceURL03")}},Name,Level,Notes) $rptRL += Get-HTMLContentClose $rptRL += Get-HTMLTabContentclose #Endregion #region AdvisorRecommendations $ImpactGroup = $Advisor | Group Impact $ImpactPie = Get-HTMLPieChartObject -ColorScheme Generated3 $ImpactPie.Size.Height =300 $CategoryGroup = $Advisor | Group Category $CategoryPie = Get-HTMLPieChartObject -ColorScheme Generated2 $CategoryPie.Size.Height =300 $ProblemGroup = $Advisor | Group Problem $ProblemPie = Get-HTMLPieChartObject -ColorScheme Generated4 $ProblemPie.Size.Height =200 $ProblemPie.ChartStyle.legendPosition ='none' $RiskGroup = $Advisor | Group Risk $RiskPie = Get-HTMLPieChartObject -ColorScheme Generated5 $RiskPie.Size.Height =200 $tab = 'Advisor' $rptAD =@() $rptAD += Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptAD += Get-HTMLContentOpen -HeaderText 'Advisor' $rptAD += Get-HTMLColumn1of2 $rptAD += Get-HTMLPieChart -ChartObject $ImpactPie -DataSet $ImpactGroup $rptAD += Get-HTMLColumnclose $rptAD += Get-HTMLColumn2of2 $rptAD += Get-HTMLPieChart -ChartObject $CategoryPie -DataSet $CategoryGroup $rptAD += Get-HTMLColumnclose $rptAD += Get-HTMLColumn1of2 $rptAD += Get-HTMLPieChart -ChartObject $ProblemPie -DataSet $ProblemGroup $rptAD += Get-HTMLColumnclose $rptAD += Get-HTMLColumn2of2 $rptAD += Get-HTMLPieChart -ChartObject $RiskPie -DataSet $RiskGroup $rptAD += Get-HTMLColumnclose $rptAD += Get-HTMLContentTable ($Advisor | select Category,Impact,ResourceType,ResourceName,Risk,Problem,` @{n='Resource';e={("URL01NEW" + $PortalLink + $_.ResourceURI + "URL02Goto ResourceURL03")}} ) -GroupBy Category $rptAD += Get-HTMLContentClose $rptAD += Get-HTMLTabContentclose #endRegion #region Event Logs $LevelGroup = $EventsLog | Group Level $LevelPie = Get-HTMLPieChartObject -ColorScheme Random $LevelPie.Size.Height =300 $EventSourceGroup = $EventsLog | Group ResourceProviderName $EventSourcePie = Get-HTMLPieChartObject -ColorScheme Generated6 $EventSourcePie.Size.Height =300 $RGGroup = $EventsLog | Group ResourceGroupName $RGPie = Get-HTMLPieChartObject -ColorScheme ColorScheme4 $RGPie.Size.Height =300 $ChannelsGroup = $EventsLog | Group Channels $ChannelsPie = Get-HTMLPieChartObject -ColorScheme Generated7 $ChannelsPie.Size.Height =300 $tab = 'Event Logs' $rptEL = @() $rptEL+= Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptEL+= Get-HTMLContentOpen -HeaderText 'Event Logs' $rptEL+= Get-HTMLColumn1of2 $rptEL+= Get-HTMLPieChart -ChartObject $LevelPie -DataSet $LevelGroup $rptEL+= Get-HTMLColumnclose $rptEL+= Get-HTMLColumn2of2 $rptEL+= Get-HTMLPieChart -ChartObject $EventSourcePie -DataSet $EventSourceGroup $rptEL+= Get-HTMLColumnclose $rptEL+= Get-HTMLColumn1of2 $rptEL+= Get-HTMLPieChart -ChartObject $RGPie -DataSet $RGGroup $rptEL+= Get-HTMLColumnclose $rptEL+= Get-HTMLColumn2of2 $rptEL+= Get-HTMLPieChart -ChartObject $ChannelsPie -DataSet $ChannelsGroup $rptEL+= Get-HTMLColumnclose $rptEL+= Get-HTMLContentOpen -HeaderText 'Events by Resource Group' -IsHidden $rptEL+= Get-HTMLContentTable ($EventsLog | select ResourceGroupName,` @{n='Resource';e={("URL01NEW" + $PortalLink + $_.ResourceURI + "URL02Goto ResourceURL03")}}, ` @{n='Event';e={("URL01NEW" + $PortalLink + $_.ID + "URL02Goto EventURL03")}}, ` ResourceProviderName,Level,OperationName) -GroupBy ResourceGroupName $rptEL+= Get-HTMLContentClose $rptEL+= Get-HTMLContentOpen -HeaderText 'Events by ResourceProviderName' -IsHidden $rptEL+= Get-HTMLContentTable ($EventsLog | select ResourceProviderName,` @{n='Resource';e={("URL01NEW" + $PortalLink + $_.ResourceURI + "URL02Goto ResourceURL03")}},` @{n='Event';e={("URL01NEW" + $PortalLink + $_.ID + "URL02Goto EventURL03")}}, ` EventSource ,ResourceGroupName,Level, OperationName) -GroupBy ResourceProviderName $rptEL+= Get-HTMLContentClose $rptEL+= Get-HTMLContentClose $rptEL+= Get-HTMLTabContentclose #Endregion #region Policy Definitions $tab = 'Policy Definitions' $rptPD = @() $rptPD+= Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptPD+= Get-HTMLContentOpen -HeaderText 'Policy Definitions' -BackgroundShade 2 $rptPD+= Get-HTMLContentOpen -HeaderText 'Policy Definitions' $rptPD+= Get-HTMLContentTable ($PolicyDefinitions | select DisplayName,Description ,PolicyType ) $rptPD+= Get-HTMLContentClose $rptPD+= Get-HTMLContentOpen -HeaderText 'Policy Assignments' $rptPD+= Get-HTMLContentTable ($PolicyAssignments | select Name,Scope) $rptPD+= Get-HTMLContentClose $rptPD+= Get-HTMLContentClose $rptPD+= Get-HTMLTabContentclose #Endregion #region RBAC $tab = 'RBAC' $rptRB = @() $rptRB += Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptRB += Get-HTMLContentOpen -HeaderText 'RBAC' -BackgroundShade 2 $rptRB += Get-HTMLContentOpen -HeaderText 'Groups' -IsHidden $rptRB += Get-HTMLContentTable ($groups | select DisplayName,ObjectType ,DirSyncEnabled,LastDirSyncTime ) $rptRB += Get-HTMLContentClose $rptRB += Get-HTMLContentOpen -HeaderText 'Users' -IsHidden $rptRB += Get-HTMLContentTable ($users | select AccountEnabled,DisplayName,ForceChangePasswordNextLogin ,DirSyncEnabled,LastDirSyncTime,UserPrincipalName,UserType) -GroupBy AccountEnabled $rptRB += Get-HTMLContentClose $rptRB += Get-HTMLContentOpen -HeaderText 'Subsciption Roles' -IsHidden $rptRB += Get-HTMLContentTable ($SubscriptionRoles | select RoleName,Description ,Type, Actions,Nonactions) $rptRB += Get-HTMLContentClose $rptRB += Get-HTMLContentOpen -HeaderText 'Tenant Roles' -IsHidden $rptRB += Get-HTMLContentTable ($TenantRoles | select DisplayName,Description ,IsSystem, ObjectType,RoleDisabled) $rptRB += Get-HTMLContentClose $rptRB += Get-HTMLContentOpen -HeaderText 'Role Templates' -IsHidden $rptRB += Get-HTMLContentTable ($RoleTemplates | select DisplayName,Description ,ObjectType,Odata.type ) $rptRB += Get-HTMLContentClose $rptRB += Get-HTMLContentOpen -HeaderText 'Role Assignments' -IsHidden $rptRB += Get-HTMLContentTable ($RoleAssignments | select Scope, RoleName ,RoleType , RoleDescription ) -GroupBy Scope $rptRB += Get-HTMLContentClose $rptRB += Get-HTMLContentClose $rptRB += Get-HTMLTabContentclose #Endregion #region Audit Events $DeviceGroup = $AuditEvents | Group ActivityType $Device = Get-HTMLpieChartObject -ColorScheme Generated7 $Device.Size.Height =300 $device.ChartStyle.legendPosition = 'bottom' $AppGroup = $AuditEvents | Group ActivityOperationType $App = Get-HTMLpieChartObject -ColorScheme Generated1 $App.Size.Height =300 $App.ChartStyle.legendPosition = 'bottom' $tab = 'Audit Events' $rptAE = @() $rptAE+= Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptAE+= Get-HTMLContentOpen -HeaderText 'Audit Events' $rptAE+= Get-HTMLColumn1of2 $rptAE+= Get-HTMLpieChart -ChartObject $Device -DataSet $DeviceGroup $rptAE+= Get-HTMLColumnclose $rptAE+= Get-HTMLColumn2of2 $rptAE+= Get-HTMLpieChart -ChartObject $App -DataSet $AppGroup $rptAE+= Get-HTMLColumnclose $rptAE+= Get-HTMLContentOpen -HeaderText 'Audit Events' $rptAE+= Get-HTMLContentTable ($AuditEvents | select ActivityDate,ActivityDateInMillis,ActivityOperationType,ActivityResultDescription,ActivityResultStatus,ActivityType,Actor,ActorType,Category,ComponentOrSource) $rptAE+= Get-HTMLContentClose $rptAE+= Get-HTMLContentClose $rptAE+= Get-HTMLTabContentclose #Endregion #region ComputeQuotaUsage $tab = 'Quota Usage' $rptQU = @() $rptQU += Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptQU+= Get-HTMLContentOpen -HeaderText 'Quota Usage' -BackgroundShade 2 $rptQU+= Get-HTMLContentOpen -HeaderText 'Storage Quota Usage' $rptQU+= Get-HTMLContentTable ($StorageQuotaUsage | select Unit,@{n='PercentUsed';e={[string]([math]::round($_.currentvalue / $_.limit * 100 )) + '%'}},CurrentValue ,Limit,Name,LocalizedName | sort -Descending) $rptQU+= Get-HTMLContentClose $rptQU+= Get-HTMLContentOpen -HeaderText 'Compute Quota Usage' $rptQU+= Get-HTMLContentTable ($ComputeQuotaUsage | where {$_.CurrentValue -ne 0} |select Unit,@{n='PercentUsed';e={([math]::round($_.currentvalue / $_.limit * 100 )) }},CurrentValue ,Limit,Name,LocalizedName ) $rptQU+= Get-HTMLContentClose $rptQU+= Get-HTMLContentOpen -HeaderText 'Compute Quota Usage (unsed)' -IsHidden $rptQU+= Get-HTMLContentTable ($ComputeQuotaUsage | where {$_.CurrentValue -eq 0} |select Unit,CurrentValue ,Limit,Name,LocalizedName | sort CurrentValue -Descending) $rptQU+= Get-HTMLContentClose $rptQU+= Get-HTMLContentClose $rptQU+= Get-HTMLTabContentclose #Endregion #region SigninEvents $DeviceGroup = $SigninEvents | Group DeviceInformation $Device = Get-HTMLpieChartObject -ColorScheme Generated2 $Device.Size.Height =300 $device.ChartStyle.legendPosition = 'none' $device.Title = 'Device Information' $AppGroup = $SigninEvents | Group AppDisplayName $App = Get-HTMLpieChartObject -ColorScheme Generated5 $App.Size.Height =300 $App.ChartStyle.legendPosition = 'none' $app.Title = 'App Name' $StatusGroup = $SigninEvents | Group LoginStatus $Status= Get-HTMLpieChartObject -ColorScheme Generated2 $Status.Size.Height =300 $Status.ChartStyle.legendPosition = 'bottom' $Status.Title = "Login Status" $UPNGroup = $SigninEvents | Group UserPrincipalName $UPN = Get-HTMLpieChartObject -ColorScheme Generated5 $UPN.Size.Height =300 $UPN.ChartStyle.legendPosition = 'none' $UPN.Title = "Sign in By User" $tab = 'Signin Events' $rptSE = @() $rptSE+= Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptSE+= Get-HTMLContentOpen -HeaderText 'Signin Events' -BackgroundShade 2 $rptSE+= Get-HTMLColumn1of2 $rptSE+= Get-HTMLpieChart -ChartObject $Device -DataSet $DeviceGroup $rptSE+= Get-HTMLColumnclose $rptSE+= Get-HTMLColumn2of2 $rptSE+= Get-HTMLpieChart -ChartObject $App -DataSet $AppGroup $rptSE+= Get-HTMLColumnclose $rptSE+= Get-HTMLColumn1of2 $rptSE+= Get-HTMLpieChart -ChartObject $Status -DataSet $StatusGroup $rptSE+= Get-HTMLColumnclose $rptSE+= Get-HTMLColumn2of2 $rptSE+= Get-HTMLpieChart -ChartObject $UPN -DataSet $UPNGroup $rptSE+= Get-HTMLColumnclose $rptSE+= Get-HTMLContentOpen -HeaderText 'Signin Events' $rptSE+= Get-HTMLContentTable ($SigninEvents | select AppDisplayName,DeviceInformation,Latitude,Longitude,IpAddress,LoginStatus,SigninDateTime,UserDisplayName,UserPrincipalName) $rptSE+= Get-HTMLContentClose $rptSE+= Get-HTMLContentClose $rptSE+= Get-HTMLTabContentclose #Endregion #region OauthPermissionGrants $tab = 'Oauth Grants' $rptOG = @() $rptOG += Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptOG += Get-HTMLContentOpen -HeaderText 'Oauth Grants' $rptOG += Get-HTMLContentTable ($OauthPermissionGrants | select ClientId,ConsentType,Principal,ExpiryTime,ObjectId,ResourceId ,PrincipalId,Scope) $rptOG += Get-HTMLContentClose $rptOG += Get-HTMLTabContentclose #Endregion #region VM Sizes $VMSizesExtra = $VMSizes | select Location,name,@{n='VM Size Group';e={$_.name.Substring(0,$_.name.IndexOf('_')+2)}},` NumberOfCores,OsDiskSizeInmb,ResourceDiskSizeInMB,MemoryInMB,MaxDataDiskCount $GroupedVMSizes = $VMSizesExtra | group location $GroupedVMSizeBase= $VMSizesExtra | group 'VM Size Group' $tab = 'VM Sizes' $rptVS = @() $rptVS += Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptVS += Get-HTMLContentOpen -HeaderText 'VM Sizes by Region' -BackgroundShade 2 -IsHidden foreach ($GroupedVMSize in $GroupedVMSizes ) { $rptVS += Get-HTMLContentOpen -HeaderText $GroupedVMSize.name -IsHidden $rptVS += Get-HTMLContentTable ($GroupedVMSize.group ) -GroupBy 'VM Size Group' #@{n='OsDiskSizeInGB';e={$_.OsDiskSizeInMB /1gb}} $rptVS += Get-HTMLContentClose } $rptVS += Get-HTMLContentClose $rptVS += Get-HTMLContentOpen -HeaderText 'VM Sizes by Base Size' -BackgroundShade 2 -IsHidden foreach ($GroupedVMSize in $GroupedVMSizeBase ) { $rptVS += Get-HTMLContentOpen -HeaderText $GroupedVMSize.name -IsHidden $rptVS += Get-HTMLContentTable ($GroupedVMSize.group | select name,Location,'NumberOfCores','OsDiskSizeInMB','ResourceDiskSizeInMB','MemoryInMB','MaxDataDiskCount' ) -GroupBy 'Name' #@{n='OsDiskSizeInGB';e={$_.OsDiskSizeInMB /1gb}} $rptVS += Get-HTMLContentClose } $rptVS += Get-HTMLContentClose $rptVS += Get-HTMLTabContentclose #Endregion #region Resource Tags $tab = 'Resource Tags' $rptRT = @() $rptRT += Get-HTMLTabContentOpen -TabName $tab -TabHeading $tab $rptRT += Get-HTMLContentOpen -HeaderText 'Resource Tag Grouping' $rptRT += Get-HTMLContentTable $TagNameUsage $rptRT += Get-HTMLContentClose $rptRT += Get-HTMLTabContentclose #Endregion $PortalLink = 'https://portal.azure.com/#resource' $colourSchemes = Get-HTMLColorSchemes $tabHeaders = @('Advisor','Resource Tags','Event Logs','Policy Definitions','RBAC','Audit Events','Signin Events','Resource Locks','Oauth Grants','Quota Usage','VM Sizes') $rpt = @() $rpt += Get-HTMLOpenPage -LeftLogoString $LeftLogo -RightLogoString $RightLogo -TitleText $ReportName $rpt += Get-HTMLTabheader $tabHeaders #audit Event $rpt += $rptAE #EventLogs $rpt += $rptEL #Policy Definition $rpt += $rptPD #Advisor $rpt += $rptAD #RBAC $rpt += $rptRL #RBAC $rpt += $rptRB #Quota Usage $rpt += $rptQU #Signin Events $rpt += $rptSE #Oauth Grants $rpt += $rptOG #VMSizes $rpt += $rptVS #REsourceTags $rpt += $rptRT $rpt += Get-HTMLClosePage Save-HTMLReport -ReportContent $rpt -ReportPath $ReportPath -ReportName $ReportName.Replace(' ','') -ShowReport |