mirror of
https://github.com/Gerenios/AADInternals
synced 2026-06-08 11:09:38 +00:00
1014 lines
35 KiB
PowerShell
1014 lines
35 KiB
PowerShell
# This script contains functions for Graph API at https://graph.windows.net
|
|
# Office 365 / Azure AD v2, a.k.a. AzureAD module uses this API
|
|
|
|
function Get-DynamicAbusableGroups
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Return Entra ID groups with dynamic membership rule that contains attributes that can be modified by users.
|
|
Related articles:
|
|
https://medium.com/r3d-buck3t/abusing-dynamic-groups-in-azuread-part-1-ff12e328c8c0
|
|
https://www.mnemonic.io/resources/blog/abusing-dynamic-groups-in-azure-ad-for-privilege-escalation/
|
|
|
|
.DESCRIPTION
|
|
Return Entra ID groups with dynamic membership rule that contains attributes that can be modified by users using the given Access Token
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token
|
|
|
|
.Example
|
|
PS C:\>Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Get-AADIntDynamicAbusableGroups
|
|
|
|
abusableRule groupId
|
|
------------ -------
|
|
(user.userType -eq "Member") -or (user.city -eq "Redmond") 69d8fc52-d45e-47a2-972a-6c99e057ead1
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken
|
|
)
|
|
Process
|
|
{
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
$abusableCondsUser = @("ageGroup","jobTitle","city","givenName","displayName","companyName", "country","department","employeeType","mailNickname","mail","state")
|
|
|
|
$results=Call-GraphAPI -AccessToken $AccessToken -Command groups
|
|
$dynamicGroups = $results | Where-Object groupTypes -contains "DynamicMembership"
|
|
$userReg = 'user\.(.+?)\s'
|
|
$abusableGroupsOutput = @{}
|
|
foreach($dynamicGroup in $dynamicGroups){
|
|
$abusable = $false
|
|
$groupId = $dynamicGroup.objectId
|
|
$groupTempList = @()
|
|
$userMatches = $dynamicGroup.membershipRule | Select-String -Pattern $userReg -AllMatches
|
|
foreach($userMatch in $userMatches.Matches)
|
|
{
|
|
$matchType = $userMatch.Groups[1]
|
|
if($abusableCondsUser.Contains($matchType.value))
|
|
{
|
|
$abusable = $true
|
|
}
|
|
}
|
|
if($abusable)
|
|
{
|
|
$abusableGroupsOutput.Add($groupId,$dynamicGroup.membershipRule)
|
|
}
|
|
}
|
|
|
|
$abusableGroupsOutput.keys | % {
|
|
New-object psobject -Property @{
|
|
'groupId' = $_
|
|
'abusableRule' = $abusableGroupsOutput[$_]
|
|
}
|
|
}
|
|
return $abusableGroupsOutput
|
|
}
|
|
}
|
|
|
|
function Get-AADUsers
|
|
{
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken,
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$SearchString,
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$UserPrincipalName
|
|
|
|
)
|
|
Process
|
|
{
|
|
if(![string]::IsNullOrEmpty($SearchString))
|
|
{
|
|
$queryString="`$filter=(startswith(displayName,'$SearchString') or startswith(userPrincipalName,'$SearchString'))"
|
|
}
|
|
elseif(![string]::IsNullOrEmpty($UserPrincipalName))
|
|
{
|
|
$queryString="`$filter=userPrincipalName eq '$UserPrincipalName'"
|
|
}
|
|
|
|
$results=Call-GraphAPI -AccessToken $AccessToken -Command users -QueryString $queryString
|
|
|
|
return $results
|
|
}
|
|
}
|
|
|
|
# Gets the tenant details
|
|
function Get-TenantDetails
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Extract tenant details using the given Access Token
|
|
|
|
.DESCRIPTION
|
|
Extract tenant details using the given Access Token
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token.
|
|
|
|
.Example
|
|
PS C:\>$token=Get-AADIntAccessTokenForAADGraph
|
|
PS C:\>Get-AADIntTenantDetails -AccessToken $token
|
|
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken
|
|
)
|
|
Process
|
|
{
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
# Call the API
|
|
$response=Call-GraphAPI -AccessToken $AccessToken -Command tenantDetails
|
|
|
|
# Verbose
|
|
Write-Verbose "TENANT INFORMATION: $($response.value | Out-String)"
|
|
|
|
# Return
|
|
$response
|
|
}
|
|
}
|
|
|
|
# Gets the tenant devices
|
|
# Jun 24th 2020
|
|
function Get-Devices
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Extracts tenant devices using the given Access Token
|
|
|
|
.DESCRIPTION
|
|
Extracts tenant devices using the given Access Token
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token.
|
|
|
|
.Example
|
|
PS C:\>$token=Get-AADIntAccessTokenForAADGraph
|
|
PS C:\>Get-AADIntDevices -AccessToken $token
|
|
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken
|
|
)
|
|
Process
|
|
{
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
# Call the API
|
|
$response=Call-GraphAPI -AccessToken $AccessToken -Command devices -QueryString "`$expand=registeredOwner"
|
|
|
|
# Return
|
|
$response
|
|
}
|
|
}
|
|
|
|
# Gets detailed information about the given user
|
|
# Jun 24th 2020
|
|
function Get-UserDetails
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Extracts detailed information of the given user
|
|
|
|
.DESCRIPTION
|
|
Extracts detailed information of the given user
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token.
|
|
|
|
.Parameter UserPrincipalName
|
|
The user principal name of the user whose details is to be extracted
|
|
|
|
.Example
|
|
PS C:\>$token=Get-AADIntAccessTokenForAADGraph
|
|
PS C:\>Get-AADIntUserDetails -AccessToken $token
|
|
|
|
odata.type : Microsoft.DirectoryServices.User
|
|
objectType : User
|
|
objectId : cd5676ad-ba80-4782-bdcb-ff5de37fc347
|
|
deletionTimestamp :
|
|
acceptedAs :
|
|
acceptedOn :
|
|
accountEnabled : True
|
|
ageGroup :
|
|
alternativeSecurityIds : {}
|
|
signInNames : {user@company.com}
|
|
signInNamesInfo : {}
|
|
appMetadata :
|
|
assignedLicenses : {@{disabledPlans=System.Object[]; skuId=c7df2760-2c81-4ef7-b578-5b5392b571df}, @{disabledPlans=System.Object[]; skuId=b05e124f-c7cc-45a0-a6aa-8cf78c946968}}
|
|
assignedPlans : {@{assignedTimestamp=2019-12-02T07:41:59Z; capabilityStatus=Enabled; service=MultiFactorService; servicePlanId=8a256a2b-b617-496d-b51b-e76466e88db0}, @{assignedTimestamp=2019-12-02T07
|
|
:41:59Z; capabilityStatus=Enabled; service=exchange; servicePlanId=34c0d7a0-a70f-4668-9238-47f9fc208882}, @{assignedTimestamp=2019-12-02T07:41:59Z; capabilityStatus=Enabled; service=P
|
|
owerBI; servicePlanId=70d33638-9c74-4d01-bfd3-562de28bd4ba}, @{assignedTimestamp=2019-12-02T07:41:59Z; capabilityStatus=Enabled; service=WhiteboardServices; servicePlanId=4a51bca5-1ef
|
|
f-43f5-878c-177680f191af}...}
|
|
city :
|
|
cloudAudioConferencingProviderInfo : <acpList>
|
|
<acpInformation default="true">
|
|
<tollNumber>18728886261</tollNumber>
|
|
<participantPassCode>0</participantPassCode>
|
|
<domain>resources.lync.com</domain>
|
|
<name>Microsoft</name>
|
|
<url>https://dialin.lync.com/c73270cd-afd0-4f70-8328-747f36508d85</url>
|
|
</acpInformation>
|
|
</acpList>
|
|
cloudMSExchRecipientDisplayType : 1073741824
|
|
cloudMSRtcIsSipEnabled : True
|
|
cloudMSRtcOwnerUrn :
|
|
...
|
|
|
|
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken,
|
|
[Parameter(Mandatory=$True)]
|
|
[String]$UserPrincipalName
|
|
)
|
|
Process
|
|
{
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
# Url encode for external users, replace # with %23
|
|
$UserPrincipalName = $UserPrincipalName.Replace("#","%23")
|
|
|
|
# Call the API
|
|
$response=Call-GraphAPI -AccessToken $AccessToken -Command "users/$UserPrincipalName"
|
|
|
|
# Return
|
|
$response
|
|
}
|
|
}
|
|
|
|
# Gets tenant's Azure AD settings
|
|
# Jun 24th 2020
|
|
function Get-Settings
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Extracts Azure AD settings
|
|
|
|
.DESCRIPTION
|
|
Extracts Azure AD settings
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token.
|
|
|
|
.Example
|
|
PS C:\>$token=Get-AADIntAccessTokenForAADGraph
|
|
PS C:\>Get-AADIntSettings -AccessToken $token
|
|
|
|
id displayName templateId values
|
|
-- ----------- ---------- ------
|
|
8b16b029-bb31-48c8-b4df-5ee419596688 Password Rule Settings 5cf42378-d67d-4f36-ba46-e8b86229381d {@{name=BannedPasswordCheckOnPremisesMode; value=Audit}, @{name=EnableBannedPasswordCheckOnPremises; value=True}, @{name=En...
|
|
|
|
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken
|
|
)
|
|
Process
|
|
{
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
# Call the API
|
|
$response=Call-GraphAPI -AccessToken $AccessToken -Command "settings"
|
|
|
|
# Return
|
|
$response
|
|
}
|
|
}
|
|
|
|
# Gets tenant's OAuth grants
|
|
# Jun 24th 2020
|
|
function Get-OAuthGrants
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Extracts Azure AD OAuth grants
|
|
|
|
.DESCRIPTION
|
|
Extracts Azure AD OAuth grants
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token.
|
|
|
|
.Example
|
|
PS C:\>$token=Get-AADIntAccessTokenForAADGraph
|
|
PS C:\>Get-AADIntOAuthGrants -AccessToken $token
|
|
|
|
id displayName templateId values
|
|
-- ----------- ---------- ------
|
|
8b16b029-bb31-48c8-b4df-5ee419596688 Password Rule Settings 5cf42378-d67d-4f36-ba46-e8b86229381d {@{name=BannedPasswordCheckOnPremisesMode; value=Audit}, @{name=EnableBannedPasswordCheckOnPremises; value=True}, @{name=En...
|
|
|
|
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken
|
|
)
|
|
Process
|
|
{
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
# Call the API
|
|
$response=Call-GraphAPI -AccessToken $AccessToken -Command "oauth2PermissionGrants"
|
|
|
|
# Return
|
|
$response
|
|
}
|
|
}
|
|
|
|
# Gets tenant's service principals
|
|
# Jun 24th 2020
|
|
function Get-ServicePrincipals
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Extracts Azure AD service principals
|
|
|
|
.DESCRIPTION
|
|
Extracts Azure AD service principals. If client id(s) are provided, show detailed information.
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token.
|
|
|
|
.Parameter ClientIds
|
|
List of client ids to get detailed information.
|
|
|
|
.Example
|
|
PS C:\>Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Get-AADIntServicePrincipals
|
|
|
|
AccountEnabled : true
|
|
Addresses :
|
|
AppPrincipalId : d32c68ad-72d2-4acb-a0c7-46bb2cf93873
|
|
DisplayName : Microsoft Activity Feed Service
|
|
ObjectId : 321e7bdd-d7b0-4a64-8eb3-38c259c1304a
|
|
ServicePrincipalNames : ServicePrincipalNames
|
|
TrustedForDelegation : false
|
|
|
|
AccountEnabled : true
|
|
Addresses : Addresses
|
|
AppPrincipalId : 0000000c-0000-0000-c000-000000000000
|
|
DisplayName : Microsoft App Access Panel
|
|
ObjectId : a9e03f2f-4471-41f2-96c5-589d5d7117bc
|
|
ServicePrincipalNames : ServicePrincipalNames
|
|
TrustedForDelegation : false
|
|
|
|
AccountEnabled : true
|
|
Addresses :
|
|
AppPrincipalId : dee7ba80-6a55-4f3b-a86c-746a9231ae49
|
|
DisplayName : Microsoft AppPlat EMA
|
|
ObjectId : ae0b81fc-c521-4bfd-9eaa-04c520b4b5fd
|
|
ServicePrincipalNames : ServicePrincipalNames
|
|
TrustedForDelegation : false
|
|
|
|
AccountEnabled : true
|
|
Addresses : Addresses
|
|
AppPrincipalId : 65d91a3d-ab74-42e6-8a2f-0add61688c74
|
|
DisplayName : Microsoft Approval Management
|
|
ObjectId : d8ec5b95-e5f6-416e-8e7c-c6c52ec5a11f
|
|
ServicePrincipalNames : ServicePrincipalNames
|
|
TrustedForDelegation : false
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken,
|
|
[Parameter(Mandatory=$False)]
|
|
[String[]]$ClientIds
|
|
)
|
|
Process
|
|
{
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
# If client id(s) are provided, get only those (with extra information)
|
|
if($ClientIds)
|
|
{
|
|
$body = @{
|
|
"appIds" = $ClientIds
|
|
}
|
|
|
|
# Call the API
|
|
Call-GraphAPI -AccessToken $AccessToken -Command "getServicePrincipalsByAppIds" -Body ($body | ConvertTo-Json) -Method Post -QueryString "`$Select="
|
|
}
|
|
else
|
|
{
|
|
# Call the Provisioning API
|
|
Get-ServicePrincipals2 -AccessToken $AccessToken
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
# Gets tenant's conditional access policies
|
|
# Apr 8th 2021
|
|
function Get-ConditionalAccessPolicies
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Shows conditional access policies.
|
|
|
|
.DESCRIPTION
|
|
Shows conditional access policies.
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token.
|
|
|
|
.Example
|
|
PS C:\>Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Get-AADIntConditionalAccessPolicies
|
|
|
|
odata.type : Microsoft.DirectoryServices.Policy
|
|
objectType : Policy
|
|
objectId : 1a6a3b84-7d6d-4398-9c26-50fab315be8b
|
|
deletionTimestamp :
|
|
displayName : Default Policy
|
|
keyCredentials : {}
|
|
policyType : 18
|
|
policyDetail : {{"Version":0,"State":"Disabled"}}
|
|
policyIdentifier : 2022-11-18T00:16:20.2379877Z
|
|
tenantDefaultPolicy : 18
|
|
|
|
odata.type : Microsoft.DirectoryServices.Policy
|
|
objectType : Policy
|
|
objectId : 7f6ac8e5-bd21-4091-ae4c-0e48e0f4db04
|
|
deletionTimestamp :
|
|
displayName : Block NestorW
|
|
keyCredentials : {}
|
|
policyType : 18
|
|
policyDetail : {{"Version":1,"CreatedDateTime":"2022-11-18T00:16:19.461967Z","State":"Enabled
|
|
","Conditions":{"Applications":{"Include":[{"Applications":["None"]}]},"Users"
|
|
:{"Include":[{"Users":["8ab3ed0d-6668-49f7-a108-c50bb230c870"]}]}},"Controls":
|
|
[{"Control":["Block"]}],"EnforceAllPoliciesForEas":true,"IncludeOtherLegacyCli
|
|
entTypeForEvaluation":true}}
|
|
policyIdentifier :
|
|
tenantDefaultPolicy :
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken
|
|
)
|
|
Process
|
|
{
|
|
# Return conditional access policies
|
|
Get-AzureADPolicies -AccessToken $AccessToken | Where policyType -eq 18
|
|
}
|
|
}
|
|
|
|
# Gets tenant's Azure AD Policies
|
|
# Nov 17th 2022
|
|
function Get-AzureADPolicies
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Shows Azure AD policies.
|
|
|
|
.DESCRIPTION
|
|
Shows Azure AD policies.
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token.
|
|
|
|
.Example
|
|
PS C:\>Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Get-AADIntAzureADPolicies
|
|
|
|
odata.type : Microsoft.DirectoryServices.Policy
|
|
objectType : Policy
|
|
objectId : e35e4cd3-53f8-4d65-80bb-e3279c2c1b71
|
|
deletionTimestamp :
|
|
displayName : On-Premise Authentication Flow Policy
|
|
keyCredentials : {**}
|
|
policyType : 8
|
|
policyDetail : {**}
|
|
policyIdentifier :
|
|
tenantDefaultPolicy : 8
|
|
|
|
odata.type : Microsoft.DirectoryServices.Policy
|
|
objectType : Policy
|
|
objectId : 259b810f-fb50-4e57-925b-ec2292c17883
|
|
deletionTimestamp :
|
|
displayName : 2/5/2021 5:53:07 AM
|
|
keyCredentials : {}
|
|
policyType : 10
|
|
policyDetail : {{"SecurityPolicy":{"Version":0,"SecurityDefaults":{"IgnoreBaselineProtectionPolicies":true,"I
|
|
sEnabled":false}}}}
|
|
policyIdentifier :
|
|
tenantDefaultPolicy : 10
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken
|
|
)
|
|
Process
|
|
{
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
# Call the API
|
|
Call-GraphAPI -AccessToken $AccessToken -Command "policies" -Method Get
|
|
}
|
|
}
|
|
|
|
# Gets tenant's Azure AD Policies
|
|
# Nov 17th 2022
|
|
function Set-AzureADPolicyDetails
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Sets Azure AD policy details.
|
|
|
|
.DESCRIPTION
|
|
Sets Azure AD policy details.
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token.
|
|
|
|
.PARAMETER ObjectId
|
|
Object ID of the policy
|
|
|
|
.PARAMETER PolicyDetail
|
|
Policy details.
|
|
|
|
.PARAMETER DisplayName
|
|
New displayname of the policy
|
|
|
|
.Example
|
|
PS C:\>Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Set-AADIntAzureADPolicyDetail -ObjectId "e35e4cd3-53f8-4d65-80bb-e3279c2c1b71" -PolicyDetail '{{"SecurityPolicy":{"Version":0,"SecurityDefaults":{"IgnoreBaselineProtectionPolicies":true,"IsEnabled":false}}}}'
|
|
|
|
.Example
|
|
PS C:\>Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Set-AADIntAzureADPolicyDetail -ObjectId "e35e4cd3-53f8-4d65-80bb-e3279c2c1b71" -PolicyDetail '{{"SecurityPolicy":{"Version":0,"SecurityDefaults":{"IgnoreBaselineProtectionPolicies":true,"IsEnabled":false}}}}' -displayName "My Policy"
|
|
|
|
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken,
|
|
[Parameter(Mandatory=$True)]
|
|
[Guid]$ObjectId,
|
|
[Parameter(Mandatory=$True)]
|
|
[String]$PolicyDetail,
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$DisplayName
|
|
)
|
|
Process
|
|
{
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
$body = @{
|
|
"policyDetail" = @($PolicyDetail)
|
|
}
|
|
if(![string]::IsNullOrEmpty($DisplayName))
|
|
{
|
|
$body["displayName"] = $DisplayName
|
|
}
|
|
|
|
# Call the API
|
|
Call-GraphAPI -AccessToken $AccessToken -Command "policies/$($ObjectId)" -Method Patch -Body ($body | ConvertTo-Json)
|
|
}
|
|
}
|
|
|
|
# Get Azure AD features
|
|
# Aug 23 2023
|
|
function Get-AzureADFeatures
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Show the status of Azure AD features.
|
|
|
|
.DESCRIPTION
|
|
Show the status of Azure AD features using Azure AD Graph internal API.
|
|
Requires Global Administrator role
|
|
|
|
.Parameter AccessToken
|
|
Access Token
|
|
|
|
.Example
|
|
Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Get-AADIntAzureADFeatures
|
|
|
|
Feature Enabled
|
|
------- -------
|
|
AllowEmailVerifiedUsers True
|
|
AllowInvitations True
|
|
AllowMemberUsersToInviteOthersAsMembers False
|
|
AllowUsersToChangeTheirDisplayName False
|
|
B2CFeature False
|
|
BlockAllTenantAuth False
|
|
ConsentedForMigrationToPublicCloud False
|
|
CIAMFeature False
|
|
CIAMTrialFeature False
|
|
CIAMTrialUpgrade False
|
|
EnableExchangeDualWrite False
|
|
EnableHiddenMembership False
|
|
EnableSharedEmailDomainApis False
|
|
EnableWindowsLegacyCredentials False
|
|
EnableWindowsSupplementalCredentials False
|
|
ElevatedGuestsAccessEnabled False
|
|
ExchangeDualWriteUsersV1 False
|
|
GuestsCanInviteOthersEnabled True
|
|
InvitationsEnabled True
|
|
LargeScaleTenant False
|
|
TestTenant False
|
|
USGovTenant False
|
|
DisableOnPremisesWindowsLegacyCredentialsSync False
|
|
DisableOnPremisesWindowsSupplementalCredentialsSync False
|
|
RestrictPublicNetworkAccess False
|
|
AutoApproveSameTenantRequests False
|
|
RedirectPpeUsersToMsaInt False
|
|
LegacyTlsExceptionForEsts False
|
|
LegacyTlsBlockForEsts False
|
|
TenantAuthBlockReasonFraud False
|
|
TenantAuthBlockReasonLifecycle False
|
|
TenantExcludeDeprecateAADLicenses False
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken
|
|
)
|
|
Begin
|
|
{
|
|
$features = @(
|
|
"AllowEmailVerifiedUsers"
|
|
"AllowInvitations"
|
|
"AllowMemberUsersToInviteOthersAsMembers"
|
|
"AllowUsersToChangeTheirDisplayName"
|
|
"B2CFeature"
|
|
"BlockAllTenantAuth"
|
|
"ConsentedForMigrationToPublicCloud"
|
|
"CIAMFeature"
|
|
"CIAMTrialFeature"
|
|
"CIAMTrialUpgrade"
|
|
"EnableExchangeDualWrite"
|
|
"EnableHiddenMembership"
|
|
"EnableSharedEmailDomainApis"
|
|
"EnableWindowsLegacyCredentials"
|
|
"EnableWindowsSupplementalCredentials"
|
|
"ElevatedGuestsAccessEnabled"
|
|
"ExchangeDualWriteUsersV1"
|
|
"GuestsCanInviteOthersEnabled"
|
|
"InvitationsEnabled"
|
|
"LargeScaleTenant"
|
|
"TestTenant"
|
|
"USGovTenant"
|
|
"DisableOnPremisesWindowsLegacyCredentialsSync"
|
|
"DisableOnPremisesWindowsSupplementalCredentialsSync"
|
|
"RestrictPublicNetworkAccess"
|
|
"AutoApproveSameTenantRequests"
|
|
"RedirectPpeUsersToMsaInt"
|
|
"LegacyTlsExceptionForEsts"
|
|
"LegacyTlsBlockForEsts"
|
|
"TenantAuthBlockReasonFraud"
|
|
"TenantAuthBlockReasonLifecycle"
|
|
"TenantExcludeDeprecateAADLicenses"
|
|
)
|
|
}
|
|
Process
|
|
{
|
|
# Get from cache if not provided
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
$retVal = @()
|
|
|
|
# Loop through the features
|
|
foreach($feature in $features)
|
|
{
|
|
try
|
|
{
|
|
$value = Get-AzureADFeature -AccessToken $AccessToken -Feature $feature
|
|
|
|
$retVal += [pscustomobject][ordered]@{
|
|
"Feature" = $feature
|
|
"Enabled" = $value
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
$retVal
|
|
|
|
|
|
}
|
|
}
|
|
|
|
# Get Azure AD feature status
|
|
# Aug 23 2023
|
|
function Get-AzureADFeature
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Show the status of given Azure AD feature.
|
|
|
|
.DESCRIPTION
|
|
Show the status of given Azure AD feature using Azure AD Graph internal API.
|
|
Requires Global Administrator role
|
|
|
|
.Parameter AccessToken
|
|
Access Token
|
|
|
|
.PARAMETER Feature
|
|
The name of the feature. Should be one of:
|
|
|
|
AllowEmailVerifiedUsers
|
|
AllowInvitations
|
|
AllowMemberUsersToInviteOthersAsMembers
|
|
AllowUsersToChangeTheirDisplayName
|
|
B2CFeature
|
|
BlockAllTenantAuth
|
|
ConsentedForMigrationToPublicCloud
|
|
CIAMFeature
|
|
CIAMTrialFeature
|
|
CIAMTrialUpgrade
|
|
EnableExchangeDualWrite
|
|
EnableHiddenMembership
|
|
EnableSharedEmailDomainApis
|
|
EnableWindowsLegacyCredentials
|
|
EnableWindowsSupplementalCredentials
|
|
ElevatedGuestsAccessEnabled
|
|
ExchangeDualWriteUsersV1
|
|
GuestsCanInviteOthersEnabled
|
|
InvitationsEnabled
|
|
LargeScaleTenant
|
|
TestTenant
|
|
USGovTenant
|
|
DisableOnPremisesWindowsLegacyCredentialsSync
|
|
DisableOnPremisesWindowsSupplementalCredentialsSync
|
|
RestrictPublicNetworkAccess
|
|
AutoApproveSameTenantRequests
|
|
RedirectPpeUsersToMsaInt
|
|
LegacyTlsExceptionForEsts
|
|
LegacyTlsBlockForEsts
|
|
TenantAuthBlockReasonFraud
|
|
TenantAuthBlockReasonLifecycle
|
|
TenantExcludeDeprecateAADLicenses
|
|
|
|
.Example
|
|
Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Get-AADIntAzureADFeature -Feature "B2CFeature"
|
|
|
|
True
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken,
|
|
[ValidateSet('AllowEmailVerifiedUsers','AllowInvitations','AllowMemberUsersToInviteOthersAsMembers','AllowUsersToChangeTheirDisplayName','B2CFeature','BlockAllTenantAuth','ConsentedForMigrationToPublicCloud','CIAMFeature','CIAMTrialFeature','CIAMTrialUpgrade','EnableExchangeDualWrite','EnableHiddenMembership','EnableSharedEmailDomainApis','EnableWindowsLegacyCredentials','EnableWindowsSupplementalCredentials','ElevatedGuestsAccessEnabled','ExchangeDualWriteUsersV1','GuestsCanInviteOthersEnabled','InvitationsEnabled','LargeScaleTenant','TestTenant','USGovTenant','DisableOnPremisesWindowsLegacyCredentialsSync','DisableOnPremisesWindowsSupplementalCredentialsSync','RestrictPublicNetworkAccess','AutoApproveSameTenantRequests','RedirectPpeUsersToMsaInt','LegacyTlsExceptionForEsts','LegacyTlsBlockForEsts','TenantAuthBlockReasonFraud','TenantAuthBlockReasonLifecycle','TenantExcludeDeprecateAADLicenses')]
|
|
[Parameter(Mandatory=$True)]
|
|
[String]$Feature
|
|
)
|
|
Process
|
|
{
|
|
# Get from cache if not provided
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
$body = @{
|
|
"directoryFeature" = $feature
|
|
}
|
|
|
|
# Call the API
|
|
try
|
|
{
|
|
$response = Call-GraphAPI -AccessToken $AccessToken -Command "isDirectoryFeatureEnabled" -Method Post -Body ($body | ConvertTo-Json)
|
|
|
|
$enabled = $false;
|
|
|
|
# For some reason True is returned as boolean but False as object with value attribute
|
|
if($response -isnot [boolean])
|
|
{
|
|
$enabled = $response.Value
|
|
}
|
|
else
|
|
{
|
|
$enabled = $response
|
|
}
|
|
|
|
return $enabled
|
|
}
|
|
catch
|
|
{
|
|
$stream = $_.Exception.Response.GetResponseStream()
|
|
$responseBytes = New-Object byte[] $stream.Length
|
|
|
|
$stream.Position = 0
|
|
$stream.Read($responseBytes,0,$stream.Length) | Out-Null
|
|
|
|
$response = [text.encoding]::UTF8.GetString($responseBytes) | ConvertFrom-Json
|
|
|
|
throw $response.'odata.error'.message.value
|
|
}
|
|
}
|
|
}
|
|
|
|
# Enable or Disable Azure AD feature
|
|
# Aug 23 2023
|
|
function Set-AzureADFeature
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Enables or disables the given Azure AD feature.
|
|
|
|
.DESCRIPTION
|
|
Enables or disables the given Azure AD feature using Azure AD Graph internal API.
|
|
Requires Global Administrator role
|
|
|
|
.Parameter AccessToken
|
|
Access Token
|
|
|
|
.PARAMETER Feature
|
|
The name of the feature. Should be one of:
|
|
|
|
AllowEmailVerifiedUsers
|
|
AllowInvitations
|
|
AllowMemberUsersToInviteOthersAsMembers
|
|
AllowUsersToChangeTheirDisplayName
|
|
B2CFeature
|
|
BlockAllTenantAuth
|
|
ConsentedForMigrationToPublicCloud
|
|
CIAMFeature
|
|
CIAMTrialFeature
|
|
CIAMTrialUpgrade
|
|
EnableExchangeDualWrite
|
|
EnableHiddenMembership
|
|
EnableSharedEmailDomainApis
|
|
EnableWindowsLegacyCredentials
|
|
EnableWindowsSupplementalCredentials
|
|
ElevatedGuestsAccessEnabled
|
|
ExchangeDualWriteUsersV1
|
|
GuestsCanInviteOthersEnabled
|
|
InvitationsEnabled
|
|
LargeScaleTenant
|
|
TestTenant
|
|
USGovTenant
|
|
DisableOnPremisesWindowsLegacyCredentialsSync
|
|
DisableOnPremisesWindowsSupplementalCredentialsSync
|
|
RestrictPublicNetworkAccess
|
|
AutoApproveSameTenantRequests
|
|
RedirectPpeUsersToMsaInt
|
|
LegacyTlsExceptionForEsts
|
|
LegacyTlsBlockForEsts
|
|
TenantAuthBlockReasonFraud
|
|
TenantAuthBlockReasonLifecycle
|
|
TenantExcludeDeprecateAADLicenses
|
|
|
|
.Example
|
|
Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Set-AADIntAzureADFeature -Feature "B2CFeature" -Enable $true
|
|
|
|
Feature Enabled
|
|
------- -------
|
|
B2CFeature True
|
|
|
|
.Example
|
|
Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Set-AADIntAzureADFeature -Feature "B2CFeature" -Enable $false
|
|
|
|
Feature Enabled
|
|
------- -------
|
|
B2CFeature False
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken,
|
|
[ValidateSet('AllowEmailVerifiedUsers','AllowInvitations','AllowMemberUsersToInviteOthersAsMembers','AllowUsersToChangeTheirDisplayName','B2CFeature','BlockAllTenantAuth','ConsentedForMigrationToPublicCloud','CIAMFeature','CIAMTrialFeature','CIAMTrialUpgrade','EnableExchangeDualWrite','EnableHiddenMembership','EnableSharedEmailDomainApis','EnableWindowsLegacyCredentials','EnableWindowsSupplementalCredentials','ElevatedGuestsAccessEnabled','ExchangeDualWriteUsersV1','GuestsCanInviteOthersEnabled','InvitationsEnabled','LargeScaleTenant','TestTenant','USGovTenant','DisableOnPremisesWindowsLegacyCredentialsSync','DisableOnPremisesWindowsSupplementalCredentialsSync','RestrictPublicNetworkAccess','AutoApproveSameTenantRequests','RedirectPpeUsersToMsaInt','LegacyTlsExceptionForEsts','LegacyTlsBlockForEsts','TenantAuthBlockReasonFraud','TenantAuthBlockReasonLifecycle','TenantExcludeDeprecateAADLicenses')]
|
|
[Parameter(Mandatory=$True)]
|
|
[String]$Feature,
|
|
[Parameter(Mandatory=$True)]
|
|
[bool]$Enabled
|
|
)
|
|
Process
|
|
{
|
|
# Get from cache if not provided
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
$isEnabled = Get-AzureADFeature -Feature $feature -AccessToken $AccessToken
|
|
|
|
if($Enabled)
|
|
{
|
|
# Check if already enabled
|
|
if($isEnabled)
|
|
{
|
|
Write-Warning "Feature $feature is already enabled."
|
|
return
|
|
}
|
|
$command = "enableDirectoryFeature"
|
|
}
|
|
else
|
|
{
|
|
# Check if already disabled
|
|
if(!$isEnabled)
|
|
{
|
|
Write-Warning "Feature $feature is already disabled."
|
|
return
|
|
}
|
|
$command = "disableDirectoryFeature"
|
|
}
|
|
|
|
$body = @{
|
|
"directoryFeature" = $feature
|
|
}
|
|
|
|
# Call the API
|
|
try
|
|
{
|
|
Call-GraphAPI -AccessToken $AccessToken -Command $command -Method Post -Body ($body | ConvertTo-Json)
|
|
}
|
|
catch
|
|
{
|
|
$stream = $_.Exception.Response.GetResponseStream()
|
|
$responseBytes = New-Object byte[] $stream.Length
|
|
|
|
$stream.Position = 0
|
|
$stream.Read($responseBytes,0,$stream.Length) | Out-Null
|
|
|
|
$response = [text.encoding]::UTF8.GetString($responseBytes) | ConvertFrom-Json
|
|
|
|
throw $response.'odata.error'.message.value
|
|
}
|
|
|
|
|
|
[pscustomobject][ordered]@{
|
|
"Feature" = $feature
|
|
"Enabled" = Get-AzureADFeature -AccessToken $AccessToken -Feature $feature
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
# Adds Microsoft.Azure.SyncFabric service principal
|
|
# Dec 4th 2023
|
|
function Add-SyncFabricServicePrincipal
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Adds Microsoft.Azure.SyncFabric service principal needed to create BPRTs.
|
|
|
|
.DESCRIPTION
|
|
Adds Microsoft.Azure.SyncFabric service principal needed to create BPRTs.
|
|
|
|
Requires Application Administrator, Cloud Application Administrator, Directory Synchronization Accounts, Hybrid Identity Administrator, or Global Administrator permissions.
|
|
|
|
.Parameter AccessToken
|
|
The Access Token. If not given, tries to use cached Access Token.
|
|
|
|
.Example
|
|
PS C:\>Get-AADIntAccessTokenForAADGraph -SaveToCache
|
|
PS C:\>Add-AADIntSyncFabricServicePrincipal
|
|
|
|
DisplayName AppId ObjectId
|
|
----------- ----- --------
|
|
Microsoft.Azure.SyncFabric 00000014-0000-0000-c000-000000000000 138018f7-6aa2-454c-a103-a7e682e17d6b
|
|
#>
|
|
[cmdletbinding()]
|
|
Param(
|
|
[Parameter(Mandatory=$False)]
|
|
[String]$AccessToken
|
|
)
|
|
Process
|
|
{
|
|
$AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -ClientID "1b730954-1685-4b74-9bfd-dac224a7b894" -Resource "https://graph.windows.net"
|
|
|
|
|
|
$body = @{
|
|
"accountEnabled" = "True"
|
|
"appId" = "00000014-0000-0000-c000-000000000000"
|
|
"appRoleAssignmentRequired" = $false
|
|
"displayName" = "Microsoft.Azure.SyncFabric"
|
|
"tags" = @( "WindowsAzureActiveDirectoryIntegratedApp" )
|
|
}
|
|
|
|
# Call the API
|
|
$result = Call-GraphAPI -AccessToken $AccessToken -Command "servicePrincipals" -Body ($body | ConvertTo-Json) -Method Post
|
|
|
|
if($result)
|
|
{
|
|
[pscustomobject]@{
|
|
"DisplayName" = $result.displayName
|
|
"AppId" = $result.appId
|
|
"ObjectId" = $result.objectId
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
} |