diff --git a/PowerShell/ScubaGear/Modules/Orchestrator.psm1 b/PowerShell/ScubaGear/Modules/Orchestrator.psm1 index 20a599c3ba..7fa7bad1d0 100644 --- a/PowerShell/ScubaGear/Modules/Orchestrator.psm1 +++ b/PowerShell/ScubaGear/Modules/Orchestrator.psm1 @@ -550,7 +550,7 @@ function Invoke-ProviderList { $RetVal = "" switch ($Product) { "aad" { - $RetVal = Export-AADProvider | Select-Object -Last 1 + $RetVal = Export-AADProvider -M365Environment $M365Environment | Select-Object -Last 1 } "exo" { $RetVal = Export-EXOProvider | Select-Object -Last 1 diff --git a/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1 b/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1 index b789e9b18f..9dde49a287 100644 --- a/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1 +++ b/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1 @@ -14,6 +14,10 @@ function Invoke-GraphDirectly { [string] $commandlet, + [ValidateNotNullOrEmpty()] + [string] + $M365Environment, + [System.Collections.Hashtable] $queryParams ) @@ -25,6 +29,16 @@ function Invoke-GraphDirectly { Write-Error "The commandlet $commandlet can't be used with the Invoke-GraphDirectly function yet." } + if ($M365Environment -eq "gcchigh") { + $endpoint = "https://graph.microsoft.us" + $endpoint + } + elseif ($M365Environment -eq "dod") { + $endpoint = "https://dod-graph.microsoft.us" + $endpoint + } + else { + $endpoint = "https://graph.microsoft.com" + $endpoint + } + if ($queryParams) { <# If query params are passed in, we need to augment the endpoint URI to include the params. Paperwork below. @@ -41,7 +55,7 @@ function Invoke-GraphDirectly { } Write-Debug "Graph Api direct: $endpoint" - $resp = Invoke-MgGraphRequest -Uri $endpoint -UserAgent 'ScubaGear' + $resp = Invoke-MgGraphRequest -Uri $endpoint return $resp.Value } @@ -55,6 +69,13 @@ function Export-AADProvider { Internal #> + [CmdletBinding()] + param ( + [ValidateNotNullOrEmpty()] + [string] + $M365Environment + ) + Import-Module $PSScriptRoot/ProviderHelpers/CommandTracker.psm1 $Tracker = Get-CommandTracker @@ -103,10 +124,10 @@ function Export-AADProvider { # Get-PrivilegedUser provides a list of privileged users and their role assignments. Used for 2.11 and 2.12 if ($RequiredServicePlan) { # If the tenant has the premium license then we want to also include PIM Eligible role assignments - otherwise we don't to avoid an API error - $PrivilegedUsers = $Tracker.TryCommand("Get-PrivilegedUser", @{"TenantHasPremiumLicense"=$true}) + $PrivilegedUsers = $Tracker.TryCommand("Get-PrivilegedUser", @{"TenantHasPremiumLicense"=$true; "M365Environment"=$M365Environment}) } else{ - $PrivilegedUsers = $Tracker.TryCommand("Get-PrivilegedUser", @{"TenantHasPremiumLicense"=$false}) + $PrivilegedUsers = $Tracker.TryCommand("Get-PrivilegedUser", @{"TenantHasPremiumLicense"=$false; "M365Environment"=$M365Environment}) } $PrivilegedUsers = $PrivilegedUsers | ConvertTo-Json # The above Converto-Json call doesn't need to have the input wrapped in an @@ -125,10 +146,10 @@ function Export-AADProvider { # Get-PrivilegedRole provides data for 2.14 - 2.16, policies that evaluate conditions related to Azure AD PIM if ($RequiredServicePlan){ # If the tenant has the premium license then we want to also include PIM Eligible role assignments - otherwise we don't to avoid an API error - $PrivilegedRoles = $Tracker.TryCommand("Get-PrivilegedRole", @{"TenantHasPremiumLicense"=$true}) + $PrivilegedRoles = $Tracker.TryCommand("Get-PrivilegedRole", @{"TenantHasPremiumLicense"=$true; "M365Environment"=$M365Environment}) } else { - $PrivilegedRoles = $Tracker.TryCommand("Get-PrivilegedRole", @{"TenantHasPremiumLicense"=$false}) + $PrivilegedRoles = $Tracker.TryCommand("Get-PrivilegedRole", @{"TenantHasPremiumLicense"=$false; "M365Environment"=$M365Environment}) } $PrivilegedRoles = ConvertTo-Json -Depth 10 @($PrivilegedRoles) # Depth required to get policy rule object details } @@ -246,7 +267,11 @@ function Get-PrivilegedUser { param ( [ValidateNotNullOrEmpty()] [switch] - $TenantHasPremiumLicense + $TenantHasPremiumLicense, + + [ValidateNotNullOrEmpty()] + [string] + $M365Environment ) # A hashtable of privileged users @@ -305,7 +330,7 @@ function Get-PrivilegedUser { $graphArgs = @{ "commandlet" = "Get-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleInstance" "queryParams" = @{'$filter' = "groupId eq '$GroupId'"} - } + "M365Environment" = $M365Environment } $PIMGroupMembers = Invoke-GraphDirectly @graphArgs foreach ($GroupMember in $PIMGroupMembers) { # If the user is not a member of the PIM group (i.e. they are an owner) then skip them @@ -332,7 +357,7 @@ function Get-PrivilegedUser { # Get a list of all the users and groups that have Eligible assignments $graphArgs = @{ "commandlet" = "Get-MgBetaRoleManagementDirectoryRoleEligibilityScheduleInstance" - } + "M365Environment" = $M365Environment } $AllPIMRoleAssignments = Invoke-GraphDirectly @graphArgs # Add to the list of privileged users based on Eligible assignments @@ -389,7 +414,7 @@ function Get-PrivilegedUser { $graphArgs = @{ "commandlet" = "Get-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleInstance" "queryParams" = @{'$filter' = "groupId eq '$UserObjectId'"} - } + "M365Environment" = $M365Environment} $PIMGroupMembers = Invoke-GraphDirectly @graphArgs foreach ($GroupMember in $PIMGroupMembers) { # If the user is not a member of the PIM group (i.e. they are an owner) then skip them @@ -453,14 +478,18 @@ function GetConfigurationsForPimGroups{ [ValidateNotNullOrEmpty()] [array] - $AllRoleAssignments + $AllRoleAssignments, + + [ValidateNotNullOrEmpty()] + [string] + $M365Environment ) # Get a list of the groups that are enrolled in PIM - we want to ignore the others $graphArgs = @{ "commandlet" = "Get-MgBetaPrivilegedAccessResource" "queryParams" = @{'$PrivilegedAccessId' = "aadGroups"} - } + "M365Environment" = $M365Environment } $PIMGroups = Invoke-GraphDirectly @graphArgs foreach ($RoleAssignment in $AllRoleAssignments){ @@ -564,7 +593,11 @@ function Get-PrivilegedRole { param ( [ValidateNotNullOrEmpty()] [switch] - $TenantHasPremiumLicense + $TenantHasPremiumLicense, + + [ValidateNotNullOrEmpty()] + [string] + $M365Environment ) $PrivilegedRoles = [ScubaConfig]::ScubaDefault('DefaultPrivilegedRoles') @@ -580,14 +613,14 @@ function Get-PrivilegedRole { # Get ALL the roles and users actively assigned to them $graphArgs = @{ "commandlet" = "Get-MgBetaRoleManagementDirectoryRoleAssignmentScheduleInstance" - } + "M365Environment" = $M365Environment } $AllRoleAssignments = Invoke-GraphDirectly @graphArgs # Each of the helper functions below add configuration settings (aka rules) to the role hashtable. # Get the PIM configurations for the roles GetConfigurationsForRoles -PrivilegedRoleHashtable $PrivilegedRoleHashtable -AllRoleAssignments $AllRoleAssignments # Get the PIM configurations for the groups - GetConfigurationsForPimGroups -PrivilegedRoleHashtable $PrivilegedRoleHashtable -AllRoleAssignments $AllRoleAssignments + GetConfigurationsForPimGroups -PrivilegedRoleHashtable $PrivilegedRoleHashtable -AllRoleAssignments $AllRoleAssignments -M365Environment $M365Environment } # Return the hashtable diff --git a/PowerShell/ScubaGear/Modules/Support/Support.psm1 b/PowerShell/ScubaGear/Modules/Support/Support.psm1 index eafb93fef6..3fb4bda67d 100644 --- a/PowerShell/ScubaGear/Modules/Support/Support.psm1 +++ b/PowerShell/ScubaGear/Modules/Support/Support.psm1 @@ -115,6 +115,13 @@ function Initialize-SCuBA { $Stopwatch = [System.Diagnostics.Stopwatch]::StartNew() # Need to determine where module is so we can get required versions info + $ParentPath = Split-Path -parent $PSScriptRoot + $ModulePath = Split-Path -parent $ParentPath + # Removing the import below causes issues with testing, let it be. + # Import module magic may be helping by: + # * restricting the import so only that only function is exported + # * imported function takes precedence over imported modules w/ function + Import-Module $ModulePath -Function Initialize-Scuba $ModuleParentDir = Split-Path -Path (Get-Module ScubaGear).Path -Parent try { ($RequiredModulesPath = Join-Path -Path $ModuleParentDir -ChildPath 'RequiredVersions.ps1') *> $null diff --git a/Testing/Functional/Products/Products.Tests.ps1 b/Testing/Functional/Products/Products.Tests.ps1 index b457e8caab..b5d64bbadc 100644 --- a/Testing/Functional/Products/Products.Tests.ps1 +++ b/Testing/Functional/Products/Products.Tests.ps1 @@ -105,7 +105,6 @@ Import-Module $ConnectionModule Import-Module Selenium BeforeDiscovery{ - if ($Variant) { $TestPlanFileName = "TestPlans/$ProductName.$Variant.testplan.yaml" }