diff --git a/PowerShell/ScubaGear/Modules/Connection/Connection.psm1 b/PowerShell/ScubaGear/Modules/Connection/Connection.psm1
index baa6c5e641..f5865bf25a 100644
--- a/PowerShell/ScubaGear/Modules/Connection/Connection.psm1
+++ b/PowerShell/ScubaGear/Modules/Connection/Connection.psm1
@@ -55,41 +55,30 @@ function Connect-Tenant {
try {
switch ($Product) {
"aad" {
- $GraphScopes = (
- 'User.Read.All',
- 'Policy.Read.All',
- 'Organization.Read.All',
- 'RoleManagement.Read.Directory',
- 'GroupMember.Read.All',
- 'Directory.Read.All',
- 'PrivilegedEligibilitySchedule.Read.AzureADGroup',
- 'PrivilegedAccess.Read.AzureADGroup',
- 'RoleManagementPolicy.Read.AzureADGroup'
- )
- $GraphParams = @{
+ $GraphScopes = Get-ScubaGearPermissions -Product "aad" -Environment $M365Environment
+
+ $GraphParams = @{
'M365Environment' = $M365Environment;
'Scopes' = $GraphScopes;
- }
- if($ServicePrincipalParams) {
- $GraphParams += @{ServicePrincipalParams = $ServicePrincipalParams}
- }
- Connect-GraphHelper @GraphParams
- $AADAuthRequired = $false
+ }
+ if($ServicePrincipalParams) {
+ $GraphParams += @{ServicePrincipalParams = $ServicePrincipalParams}
+ }
+ Connect-GraphHelper @GraphParams
+ $AADAuthRequired = $false
}
{($_ -eq "exo") -or ($_ -eq "defender")} {
if($_ -eq "defender" -and $AADAuthRequired) {
- $GraphScopes = (
- 'User.Read.All'
- )
- $GraphParams = @{
+ $GraphScopes = Get-ScubaGearPermissions -Product "defender" -Environment $M365Environment
+ $GraphParams = @{
'M365Environment' = $M365Environment;
'Scopes' = $GraphScopes;
- }
- if($ServicePrincipalParams) {
- $GraphParams += @{ServicePrincipalParams = $ServicePrincipalParams}
- }
- Connect-GraphHelper @GraphParams
- $AADAuthRequired = $false
+ }
+ if($ServicePrincipalParams) {
+ $GraphParams += @{ServicePrincipalParams = $ServicePrincipalParams}
+ }
+ Connect-GraphHelper @GraphParams
+ $AADAuthRequired = $false
}
if ($EXOAuthRequired) {
$EXOHelperParams = @{
@@ -151,35 +140,27 @@ function Connect-Tenant {
$PnPParams = @{
'ErrorAction' = 'Stop';
}
+
+ #pull api endpoint from json
+ $Url = Get-ScubaGearPermissions -Product "sharepoint" -Environment $M365Environment -Domain $InitialDomainPrefix -OutAs endpoint
+ $SPOParams += @{
+ 'Url'= $Url;
+ }
+ $PnPParams += @{
+ 'Url'= $Url;
+ }
+
+ #populate the rest of the parameters for splatting
switch ($M365Environment) {
- {($_ -eq "commercial") -or ($_ -eq "gcc")} {
- $SPOParams += @{
- 'Url'= "https://$($InitialDomainPrefix)-admin.sharepoint.com";
- }
- $PnPParams += @{
- 'Url'= "$($InitialDomainPrefix)-admin.sharepoint.com";
- }
- }
- "gcchigh" {
- $SPOParams += @{
- 'Url'= "https://$($InitialDomainPrefix)-admin.sharepoint.us";
- 'Region' = "ITAR";
- }
- $PnPParams += @{
- 'Url'= "$($InitialDomainPrefix)-admin.sharepoint.us";
- 'AzureEnvironment' = 'USGovernmentHigh'
- }
- }
- "dod" {
- $SPOParams += @{
- 'Url'= "https://$($InitialDomainPrefix)-admin.sharepoint-mil.us";
- 'Region' = "ITAR";
- }
- $PnPParams += @{
- 'Url'= "$($InitialDomainPrefix)-admin.sharepoint-mil.us";
- 'AzureEnvironment' = 'USGovernmentDoD'
- }
- }
+ "gcchigh" {
+ $SPOParams += @{'Region' = "ITAR"; }
+ $PnPParams += @{'AzureEnvironment' = 'USGovernmentHigh';}
+ }
+ "dod" {
+ $SPOParams += @{'Region' = "ITAR"; }
+ $PnPParams += @{'AzureEnvironment' = 'USGovernmentDoD';}
+ }
+
}
if ($ServicePrincipalParams.CertThumbprintParams) {
$PnPParams += @{
diff --git a/PowerShell/ScubaGear/Modules/Permissions/PermissionsHelper.psm1 b/PowerShell/ScubaGear/Modules/Permissions/PermissionsHelper.psm1
new file mode 100644
index 0000000000..a3395f0924
--- /dev/null
+++ b/PowerShell/ScubaGear/Modules/Permissions/PermissionsHelper.psm1
@@ -0,0 +1,374 @@
+Function Get-ScubaGearPermissions {
+ <#
+ .SYNOPSIS
+ This Function is used to retrieve the permissions of the SCuBAGear module
+
+ .DESCRIPTION
+ This Function is used to retrieve the permissions of the SCuBAGear module
+
+ .PARAMETER Domain
+ The domain to be used in the apiResource
+
+ .PARAMETER CmdletName
+ The name of the cmdlet for which the permissions are to be retrieved
+
+ .PARAMETER PermissionLevel
+ The level of permission to be retrieved. The possible values are 'least' and 'higher'. Default is 'least'
+
+ .PARAMETER ServicePrincipal
+ The switch to indicate that the permissions are to be retrieved for a service principal
+
+ .PARAMETER Product
+ The product for which the permissions are to be retrieved. Options are 'aad', 'exo', 'defender', 'teams', 'sharepoint'. Can be an array of products and used in pipeline
+
+ .PARAMETER Environment
+ The Environment for which the permissions are to be retrieved. Options are 'commercial', 'gcc', 'gcchigh', 'dod'. Default is 'commercial'
+
+ .PARAMETER OutAs
+ The output format. The possible values are 'perms', 'endpoint', 'modules', 'api', 'support'. Default is 'perms'
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -CmdletName Get-MgBetaDirectorySettings
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -CmdletName Get-MgBetaDirectorySettings -PermissionLevel higher
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -Product aad -OutAs all
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -CmdletName Get-MgBetaPrivilegedAccessResource -OutAs support
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -CmdletName Get-MgBetaGroupMember -OutAs api -id '559aabe6-7ef4-4fb6-b271-fa3d19e76017'
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -Product aad
+ Get-ScubaGearPermissions -Product exo
+ Get-ScubaGearPermissions -Product scubatank
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -CmdletName Get-MgBetaUser -OutAs modules
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -Product aad -OutAs modules
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -Product aad -servicePrincipal
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -Product exo -servicePrincipal
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -Product exo -OutAs appId
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -Product exo -OutAs endpoint
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -Product aad -OutAs api -id '559aabe6-7ef4-4fb6-b271-fa3d19e76017'
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -Product sharepoint -OutAs endpoint -Environment gcchigh -Domain contoso
+
+ .EXAMPLE
+ Get-ScubaGearPermissions -OutAs endpoint -Domain contoso
+
+ .EXAMPLE
+ 'teams' | Get-ScubaGearPermissions -OutAs role
+
+ .EXAMPLE
+ 'aad','scubatank' | Get-ScubaGearPermissions
+
+ .NOTES
+ NAME: Get-ScubaGearPermissions
+ VERSION: 1.9
+
+ USE TO FIND PERMS:
+ (Find-MgGraphCommand -Command Get-MgBetaPolicyRoleManagementPolicyAssignment).Permissions | Select Name, IsLeastPrivilege
+ Find-MgGraphPermission -All
+
+ CHANGELOG:
+ 2024-10-03 - Initial version
+ 2024-11-05 - Added support for ServicePrincipal with id's and typos
+ 2024-11-07 - Added support for Domain, and beta api.
+ 2024-11-15 - Removed redundantpermissions and added verbose messages
+ 2024-12-20 - Added version and changelog. Added support for pipeline and for multiple products. Fixed issue with role output for null values
+ 2024-12-23 - Adjusted endpoint output based on structure changes in the permissions file
+ #>
+
+ [CmdletBinding(DefaultParameterSetName = 'CmdletName')]
+ param (
+ [Parameter(Mandatory = $false, ParameterSetName = 'CmdletName')]
+ [Alias('Command')]
+ [string]$CmdletName,
+
+ [Parameter(Mandatory = $false, ParameterSetName = 'ServicePrincipal')]
+ [switch]$ServicePrincipal,
+
+ [Parameter(Mandatory = $true, ParameterSetName = 'ServicePrincipal',ValueFromPipeline=$true)]
+ [ValidateSet('aad', 'exo', 'defender', 'teams', 'sharepoint', 'scubatank')]
+ [string[]]$Product,
+
+ [Parameter(Mandatory = $false)]
+ [string]$Domain,
+
+ [Parameter(Mandatory = $false)]
+ [guid]$Id,
+
+ [Parameter(Mandatory = $false)]
+ [ValidateSet('least', 'higher')]
+ [Alias('PermissionType')]
+ [string]$PermissionLevel = 'least',
+
+ [Parameter(Mandatory = $false)]
+ [ValidateSet('commercial', 'gcc', 'gcchigh', 'dod')]
+ [string]$Environment = 'commercial',
+
+ [Parameter(Mandatory = $false)]
+ [ValidateSet('perms','modules', 'api', 'endpoint', 'support', 'role' , 'appId', 'all')]
+ [string]$OutAs ='perms'
+ )
+ Begin{
+ $ErrorActionPreference = 'Stop'
+
+ iF($OutAs -eq "endpoint" -and $Product -eq 'sharepoint' -and !$Domain){
+ Write-Error -Message "Parameter [-Domain] is required when OutAs is endpoint"
+ }
+
+ If($OutAs -eq 'api' -and $Product -match 'aad|teams' -and !$Id){
+ Write-Error -Message "Parameter [-id] is required when OutAs is api or endpoint and Product is aad or teams"
+ }
+
+ [string]$ResourceRoot = ($PWD.ProviderPath, $PSScriptRoot)[[bool]$PSScriptRoot]
+
+ $permissionSet = Get-Content -Path "$ResourceRoot\ScubaGearPermissions.json" | ConvertFrom-Json
+ Write-Verbose "Command: `$permissionSet = Get-Content -Path '$ResourceRoot\ScubaGearPermissions.json' | ConvertFrom-Json"
+
+ $ResourceAPIHash = @{
+ 'aad' = '00000003-0000-0000-c000-000000000000'
+ 'exo' = '00000002-0000-0ff1-ce00-000000000000'
+ 'defender' = '00000002-0000-0ff1-ce00-000000000000'
+ 'sharepoint' = '00000003-0000-0ff1-ce00-000000000000'
+ 'scubatank' = '00000003-0000-0000-c000-000000000000'
+ }
+
+ # Start with an empty array to build the filter
+ $conditions = @()
+ $conditionsmsg = @()
+ $output = @()
+ }
+ Process{
+
+ switch($PSBoundParameters.Keys){
+ 'CmdletName' {
+ $conditions += {$_.moduleCmdlet -eq $CmdletName}
+ $conditionsmsg += '`$_.moduleCmdlet -eq "' + $CmdletName + '"'
+ }
+
+ 'Product' {
+ Foreach($ProductItem in $Product){
+ $conditions += {$_.scubaGearProduct -contains $ProductItem }
+ $conditionsmsg = '`$_.scubaGearProduct -contains "' + $ProductItem + '"'
+ If($ServicePrincipal -and $ProductItem -ne 'teams'){
+ # Filter the resourceAPIAppId based on the product
+ $conditions += {$_.resourceAPIAppId -contains $ResourceAPIHash[$ProductItem]}
+ $conditionsmsg += '`$_.resourceAPIAppId -contains "' + $ResourceAPIHash[$ProductItem] + '"'
+ }elseif($OutAs -eq 'endpoint'){
+ #do no filter the resourceAPIAppId
+ }elseif($ProductItem -match 'exo|sharepoint|defender'){
+ # If the product is exo or SharePoint, then the resourceAPIAppId should not match the Exchange/SharePoint resourceAPIAppId
+ # This accounts for interactive permissions needed for Exchange when running the SCuBAGear, and doesn't list SharePoint interactive permissions
+ $conditions += {$_.resourceAPIAppId -notcontains $ResourceAPIHash[$ProductItem]}
+ $conditionsmsg += '`$_.resourceAPIAppId -notcontains "' + $ResourceAPIHash[$ProductItem] + '"'
+ }
+ }
+ }
+ }
+
+ foreach ($EnvironmentItem in $Environment) {
+ $conditions += {$_.supportedEnv -contains $EnvironmentItem }
+ $conditionsmsg += '`$_.supportedEnv -contains "' + $EnvironmentItem + '"'
+ }
+
+ #write a verbose statement where the values are expanded in the $conditions
+ # the $_ causes the join to fail, so we need to replace it with another character
+ $filterCondition = $conditionsmsg -join '' -replace '`', ' -and ' -replace '^\s+(-and)\s+', ''
+
+ # Correct verbose message with escaped braces
+ Write-Verbose -Message ("Command: `$collection = `$permissionSet | Where-Object {{ {0} }}" -f $filterCondition)
+
+ # Combine the conditions into a single script block
+ $filterScript = {
+ $result = $true
+ foreach ($condition in $conditions) {
+ $result = $result -and (&$condition)
+ }
+ return $result
+ }
+
+ $collection = $permissionSet | Where-Object $filterScript
+
+ # Apply the dynamically built filter in Where-Object
+ switch ($OutAs) {
+ 'perms' {
+ If($PermissionLevel -eq 'least'){
+ Write-Verbose -Message "Command: `$collection | Select-Object -ExpandProperty leastPermissions -Unique"
+ $output += $collection | Select-Object -ExpandProperty leastPermissions -Unique
+ }
+ else{
+ Write-Verbose -Message "Command: `$collection | Select-Object -ExpandProperty higherPermissions -Unique"
+ $output += $collection | Select-Object -ExpandProperty higherPermissions -Unique
+ }
+ }
+ 'modules' {
+ Write-Verbose -Message "Command: `$collection | Select-Object -ExpandProperty poshModule -Unique"
+ $output += $collection | Where-Object $filterScript | Select-Object -ExpandProperty poshModule -Unique
+ }
+ 'endpoint' {
+
+ #only get the api
+ Write-Verbose -Message "Command: `$collection | Where-Object {`$_.moduleCmdlet -like 'Connect-*'} | foreach-object {`$_.apiResource -replace '{id}',$Id -replace '{domain}',$Domain} | Select-Object -Unique"
+ #combine the apiResource and api filter if exists
+ $output += $collection | Where-Object $filterScript | Where-Object {$_.moduleCmdlet -like 'Connect-*'} | foreach-object {
+ #$apiResource = $_.'apiResource'
+
+ If($_.apifilter){
+ ($_.apiResource -replace "{id}",$Id -replace '{domain}',$Domain) + '?$filter=' + $_.apifilter
+ }else{
+ $_.apiResource -replace '{id}',$Id -replace '{domain}',$Domain
+ }
+ } | Select-Object -Unique
+
+ }
+ 'api'{
+
+ If($PSBoundParameters.ContainsKey('CmdletName') -and $CmdletName -match '-Mg'){
+ #if cmdlete is a graph cmdlet, then get the connect-* cmdlet
+ Write-Verbose -Message "Command: `$connecturi = `$permissionSet | Where-Object {`$_.moduleCmdlet -eq 'Connect-MgGraph' -and `$_.supportedEnv -eq '$Environment'} | foreach-object {`$_.apiResource} | Select-Object -Unique"
+ $connecturi = $permissionSet | Where-Object {$_.moduleCmdlet -eq 'Connect-MgGraph' -and $_.supportedEnv -eq $Environment} | foreach-object {$_.apiResource} | Select-Object -Unique
+ }Else{
+ #get the connect-* cmdlet:
+ Write-Verbose -Message "Command: `$connecturi = `$collection | Where-Object {`$_.moduleCmdlet -like 'Connect-*'} | foreach-object {`$_.apiResource} | Select-Object -Unique"
+ $connecturi = $collection | Where-Object $filterScript | Where-Object {$_.moduleCmdlet -like 'Connect-*'} | foreach-object {$_.apiResource} | Select-Object -Unique
+ }
+
+ #only get the api
+ Write-Verbose -Message "Command: `$collection | Where-Object {`$_.moduleCmdlet -notlike 'Connect-*'} | foreach-object {'$connecturi + ($_.apiResource -replace '{id}',$Id -replace '{domain}',$Domain)'} | Select-Object -Unique"
+ #combine the apiResource and api filter if exists
+ $output += $collection | Where-Object $filterScript | Where-Object {$_.moduleCmdlet -notlike 'Connect-*'} | foreach-object {
+ #$apiResource = $_.'apiResource'
+
+ If($_.apifilter){
+ $connecturi + ($_.apiResource -replace "{id}",$Id -replace '{domain}',$Domain) + '?$filter=' + $_.apifilter
+ }else{
+ $connecturi + $_.apiResource -replace '{id}',$Id -replace '{domain}',$Domain
+ }
+ } | Select-Object -Unique
+
+ }
+ 'support' {
+ Write-Verbose -Message "Command: `$collection | Select-Object -ExpandProperty supportLinks -Unique"
+ $output += $collection | Where-Object $filterScript | Select-Object -ExpandProperty supportLinks -Unique
+ }
+ 'appId'{
+ Write-Verbose -Message "Command: `$collection | Select-Object -ExpandProperty resourceAPIAppId -Unique"
+ $output += $collection | Where-Object $filterScript | Select-Object -ExpandProperty resourceAPIAppId -Unique
+ }
+ 'role' {
+ Try{
+ Write-Verbose -Message "Command: `$collection | Select-Object -ExpandProperty sprolePermissions -Unique"
+ $output += $collection | Where-Object $filterScript | Select-Object -ExpandProperty sprolePermissions -Unique
+ }Catch{
+ $output += $null
+ }
+ }
+ 'all' {
+ Write-Verbose -Message "Command: `$collection | Sort-Object"
+ $objects += $collection | Where-Object $filterScript
+
+ #replace domain and id if found in objects
+ foreach ($object in $objects) {
+ $properties = $object.PSObject.Properties
+ foreach ($property in $properties) {
+ if ($property.Value -is [string]) {
+ # Replace in string values
+ $property.Value = $property.Value -replace '{domain}', 'contoso'
+ } elseif ($property.Value -is [array]) {
+ # Replace in array values while keeping it as an array
+ $property.Value = @($property.Value | ForEach-Object {
+ if ($_ -is [string]) {
+ $_ -replace '{domain}', 'contoso'
+ } else {
+ $_
+ }
+ })
+ }
+ }
+ }
+
+ $output = $objects
+ }
+ }
+ }
+ End{
+ return $output | Sort-Object
+ }
+}
+
+
+Function Get-ScubaGearEntraRedundantPermissions{
+ [CmdletBinding()]
+ Param(
+ [Parameter(Mandatory = $false)]
+ [switch]$FilterRedundancy
+ )
+
+ $data = Get-ScubaGearPermissions -Product aad -OutAs all
+
+ ForEach($FirstItem in $data)
+ {
+ Write-Verbose "First loop [$($FirstItem.moduleCmdlet)] and HigherPermission: [$($FirstItem.higherPermissions)] and LeastPermission: [$($FirstItem.leastPermissions)]"
+ ForEach($SecondItem in $data)
+ {
+ Write-Verbose " Second loop $($SecondItem.moduleCmdlet) and LeastPermission: $($SecondItem.leastPermissions)"
+ if($SecondItem.moduleCmdlet -ne $FirstItem.moduleCmdlet `
+ -and $SecondItem.scubaGearProduct -eq $FirstItem.scubaGearProduct `
+ -and $SecondItem.higherPermissions -contains $FirstItem.leastPermissions `
+ -and $FirstItem.leastPermissions -ne $SecondItem.leastPermissions `
+ -and $SecondItem.PermissionNeeded -eq "false"
+ )
+ {
+ Write-Verbose " - Match found [$($FirstItem.moduleCmdlet)] and [$($SecondItem.moduleCmdlet)] with: [$($FirstItem.leastPermissions) and $($SecondItem.higherPermissions)]"
+ # Create node in json named redundant and set value to true
+ #$SecondItem.permissionredunancy = "true"
+ #$SecondItem.redundantcmdlet = $FirstItem.moduleCmdlet
+ #added permissionredunancy member to the object dynamically
+
+ $SecondItem | Add-Member -MemberType NoteProperty -Name PermissionNeeded -Value "false" -Force
+ $SecondItem | Add-Member -MemberType NoteProperty -Name RedundantCmdlet -Value $FirstItem.moduleCmdlet -Force
+
+ $data += $FirstItem
+ }
+ }
+ }
+
+ #filter out connect
+ $data = $data | Where-Object {$_ -notmatch 'Connect'}
+
+ If($FilterRedundancy){
+ return $data | Where-Object {$_.PermissionNeeded -ne "false"} | Select -ExpandProperty leastPermissions -Unique | Sort
+ }Else{
+ return $data| Select moduleCmdlet,RedundantCmdlet,PermissionNeeded,leastPermissions
+ }
+}
+<#
+$leastPermissions = Get-ScubaGearPermissions -Product aad -PermissionLevel least
+$higherPermissions = Get-ScubaGearPermissions -Product aad -PermissionLevel higher
+$redundantPermissions = Get-ScubaGearEntraRedundantPermissions
+#Compare the two and populate only the least privileges that does not exist in higher
+$onlyLeastPrivileges = $leastPermissions | Where-Object {$_ -notin $higherPermissions}
+#>
+
+
+Export-ModuleMember -Function Get-ScubaGearPermissions,Get-ScubaGearEntraRedundantPermissions
\ No newline at end of file
diff --git a/PowerShell/ScubaGear/Modules/Permissions/ScubaGearPermissions.json b/PowerShell/ScubaGear/Modules/Permissions/ScubaGearPermissions.json
new file mode 100644
index 0000000000..a259cf8a5c
--- /dev/null
+++ b/PowerShell/ScubaGear/Modules/Permissions/ScubaGearPermissions.json
@@ -0,0 +1,1161 @@
+[
+ {
+ "moduleCmdlet": "Get-MgRoleManagementDirectoryRoleDefinition",
+ "apiResource": "/roleManagement/directory/roleDefinitions/{unifiedRoleDefinition-id}",
+ "poshModule": [
+ "Microsoft.Graph.Identity.Governance"
+ ],
+ "leastPermissions": [
+ "RoleManagement.Read.Directory"
+ ],
+ "higherPermissions": [
+ "RoleManagement.ReadWrite.Directory",
+ "RoleManagement.Read.All",
+ "Directory.ReadWrite.All",
+ "Directory.Read.All"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "scubatank"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/graph/api/unifiedroledefinition-get?view=graph-rest-1.0"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgServicePrincipal",
+ "apiResource": "/servicePrincipals/{servicePrincipal-id}",
+ "poshModule": [
+ "Microsoft.Graph.Applications"
+ ],
+ "leastPermissions": [
+ "Application.Read.All"
+ ],
+ "higherPermissions": [
+ "Directory.ReadWrite.All",
+ "Directory.Read.All",
+ "Application.ReadWrite.OwnedBy",
+ "Application.ReadWrite.All"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "scubatank"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/graph/api/serviceprincipal-get?view=graph-rest-1.0"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "New-MgRoleManagementDirectoryRoleAssignment",
+ "apiResource": "/roleManagement/directory/roleAssignments",
+ "poshModule": [
+ "Microsoft.Graph.Identity.Governance"
+ ],
+ "leastPermissions": [
+ "RoleManagement.ReadWrite.Directory"
+ ],
+ "higherPermissions": null,
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "scubatank"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/graph/api/rbacapplication-post-roleassignments?view=graph-rest-1.0"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "New-MgServicePrincipalAppRoleAssignment",
+ "apiResource": "/servicePrincipals/{servicePrincipal-id}/appRoleAssignments",
+ "poshModule": [
+ "Microsoft.Graph.Applications"
+ ],
+ "leastPermissions": [
+ "AppRoleAssignment.ReadWrite.All",
+ "Application.Read.All"
+ ],
+ "higherPermissions": null,
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "scubatank"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/graph/api/serviceprincipal-post-approleassignments?view=graph-rest-1.0"
+ ],
+ "notes": ""
+ },
+
+
+ {
+ "moduleCmdlet": "Invoke-MgGraphRequest",
+ "apiResource": "/v1.0/me",
+ "poshModule": [
+ "Microsoft.Graph.Applications"
+ ],
+ "leastPermissions": [
+ "User.Read"
+ ],
+ "higherPermissions": null,
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "scubatank"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/graph/api/serviceprincipal-post-approleassignments?view=graph-rest-1.0"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaPolicyRoleManagementPolicyRule",
+ "apiResource": "/beta/policies/roleManagementPolicies/{unifiedRoleManagementPolicy-id}/rules",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.SignIns"
+ ],
+ "leastPermissions": [
+ "RoleManagementPolicy.Read.Directory",
+ "RoleManagementPolicy.Read.AzureADGroup"
+ ],
+ "higherPermissions": [
+ "RoleManagementPolicy.ReadWrite.Directory",
+ "RoleManagement.ReadWrite.Directory",
+ "RoleManagement.Read.All",
+ "RoleManagementPolicy.ReadWrite.AzureADGroup"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": ["aad"],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/graph/api/unifiedrolemanagementpolicyrule-get?view=graph-rest-beta&tabs=http",
+ "https://learn.microsoft.com/en-us/graph/api/policyroot-list-rolemanagementpolicies?view=graph-rest-beta&tabs=http"
+ ],
+ "notes": ["Documentation lists the leastPermissions as RoleManagementPolicy.Read.Directory, but the cmdlet requires RoleManagementPolicy.Read.AzureADGroup. If you don't use the RoleManagementPolicy.Read.AzureADGroup permission, you will receive a 403 error."]
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaDirectoryRole",
+ "apiResource": "/beta/directoryRoles",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.DirectoryManagement"
+ ],
+ "leastPermissions": [
+ "RoleManagement.Read.Directory"
+ ],
+ "higherPermissions": [
+ "Directory.Read.All",
+ "Directory.ReadWrite.All",
+ "RoleManagement.ReadWrite.Directory"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": ["aad"],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Identity.DirectoryManagement/Get-MgBetaDirectoryRole?view=graph-powershell-beta",
+ "https://learn.microsoft.com/en-us/graph/api/directoryrole-list?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaDirectoryRoleMember",
+ "apiResource": "/beta/directoryRoles/{id}/members",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.DirectoryManagement"
+ ],
+ "leastPermissions": [
+ "RoleManagement.Read.Directory"
+ ],
+ "higherPermissions": [
+ "Directory.Read.All",
+ "Directory.ReadWrite.All",
+ "RoleManagement.ReadWrite.Directory"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.beta.identity.directorymanagement/get-mgbetadirectoryrolemember?view=graph-powershell-beta",
+ "https://learn.microsoft.com/graph/api/directoryrole-list-members?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaDirectoryRoleTemplate",
+ "apiResource": "/beta/directoryRoleTemplates",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.DirectoryManagement"
+ ],
+ "leastPermissions": [
+ "RoleManagement.Read.Directory"
+ ],
+ "higherPermissions": [
+ "Directory.Read.All",
+ "Directory.ReadWrite.All",
+ "RoleManagement.ReadWrite.Directory"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Identity.DirectoryManagement/Get-MgBetaDirectoryRoleTemplate?view=graph-powershell-beta",
+ "https://learn.microsoft.com/graph/api/directoryroletemplate-list?view=graph-rest-beta"
+ ],
+ "notes": "Used within the ScubaGear function: Get-PriviledgeRole within the AADProvider module"
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaDirectorySetting",
+ "apiResource": "/beta/settings",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.DirectoryManagement"
+ ],
+ "leastPermissions": [
+ "Directory.Read.All"
+ ],
+ "higherPermissions": [
+ "Directory.ReadWrite.All",
+ "Group.Read.All",
+ "Group.ReadWrite.All"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.beta.identity.directorymanagement/get-mgbetadirectorysetting?view=graph-powershell-beta",
+ "https://learn.microsoft.com/en-us/graph/api/group-list-settings?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaDomain",
+ "apiResource": "/beta/domains",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.DirectoryManagement"
+ ],
+ "leastPermissions": [
+ "Domain.Read.All"
+ ],
+ "higherPermissions": [
+ "Domain.ReadWrite.All",
+ "Directory.Read.All"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Identity.DirectoryManagement/Get-MgBetaDomain?view=graph-powershell-beta",
+ "https://learn.microsoft.com/graph/api/domain-list?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaGroup",
+ "apiResource": "/beta/groups",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Groups"
+ ],
+ "leastPermissions": [
+ "GroupMember.Read.All"
+ ],
+ "higherPermissions": [
+ "Group.ReadWrite.All",
+ "Directory.Read.All",
+ "Directory.ReadWrite.All",
+ "Group.Read.All"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.beta.groups/get-mgbetagroup?view=graph-powershell-beta",
+ "https://learn.microsoft.com/graph/api/group-list?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaGroupMember",
+ "apiResource": "/beta/groups/{id}/members",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Groups"
+ ],
+ "leastPermissions": [
+ "GroupMember.Read.All"
+ ],
+ "higherPermissions": [
+ "Group.Read.All",
+ "Group.ReadWrite.All",
+ "Directory.Read.All",
+ "GroupMember.ReadWrite.All"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Groups/Get-MgBetaGroupMember?view=graph-powershell-beta",
+ "https://learn.microsoft.com/graph/api/group-list-members?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaIdentityConditionalAccessPolicy",
+ "apiResource": "/beta/identity/conditionalAccess/policies",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.SignIns"
+ ],
+ "leastPermissions": [
+ "Policy.Read.All"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Identity.SignIns/Get-MgBetaIdentityConditionalAccessPolicy?view=graph-powershell-beta",
+ "https://learn.microsoft.com/graph/api/conditionalaccessroot-list-policies?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleInstance",
+ "apiResource": "/beta/identityGovernance/privilegedAccess/group/eligibilityScheduleInstances",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.Governance"
+ ],
+ "leastPermissions": [
+ "PrivilegedEligibilitySchedule.Read.AzureADGroup"
+ ],
+ "higherPermissions": [
+ "PrivilegedEligibilitySchedule.ReadWrite.AzureADGroup"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Identity.Governance/get-mgbetaidentitygovernanceprivilegedaccessgroupeligibilityschedule?view=graph-powershell-beta",
+ "https://learn.microsoft.com/graph/api/privilegedaccessgroup-list-eligibilityscheduleinstances?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaOrganization",
+ "apiResource": "/beta/organization",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.DirectoryManagement"
+ ],
+ "leastPermissions": [
+ "Organization.Read.All"
+ ],
+ "higherPermissions": [
+ "Directory.Read.All",
+ "Organization.ReadWrite.All",
+ "Directory.ReadWrite.All"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Identity.DirectoryManagement/Get-MgBetaOrganization?view=graph-powershell-beta",
+ "https://learn.microsoft.com/graph/api/organization-list?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaPolicyAuthorizationPolicy",
+ "apiResource": "/beta/policies/authorizationPolicy",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.SignIns"
+ ],
+ "leastPermissions": [
+ "Policy.Read.All"
+ ],
+ "higherPermissions": [
+ "Policy.ReadWrite.Authorization"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.signins/get-mgpolicyauthorizationpolicy?view=graph-powershell-1.0",
+ "https://learn.microsoft.com/graph/api/authorizationpolicy-get?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaPolicyRoleManagementPolicyAssignment",
+ "apiResource": "/beta/policies/roleManagementPolicyAssignments",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.SignIns"
+ ],
+ "leastPermissions": [
+ "RoleManagementPolicy.Read.Directory"
+ ],
+ "higherPermissions": [
+ "RoleManagementPolicy.ReadWrite.Directory",
+ "RoleManagement.ReadWrite.Directory",
+ "RoleManagement.Read.Directory"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Identity.SignIns/Get-MgBetaPolicyRoleManagementPolicyAssignment?view=graph-powershell-beta",
+ "https://learn.microsoft.com/en-us/graph/api/unifiedrolemanagementpolicyassignment-get?view=graph-rest-beta"
+ ],
+ "notes": [
+ "If using API call, ensure you are using the correct filter to get the correct data; use: scopeId eq '/' and scopeType eq 'DirectoryRole'",
+ "Used within the ScubaGear function: Get-PriviledgeRole within the AADProvider module"
+ ]
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaPrivilegedAccessResource",
+ "apiResource": "/beta/privilegedAccess/aadGroups/resources",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.Governance"
+ ],
+ "leastPermissions": [
+ "PrivilegedAccess.Read.AzureADGroup"
+ ],
+ "higherPermissions": [
+ "PrivilegedAccess.ReadWrite.AzureADGroup"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.beta.identity.governance/get-mgbetaprivilegedaccessresource?view=graph-powershell-beta",
+ "https://learn.microsoft.com/en-us/graph/api/resources/privilegedaccess?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaRoleManagementDirectoryRoleAssignmentScheduleInstance",
+ "apiResource": "/beta/roleManagement/directory/roleAssignmentScheduleInstances",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.Governance"
+ ],
+ "leastPermissions": [
+ "RoleAssignmentSchedule.Read.Directory"
+ ],
+ "higherPermissions": [
+ "RoleAssignmentSchedule.ReadWrite.Directory",
+ "RoleManagement.ReadWrite.Directory",
+ "RoleManagement.Read.All",
+ "RoleManagement.Read.Directory"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Identity.Governance/Get-MgBetaRoleManagementDirectoryRoleAssignmentScheduleInstance?view=graph-powershell-beta",
+ "https://learn.microsoft.com/en-us/graph/api/rbacapplication-list-roleassignmentscheduleinstances?view=graph-rest-beta&tabs=http"
+ ],
+ "notes": "Used within the ScubaGear function: Get-PriviledgeRole within the AADProvider module"
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaRoleManagementDirectoryRoleEligibilityScheduleInstance",
+ "apiResource": "/beta/roleManagement/directory/roleEligibilityScheduleInstances",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.Governance"
+ ],
+ "leastPermissions": [
+ "RoleEligibilitySchedule.Read.Directory"
+ ],
+ "higherPermissions": [
+ "RoleEligibilitySchedule.ReadWrite.Directory",
+ "RoleManagement.Read.All",
+ "RoleManagement.Read.Directory",
+ "RoleManagement.ReadWrite.Directory"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.governance/get-mgrolemanagementdirectoryroleeligibilityscheduleinstance?view=graph-powershell-1.0",
+ "https://learn.microsoft.com/graph/api/rbacapplication-list-roleeligibilityscheduleinstances?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaSubscribedSku",
+ "apiResource": "/beta/subscribedSkus",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Identity.DirectoryManagement"
+ ],
+ "leastPermissions": [
+ "Organization.Read.All"
+ ],
+ "higherPermissions": [
+ "Directory.Read.All",
+ "Organization.Read.All",
+ "Directory.ReadWrite.All"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Identity.DirectoryManagement/Get-MgBetaSubscribedSku?view=graph-powershell-beta",
+ "https://learn.microsoft.com/graph/api/subscribedsku-list?view=graph-rest-beta"
+ ],
+ "notes": "The leastPermissions LicenseAssignment.Read.All does not work for this cmdlet. The cmdlet requires Organization.Read.All permission."
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaUser",
+ "apiResource": "/beta/users",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Users"
+ ],
+ "leastPermissions": [
+ "User.Read.All"]
+ ,
+ "higherPermissions": [
+ "User.ReadWrite.All",
+ "Directory.Read.All",
+ "Directory.ReadWrite.All"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "defender",
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.beta.users/get-mgbetauser?view=graph-powershell-beta",
+ "https://learn.microsoft.com/graph/api/user-list?view=graph-rest-beta"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Get-MgBetaUserCount",
+ "apiResource": "/beta/users",
+ "poshModule": [
+ "Microsoft.Graph.Beta.Users"
+ ],
+ "leastPermissions": [
+ "User.Read.All"
+ ],
+ "higherPermissions": [
+ "User.ReadWrite.All",
+ "Directory.Read.All",
+ "Directory.ReadWrite.All"
+ ],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/Microsoft.Graph.Beta.Users/Get-MgBetaUserCount?view=graph-powershell-beta",
+ "https://learn.microsoft.com/en-us/graph/api/user-list?view=graph-rest-beta&tabs=powershell#example-6-get-only-a-count-of-users"
+ ],
+ "notes": "There is no graph api that mimics this cmdlet besides including the query: $count=true and the consistencyLevel: eventual in the api call."
+ },
+
+ {
+ "moduleCmdlet": "Connect-ExchangeOnline",
+ "apiResource": "https://outlook.office365.com/powershell-liveid/",
+ "poshModule": [
+ "ExchangeOnlineManagement"
+ ],
+ "leastPermissions": [
+ "Exchange.ManageAsApp"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [
+ "Global Reader"
+ ],
+ "scubaGearProduct": [
+ "exo"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc"
+ ],
+ "resourceAPIAppId": "00000002-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/exchange/connect-exchangeonline?view=exchange-ps"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-ExchangeOnline",
+ "apiResource": "https://outlook.office365.us/powershell-liveID",
+ "poshModule": [
+ "ExchangeOnlineManagement"
+ ],
+ "leastPermissions": [
+ "Exchange.ManageAsApp"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [
+ "Global Reader"
+ ],
+ "scubaGearProduct": [
+ "exo"
+ ],
+ "supportedEnv": [
+ "gcchigh"
+ ],
+ "resourceAPIAppId": "00000002-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/exchange/connect-exchangeonline?view=exchange-ps"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-ExchangeOnline",
+ "apiResource": "https://webmail.apps.mil/powershell-liveID",
+ "poshModule": [
+ "ExchangeOnlineManagement"
+ ],
+ "leastPermissions": [
+ "Exchange.ManageAsApp"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [
+ "Global Reader"
+ ],
+ "scubaGearProduct": [
+ "exo"
+ ],
+ "supportedEnv": [
+ "dod"
+ ],
+ "resourceAPIAppId": "00000002-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/exchange/connect-exchangeonline?view=exchange-ps"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-IPPSSession",
+ "apiResource": "https://ps.compliance.protection.outlook.com/powershell-liveid/",
+ "poshModule": [
+ "ExchangeOnlineManagement"
+ ],
+ "leastPermissions": [
+ "Exchange.ManageAsApp"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [
+ "Global Reader"
+ ],
+ "scubaGearProduct": [
+ "exo",
+ "defender"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc"
+ ],
+ "resourceAPIAppId": "00000002-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/exchange/connect-ippssession?view=exchange-ps"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-IPPSSession",
+ "apiResource": "https://ps.compliance.protection.office365.us/powershell-liveid/",
+ "poshModule": [
+ "ExchangeOnlineManagement"
+ ],
+ "leastPermissions": [
+ "Exchange.ManageAsApp"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [
+ "Global Reader"
+ ],
+ "scubaGearProduct": [
+ "exo",
+ "defender"
+ ],
+ "supportedEnv": [
+ "gcchigh"
+ ],
+ "resourceAPIAppId": "00000002-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/exchange/connect-ippssession?view=exchange-ps"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-IPPSSession",
+ "apiResource": "https://l5.ps.compliance.protection.office365.us/powershell-liveid/",
+ "poshModule": [
+ "ExchangeOnlineManagement"
+ ],
+ "leastPermissions": [
+ "Exchange.ManageAsApp"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [
+ "Global Reader"
+ ],
+ "scubaGearProduct": [
+ "exo",
+ "defender"
+ ],
+ "supportedEnv": [
+ "dod"
+ ],
+ "resourceAPIAppId": "00000002-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/exchange/connect-ippssession?view=exchange-ps"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-MicrosoftTeams",
+ "apiResource": "https://*.api.interfaces.records.teams.microsoft.com",
+ "poshModule": [
+ "MicrosoftTeams"
+ ],
+ "leastPermissions": [],
+ "higherPermissions": [],
+ "spRolePermissions": [
+ "Global Reader"
+ ],
+ "scubaGearProduct": [
+ "teams"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc",
+ "gcchigh",
+ "dod"
+ ],
+ "resourceAPIAppId": "ab3be6b7-f5df-413d-ac2d-abf1e3fd9c0b",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/teams/connect-microsoftteams?view=teams-ps"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-SPOService",
+ "apiResource": "https://{domain}-admin.sharepoint.com",
+ "poshModule": [
+ "Microsoft.Online.SharePoint.PowerShell"
+ ],
+ "leastPermissions": [
+ "Sites.FullControl.All"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "sharepoint"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc"
+ ],
+ "resourceAPIAppId": "00000003-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/sharepoint/sharepoint-online/connect-sharepoint-online"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-SPOService",
+ "apiResource": "https://{domain}-admin.sharepoint.us",
+ "poshModule": [
+ "Microsoft.Online.SharePoint.PowerShell"
+ ],
+ "leastPermissions": [
+ "Sites.FullControl.All"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "sharepoint"
+ ],
+ "supportedEnv": [
+ "gcchigh"
+ ],
+ "resourceAPIAppId": "00000003-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/sharepoint/sharepoint-online/connect-sharepoint-online"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-SPOService",
+ "apiResource": "https://{domain}-admin.sharepoint.mil.us",
+ "poshModule": [
+ "Microsoft.Online.SharePoint.PowerShell"
+ ],
+ "leastPermissions": [
+ "Sites.FullControl.All"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "sharepoint"
+ ],
+ "supportedEnv": [
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/sharepoint/sharepoint-online/connect-sharepoint-online"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-PnPOnline",
+ "apiResource": "https://{domain}-admin.sharepoint.com",
+ "poshModule": [
+ "PnP.PowerShell"
+ ],
+ "leastPermissions": [
+ "Sites.FullControl.All"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "sharepoint"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc"
+ ],
+ "resourceAPIAppId": "00000003-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/sharepoint/dev/declarative-customization/site-design-pnppowershell"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-PnPOnline",
+ "apiResource": "https://{domain}-admin.sharepoint.us",
+ "poshModule": [
+ "PnP.PowerShell"
+ ],
+ "leastPermissions": [
+ "Sites.FullControl.All"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "sharepoint"
+ ],
+ "supportedEnv": [
+ "gcchigh"
+ ],
+ "resourceAPIAppId": "00000003-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/sharepoint/dev/declarative-customization/site-design-pnppowershell"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-PnPOnline",
+ "apiResource": "https://{domain}-admin.sharepoint.mil.us",
+ "poshModule": [
+ "PnP.PowerShell"
+ ],
+ "leastPermissions": [
+ "Sites.FullControl.All"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "sharepoint"
+ ],
+ "supportedEnv": [
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0ff1-ce00-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/sharepoint/dev/declarative-customization/site-design-pnppowershell"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-MgGraph",
+ "apiResource": "https://graph.microsoft.com",
+ "poshModule": [
+ "Microsoft.Graph.Authentication"
+ ],
+ "leastPermissions": [
+ "User.Read"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad",
+ "defender"
+ ],
+ "supportedEnv": [
+ "commercial",
+ "gcc"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.authentication/connect-mggraph?view=graph-powershell-1.0"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-MgGraph",
+ "apiResource": "https://graph.microsoft.us",
+ "poshModule": [
+ "Microsoft.Graph.Authentication"
+ ],
+ "leastPermissions": [
+ "User.Read"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad",
+ "defender"
+ ],
+ "supportedEnv": [
+ "gcchigh"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.authentication/connect-mggraph?view=graph-powershell-1.0"
+ ],
+ "notes": ""
+ },
+
+ {
+ "moduleCmdlet": "Connect-MgGraph",
+ "apiResource": "https://dod-graph.microsoft.us",
+ "poshModule": [
+ "Microsoft.Graph.Authentication"
+ ],
+ "leastPermissions": [
+ "User.Read"
+ ],
+ "higherPermissions": [],
+ "spRolePermissions": [],
+ "scubaGearProduct": [
+ "aad",
+ "defender"
+ ],
+ "supportedEnv": [
+ "dod"
+ ],
+ "resourceAPIAppId": "00000003-0000-0000-c000-000000000000",
+ "supportLinks": [
+ "https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.authentication/connect-mggraph?view=graph-powershell-1.0"
+ ],
+ "notes": ""
+ }
+]
\ No newline at end of file
diff --git a/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1 b/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1
index ced73ac307..6a8165b6d6 100644
--- a/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1
+++ b/PowerShell/ScubaGear/Modules/Providers/ExportAADProvider.psm1
@@ -1,12 +1,6 @@
-# Many of the commandlets can be replaced with direct API access, but we are starting the transition with the ones
-# below because they have slow imports that affect performance more than the others. Some commandlets are fast
-# and there is no obvoius performance advantage to using the API beyond maybe batching.
-$GraphEndpoints = @{
- "Get-MgBetaRoleManagementDirectoryRoleEligibilityScheduleInstance" = "/beta/roleManagement/directory/roleEligibilityScheduleInstances"
- "Get-MgBetaRoleManagementDirectoryRoleAssignmentScheduleInstance" = "/beta/roleManagement/directory/roleAssignmentScheduleInstances"
- "Get-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleInstance" = "/beta/identityGovernance/privilegedAccess/group/eligibilityScheduleInstances"
- "Get-MgBetaPrivilegedAccessResource" = "/beta/privilegedAccess/aadGroups/resources"
-}
+# Many of the cmdlets can be replaced with direct API access, but we are starting the transition with the ones
+# below because they have slow imports that affect performance more than the others. Some cmdlets are fast
+# and there is no obvious performance advantage to using the API beyond maybe batching.
function Invoke-GraphDirectly {
param (
@@ -23,20 +17,12 @@ function Invoke-GraphDirectly {
)
Write-Debug "Replacing Cmdlet: $commandlet"
- try {
- $endpoint = $GraphEndpoints[$commandlet]
- } catch {
- 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
+
+ #use Get-ScubaGearPermissions to convert cmdlets to API calls
+ $endpoint = Get-ScubaGearPermissions -CmdletName $commandlet -OutAs api -Environment $M365Environment
+ If($null -eq $endpoint){
+ Write-Error "The commandlet $commandlet can't be used with the Invoke-GraphDirectly function yet."
}
if ($queryParams) {
@@ -621,5 +607,4 @@ function Get-PrivilegedRole {
# Return the array
$PrivilegedRoleArray
-}
-
+}
\ No newline at end of file
diff --git a/PowerShell/ScubaGear/ScubaGear.psd1 b/PowerShell/ScubaGear/ScubaGear.psd1
index c6f1e4e9aa..09086400b1 100644
--- a/PowerShell/ScubaGear/ScubaGear.psd1
+++ b/PowerShell/ScubaGear/ScubaGear.psd1
@@ -86,7 +86,9 @@ FunctionsToExport = @(
'Debug-SCuBA',
'Copy-SCuBASampleReport',
'Copy-SCuBASampleConfigFile',
- 'New-SCuBAConfig'
+ 'New-SCuBAConfig',
+ 'Get-ScubaGearPermissions',
+ 'Get-ScubaGearEntraRedundantPermissions'
)
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
diff --git a/PowerShell/ScubaGear/ScubaGear.psm1 b/PowerShell/ScubaGear/ScubaGear.psm1
index e886a2d1b4..ef28fe972b 100644
--- a/PowerShell/ScubaGear/ScubaGear.psm1
+++ b/PowerShell/ScubaGear/ScubaGear.psm1
@@ -1,2 +1,3 @@
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath './Modules/Orchestrator.psm1')
-Import-Module (Join-Path -Path $PSScriptRoot -ChildPath './Modules/Connection/Connection.psm1')
\ No newline at end of file
+Import-Module (Join-Path -Path $PSScriptRoot -ChildPath './Modules/Connection/Connection.psm1')
+Import-Module (Join-Path -Path $PSScriptRoot -ChildPath './Modules/Permissions/PermissionsHelper.psm1') -Force
\ No newline at end of file
diff --git a/docs/prerequisites/noninteractive.md b/docs/prerequisites/noninteractive.md
index 6c9afd8602..ee9722ea43 100644
--- a/docs/prerequisites/noninteractive.md
+++ b/docs/prerequisites/noninteractive.md
@@ -24,19 +24,27 @@ Configuring a service principal is beyond the scope of these instructions, but M
The minimum permissions and roles that must be assigned to the service principal are listed in the table below.
-| Product | API Permissions | Role |
-| ----------------------- | ----------------------------------------------- | ------------- |
-| Entra ID | Directory.Read.All, GroupMember.Read.All, | |
-| | Organization.Read.All, Policy.Read.All, | |
-| | RoleManagement.Read.Directory, User.Read.All | |
-| | PrivilegedEligibilitySchedule.Read.AzureADGroup | |
-| | PrivilegedAccess.Read.AzureADGroup | |
-| | RoleManagementPolicy.Read.AzureADGroup | |
-| Defender for Office 365 | Exchange.ManageAsApp | Global Reader |
-| Exchange Online | Exchange.ManageAsApp | Global Reader |
-| Power Platform | (see below) | |
-| SharePoint Online | Sites.FullControl.All, Directory.Read.All | |
-| Microsoft Teams | | Global Reader |
+| ScubaGear Product | API Permissions | Role | API Name | API APPID |
+| ----------------------- | ----------------------------------------------- | ------------- | ------------------------------------- | ------------------------------------- |
+| Entra ID (aad) | User.Read.All | | Microsoft.Graph | 00000003-0000-0000-c000-000000000000 |
+| | Directory.Read.All | | | |
+| | Policy.Read.All | | | |
+| | PrivilegedEligibilitySchedule.Read.AzureADGroup | | | |
+| | PrivilegedAccess.Read.AzureADGroup | | | |
+| | RoleAssignmentSchedule.Read.Directory | | | |
+| | RoleEligibilitySchedule.Read.Directory | | | |
+| | RoleManagementPolicy.Read.Directory | | | |
+| | RoleManagementPolicy.Read.AzureADGroup | | | |
+| Defender | | Global Reader | | |
+| Exchange (exo) | Exchange.ManageAsApp | Global Reader | Office 365 Exchange Online | 00000002-0000-0ff1-ce00-000000000000 |
+| | Exchange.ManageAsApp | | **Microsoft Exchange Online Protection**1| **00000007-0000-0ff1-ce00-000000000000**1 |
+| Power Platform | (see below) | | | |
+| SharePoint | Sites.FullControl.All | | SharePoint | 00000003-0000-0ff1-ce00-000000000000 |
+| Microsoft Teams (teams) | | Global Reader | | |
+
+
+> [!IMPORTANT]
+> Required for Azure Government and DOD Tenants only (GCCH / DoD) 1
## Certificate Thumbprint