Skip to content

Commit

Permalink
Preview (#63)
Browse files Browse the repository at this point in the history
* Fixed bug for instances where .principal prop didn't exist

* Fixed issue with incorrect variable name for $InputObject

* Role-assignments (#62)

* update role assignment collection logic

* Update pbit to match pwsh output

* Fix module version check

* Fix bug on tenants with no P2 licenses

* Fix warning on tenants with no AAD licenses

* Remove resource not found warnings

* Remove auth method registration warning

* Remove posh test gallery from cd pipeline

Co-authored-by: Merill Fernando <[email protected]>
  • Loading branch information
jazuntee and merill authored Aug 15, 2022
1 parent bd6b3d3 commit 444dc53
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 144 deletions.
26 changes: 26 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit <https://cla.opensource.microsoft.com>.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [[email protected]](mailto:[email protected]) with any additional questions or comments.

<!-- ## Build -->

<!-- ## Test -->

## Power BI Template Updates

Updating the Power BI Template files (.pbit) can be tricky and must align with changes to the PowerShell data collection process. Power BI also has a [Data Privacy Firewall](https://docs.microsoft.com/en-us/power-query/dataprivacyfirewall) which prevents accidental data leakage between data sources. This firewall can sometimes prevent our assessment templates from loading when a query combines or joins data from multiple files, for example, oauth2PermissionGrants.csv + servicePrincipals.json. In our case, all the data sources have the same privacy level which should allow them to be combined but Power BI may still prevent loading with the following error:
Query 'Query1' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.

One option to avoid this error is to turn off the Data Privacy Firewall by setting [Power BI Desktop privacy level](https://docs.microsoft.com/en-us/power-bi/enterprise/desktop-privacy-levels) to "Ignore the Privacy levels" when the template fails to load the data.

However, in order to avoid changing this setting whenever the template is instantiated, we can "rebuild this data combination" to avoid the firewall restrictions by introducing a proxy [function](https://docs.microsoft.com/en-us/power-query/custom-function) for each data sources used in the combination query. You can see some examples of this in the existing templates where queries will reference f_oauth2PermissionGrants() and f_servicePrincipals() which are proxy functions for the oauth2PermissionGrants and servicePrincipal data source tables rather than referencing those tables directly.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,5 @@ provided by the bot. You will only need to do this once across all repos using o
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [[email protected]](mailto:[email protected]) with any additional questions or comments.

For more detailed guidance and recommendations for contributing, see the page for [contributing](CONTRIBUTING.md).
Binary file modified assets/AzureADAssessment-ConditionalAccess.pbit
Binary file not shown.
Binary file modified assets/AzureADAssessment.pbit
Binary file not shown.
72 changes: 36 additions & 36 deletions build/azure-pipelines/azure-pipelines-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,43 +119,43 @@ stages:
moduleName: '$(moduleName)'
moduleVersion: '$(moduleVersion)'

- stage: DeployTest
displayName: 'Deploy Test'
dependsOn:
- Build
jobs:
- job: Prepare
variables:
skipComponentGovernanceDetection: true
steps:
- download: current
artifact: '$(artifactModuleSigned)'
- task: PowerShell@2
name: ModuleInfo
displayName: 'Get PowerShell Module Information'
inputs:
filePath: '$(System.DefaultWorkingDirectory)/build/Get-PSModuleInfo.ps1'
arguments: '-ModuleManifestPath "$(Pipeline.Workspace)/$(artifactModuleSigned)/*/*.psd1"'
pwsh: true
# - stage: DeployTest
# displayName: 'Deploy Test'
# dependsOn:
# - Build
# jobs:
# - job: Prepare
# variables:
# skipComponentGovernanceDetection: true
# steps:
# - download: current
# artifact: '$(artifactModuleSigned)'
# - task: PowerShell@2
# name: ModuleInfo
# displayName: 'Get PowerShell Module Information'
# inputs:
# filePath: '$(System.DefaultWorkingDirectory)/build/Get-PSModuleInfo.ps1'
# arguments: '-ModuleManifestPath "$(Pipeline.Workspace)/$(artifactModuleSigned)/*/*.psd1"'
# pwsh: true

- deployment: Publish
environment: Test
dependsOn: Prepare
variables:
moduleName: '$[ dependencies.Prepare.outputs[''ModuleInfo.moduleName''] ]'
moduleVersion: '$[ dependencies.Prepare.outputs[''ModuleInfo.moduleVersion''] ]'
strategy:
runOnce:
deploy:
steps:
- template: template-psmodule-publish.yml
parameters:
moduleName: '$(moduleName)'
RepositorySourceLocation: 'https://www.poshtestgallery.com/api/v2'
NuGetApiKeyAzureConnection: 'GTP - Architecture (980e0e9f-178a-4c38-9372-f17806c6b944)'
NuGetApiKeyVaultName: 'codesign-kv'
NuGetApiKeySecretName: 'PSTestGallery-API-Key'
Unlist: true
# - deployment: Publish
# environment: Test
# dependsOn: Prepare
# variables:
# moduleName: '$[ dependencies.Prepare.outputs[''ModuleInfo.moduleName''] ]'
# moduleVersion: '$[ dependencies.Prepare.outputs[''ModuleInfo.moduleVersion''] ]'
# strategy:
# runOnce:
# deploy:
# steps:
# - template: template-psmodule-publish.yml
# parameters:
# moduleName: '$(moduleName)'
# RepositorySourceLocation: 'https://www.poshtestgallery.com/api/v2'
# NuGetApiKeyAzureConnection: 'GTP - Architecture (980e0e9f-178a-4c38-9372-f17806c6b944)'
# NuGetApiKeyVaultName: 'codesign-kv'
# NuGetApiKeySecretName: 'PSTestGallery-API-Key'
# Unlist: true

- stage: Production
displayName: 'Deploy Production'
Expand Down
6 changes: 3 additions & 3 deletions src/Complete-AADAssessmentReports.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,18 @@ function Complete-AADAssessmentReports {

## Expand Data Package
Write-Progress -Id 0 -Activity 'Microsoft Azure AD Assessment Complete Reports' -Status 'Expand Data' -PercentComplete 0
#Expand-Archive $Path -DestinationPath $OutputDirectoryData -Force -ErrorAction Stop
# Remove destination before extract
if (Test-Path -Path $OutputDirectoryData) {
Remove-Item $OutputDirectoryData -Recurse -Force
}
# Extract content
#Expand-Archive $Path -DestinationPath $OutputDirectoryData -Force -ErrorAction Stop
[System.IO.Compression.ZipFile]::ExtractToDirectory($Path,$OutputDirectoryData)
$AssessmentDetail = Get-Content $AssessmentDetailPath -Raw | ConvertFrom-Json
#Check for DataFiles
$OutputDirectoryAAD = Join-Path $OutputDirectoryData 'AAD-*' -Resolve -ErrorAction Stop
[array] $DataFiles = Get-Item -Path (Join-Path $OutputDirectoryAAD "*") -Include "*Data.xml"
$SkippedReportOutput = $DataFiles -and $DataFiles.Count -eq 9
$SkippedReportOutput = $DataFiles -and $DataFiles.Count -ge 8

## Check the provided archive
$archiveState = Test-AADAssessmentPackage -Path $Path -SkippedReportOutput $SkippedReportOutput
Expand All @@ -87,7 +87,7 @@ function Complete-AADAssessmentReports {
}

# Check assessment version
$moduleVersion = $MyInvocation.MyCommand.ScriptBlock.Module.Version
$moduleVersion = $MyInvocation.MyCommand.Module.Version
[System.Version]$packageVersion = $AssessmentDetail.AssessmentVersion
if ($packageVersion.Build -eq -1) {
Write-Warning "The package was not generate with a module installed from the PowerShell Gallery"
Expand Down
17 changes: 9 additions & 8 deletions src/Export-AADAssessmentReportData.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function Export-AADAssessmentReportData {
$LookupCache.userRegistrationDetails.Clear()
}

# notificaiton emails report
# notificaiton emails report (Remove on next release)
if (!(Test-Path -Path (Join-Path $OutputDirectory "NotificationsEmailsReport.csv")) -or $Force) {
# load unique data
$OrganizationData = Get-Content -Path (Join-Path $SourceDirectory "organization.json") -Raw | ConvertFrom-Json
Expand Down Expand Up @@ -186,18 +186,19 @@ function Export-AADAssessmentReportData {
# role assignment report
if (!(Test-Path -Path (Join-Path $OutputDirectory "RoleAssignmentReport.csv")) -or $Force) {
# Set file header
Set-Content -Path (Join-Path $OutputDirectory "RoleAssignmentReport.csv") -Value "id,directoryScopeId,directoryScopeObjectId,directoryScopeDisplayName,directoryScopeType,roleDefinitionId,roleDefinitionTemplateId,roleDefinitionDisplayName,principalId,principalDisplayName,principalType,memberType,status,assignmentType,startDateTime,endDateTime"
Set-Content -Path (Join-Path $OutputDirectory "RoleAssignmentReport.csv") -Value "id,directoryScopeId,directoryScopeObjectId,directoryScopeDisplayName,directoryScopeType,roleDefinitionId,roleDefinitionTemplateId,roleDefinitionDisplayName,principalId,principalDisplayName,principalType,principalMail,principalOtherMails,memberType,assignmentType,startDateTime,endDateTime"
# load unique data
[array] $roleAssignmentSchedulesData = @()
[array] $roleEligibilitySchedulesData = @()
[array] $roleAssignmentScheduleInstancesData = @()
[array] $roleEligibilityScheduleInstancesData = @()
[array] $roleAssignmentsData = @()
if ($licenseType -eq "P2") {
$roleAssignmentSchedulesData = Import-Clixml -Path (Join-Path $SourceDirectory "roleAssignmentSchedulesData.xml")
$roleEligibilitySchedulesData = Import-Clixml -Path (Join-Path $SourceDirectory "roleEligibilitySchedulesData.xml")
$roleAssignmentScheduleInstancesData = Import-Clixml -Path (Join-Path $SourceDirectory "roleAssignmentScheduleInstancesData.xml")
$roleEligibilityScheduleInstancesData = Import-Clixml -Path (Join-Path $SourceDirectory "roleEligibilityScheduleInstancesData.xml")
} else {
$roleAssignmentsData = Import-Clixml -Path (Join-Path $SourceDirectory "roleAssignmentsData.xml")
}
# load data if cache empty
$OrganizationData = Get-Content -Path (Join-Path $SourceDirectory "organization.json") -Raw | ConvertFrom-Json
if ($LookupCache.user.Count -eq 0) {
Write-Output "Loading users in lookup cache"
Import-Clixml -Path (Join-Path $SourceDirectory "userData.xml") | Add-AadObjectToLookupCache -Type user -LookupCache $LookupCache
Expand All @@ -220,13 +221,13 @@ function Export-AADAssessmentReportData {
}

# generate the report
Get-AADAssessRoleAssignmentReport -Offline -TenantHasP2 ($licenseType -eq "P2") -RoleAssignmentsData $roleAssignmentsData -RoleAssignmentSchedulesData $roleAssignmentSchedulesData -RoleEligibilitySchedulesData $roleEligibilitySchedulesData -OrganizationData $OrganizationData -AdministrativeUnitsData $LookupCache.administrativeUnit -UsersData $LookupCache.user -GroupsData $LookupCache.group -ApplicationsData $LookupCache.application -ServicePrincipalsData $LookupCache.servicePrincipal `
Get-AADAssessRoleAssignmentReport -Offline -RoleAssignmentsData $roleAssignmentsData -RoleAssignmentScheduleInstancesData $roleAssignmentScheduleInstancesData -RoleEligibilityScheduleInstancesData $roleEligibilityScheduleInstancesData -OrganizationData $OrganizationData -AdministrativeUnitsData $LookupCache.administrativeUnit -UsersData $LookupCache.user -GroupsData $LookupCache.group -ApplicationsData $LookupCache.application -ServicePrincipalsData $LookupCache.servicePrincipal `
| Use-Progress -Activity 'Exporting RoleAssignmentReport' -Property id -PassThru -WriteSummary `
| Format-Csv `
| Export-Csv -Path (Join-Path $OutputDirectory "RoleAssignmentReport.csv") -NoTypeInformation -Append

# clear unique data
Remove-Variable roleAssignmentSchedulesData, roleEligibilitySchedulesData
Remove-Variable roleAssignmentScheduleInstancesData, roleEligibilityScheduleInstancesData
# clear cache as data is not further used by other reports
$LookupCache.group.Clear()
$LookupCache.administrativeUnit.Clear()
Expand Down
Loading

0 comments on commit 444dc53

Please sign in to comment.