AdminAPI.ps1
# This file contains functions utilising https://admin.microsoft.com API # Approves the delegated admin request # Sep 22nd 2021 function Approve-MSPartnerDelegatedAdminRequest { <# .SYNOPSIS Assigns Delegated Admin Permissions (DAP) for the given partner organisation. .DESCRIPTION Assigns Delegated Admin Permissions (DAP) for the given partner organisation. .Parameter TenantId TenantId of the partner organisation. .Parameter Domain Any registered domain of the partner organisation. .Example PS C:\>Get-AADIntAccessTokenForAdmin -SaveToCache PS C:\>Approve-AADIntMSPartnerDelegatedAdminRequest -Domain company.com responseCode message ------------ ------- success .Example PS C:\>Get-AADIntAccessTokenForAdmin -SaveToCache PS C:\>Approve-AADIntMSPartnerDelegatedAdminRequest -TenantId c7e52a77-e461-4f2e-a652-573305414be9 responseCode message ------------ ------- success #> [cmdletbinding()] Param( [Parameter(ParameterSetName='TenantId',Mandatory=$True)] [guid]$TenantId, [Parameter(ParameterSetName='Domain',Mandatory=$True)] [String]$Domain, [Parameter(Mandatory=$False)] [String]$AccessToken ) Process { if($Domain) { $TenantId = Get-TenantID -Domain $Domain } $body = @{ "authorizeDelegateAdminData" = [ordered]@{ "msppId" = 0 "partnerId" = $TenantId "companyName" = " " "indirectCSPId" = "" "userTenantId" = (Read-Accesstoken $AccessToken).tid "enableDap" = $true "invitationType" = "Administration" "address" = $null "roles" = @( "62e90394-69f5-4237-9190-012177145e10" # Global Administrator "729827e3-9c14-49f7-bb1b-9608f156bbb8" # Helpdesk Administrator ) "userPrincipalName" = $null } } try { $response = Invoke-AdminAPI -Method Post -AccessToken $AccessToken -Url "fd/commerceMgmt/partnermanage/partners/csp/delegatedaccess?api-version=2.1" -Body ($body | ConvertTo-Json) } catch { Write-Error ($_.ErrorDetails.Message | ConvertFrom-Json).error.message return } $response } } # Gets the list of partners # Dec 9th 2021 function Get-MSPartners { <# .SYNOPSIS Shows organisation's partners. .DESCRIPTION Shows organisation's partners using Admin API. .Parameter AccessToken Access token to retrieve partners. .Example PS C:\>Get-AADIntAccessTokenForAdmin -SaveToCache PS C:\>Get-AADIntMSPartners Identity : b1f6d5cc-f1d3-41d9-b88c-1d177aaf171b DisplayName : Partner Ltd Email : pmanager@company.com Website : http://www.company.com Phone : +1234567890 Relationship : Indirect Reseller and Admin TypeDetail : PartnerAdmin CanDelete : False CanRemoveDap : True AllDataRetrieved : True #> [cmdletbinding()] Param( [Parameter(Mandatory=$False)] [String]$AccessToken ) Process { try { $response = Invoke-AdminAPI -AccessToken $AccessToken -Url "admin/api/Partners/GetPartners" -Method Post } catch { if($_.ErrorDetails.Message) { throw $_.ErrorDetails.Message } else { throw $_.Exception.Message } return } $response } } # Returns access token for the requested resource # Dec 9th 2021 function Get-AccessTokenUsingAdminAPI { <# .SYNOPSIS Gets access token for the requested resource using Admin API. .DESCRIPTION Gets access token for the requested resource using Admin API. The client id of the retuned access token is 00000006-0000-0ff1-ce00-000000000000 (Microsoft Office 365 Portal). .Parameter Access Some supported type of access token. .Parameter TokenType The type of the access token to return. Can be one of "PortalAT","BusinessStoreAT" .Parameter Resource Gets an access token for the given resource. Can be one of "https://management.core.windows.net/","https://graph.microsoft.com/" .Example PS C:\>Get-AADIntAccessTokenForAdmin -SaveToCache PS C:\>$at = Get-AADIntAccessTokenUsingAdminAPI -TokenType PortalAT .Example PS C:\>Get-AADIntAccessTokenForAdmin -SaveToCache PS C:\>$at = Get-AADIntAccessTokenUsingAdminAPI -Resource https://management.core.windows.net/ #> [cmdletbinding()] Param( [Parameter(ParameterSetName='Normal',Mandatory=$True)] [ValidateSet('PortalAT','BusinessStoreAT')] [String]$TokenType, [Parameter(ParameterSetName='Resource',Mandatory=$True)] [ValidateSet('https://graph.microsoft.com/','https://management.core.windows.net/')] [String]$Resource, [Parameter(Mandatory=$False)] [String]$AccessToken, [Parameter(Mandatory=$False)] [Microsoft.PowerShell.Commands.WebRequestSession]$WebSession, [Parameter(Mandatory=$False)] [bool]$SaveToCache=$False ) Process { if($TokenType) { $access_token = Invoke-AdminAPI -AccessToken $AccessToken -Url "admin/api/users/getuseraccesstoken?tokenType=$TokenType" -Method Get -WebSession $WebSession } else { $access_token = Invoke-AdminAPI -AccessToken $AccessToken -Url "admin/api/users/token" -Method Post -Body "=$Resource" } if($SaveToCache) { Add-AccessTokenToCache -AccessToken $access_token } else { $access_token } } } # Approves the delegated admin request # Dec 11th 2021 function Remove-MSPartnerDelegatedAdminRoles { <# .SYNOPSIS Removes Delegated Admin Permissions (DAP) from the given partner organisation. .DESCRIPTION Removes Delegated Admin Permissions (DAP) from the given partner organisation. .Parameter TenantId TenantId of the partner organisation. .Parameter Domain Any registered domain of the partner organisation. .Example PS C:\>Get-AADIntAccessTokenForAdmin -SaveToCache PS C:\>Remove-AADIntMSPartnerDelegatedAdminRoles -Domain company.com responseCode message ------------ ------- success .Example PS C:\>Get-AADIntAccessTokenForAdmin -SaveToCache PS C:\>Remove-AADIntMSPartnerDelegatedAdminRoles -TenantId c7e52a77-e461-4f2e-a652-573305414be9 responseCode message ------------ ------- success #> [cmdletbinding()] Param( [Parameter(ParameterSetName='TenantId',Mandatory=$True)] [guid]$TenantId, [Parameter(ParameterSetName='Domain',Mandatory=$True)] [String]$Domain, [Parameter(Mandatory=$False)] [String]$AccessToken ) Process { if($Domain) { $TenantId = Get-TenantID -Domain $Domain } try { $response = Invoke-AdminAPI -Method Delete -AccessToken $AccessToken -Url "fd/commerceMgmt/partnermanage/partners/csp/$TenantId/delegatedaccess?api-version=2.1" } catch { Write-Error ($_.ErrorDetails.Message | ConvertFrom-Json).error.message return } $response } } # Returns tenant organisation information # Jan 26th 2022 function Get-TenantOrganisationInformation { <# .SYNOPSIS Returns organisation information for the given tenant. .DESCRIPTION Returns organisation information for the given tenant using commercial API used to get Partner Tenant information. .Parameter AccessToken Access Token used to fetch information. Can be any standard user of any tenant. .Parameter TenantId TenantId of the target tenant. .Parameter Domain Domain name of the target tenant. .Example PS C:\>Get-AADIntAccessTokenForAdmin -SaveToCache PS C:\>Get-AADIntTenantOrganisationInformation -Domain "company.com" TenantId : 043050e2-7993-416a-ae66-108ab1951612 CompanyName : Company Ltd StreetAddress : 10 Wall Street ApartmentOrSuite : 666 City : New York StateOrProvince : NY PostalCode : 10005 CountryCode : US PhoneNumber : 1234567890 FirstName : John LastName : Doe #> Param( [Parameter(Mandatory=$False)] [String]$AccessToken, [Parameter(ParameterSetName='Domain',Mandatory=$True)] [String]$Domain, [Parameter(ParameterSetName='TenantId',Mandatory=$True)] [guid]$TenantId ) Process { # Get from cache if not provided $AccessToken = Get-AccessTokenFromCache -AccessToken $AccessToken -Resource "https://admin.microsoft.com" -ClientId "d3590ed6-52b3-4102-aeff-aad2292ab01c" if($Domain) { [guid]$TenantId = [guid](Get-TenantID -Domain $Domain) } if($TenantId -eq ([guid](Read-AccessToken $AccessToken).tid)) { Write-Error "Can't query information from your own tenant. Log in to another tenant and try again." return } $headers = @{ "Authorization" = "Bearer $AccessToken" "Accept" = "application/json; charset=utf-8" } $response = Invoke-WebRequest -UseBasicParsing -uri "https://admin.microsoft.com/fd/commerceMgmt/partnermanage/partners/csp/$($TenantId.toString())/delegatedaccess?invType=Administration&api-version=2.1" -Headers $headers # Content is utf-8 encoded json, but response headers don't have encoding information $responseBytes = New-Object byte[] $response.RawContentLength $response.RawContentStream.Read($responseBytes,0,$response.RawContentLength) $responseObj = ConvertFrom-Json -InputObject ([text.encoding]::UTF8.GetString($responseBytes)) $tenantInfo = $responseObj.authorizeDelegateAdminData $attributes = [ordered]@{ "TenantId" = $tenantInfo.partnerId "CompanyName" = $tenantInfo.companyName "StreetAddress" = $tenantInfo.address.line1 "ApartmentOrSuite" = $tenantInfo.address.line2 #"Line3" = $tenantInfo.address.line3 "City" = $tenantInfo.address.city "StateOrProvince" = $tenantInfo.address.state "PostalCode" = $tenantInfo.address.postalCode "CountryCode" = $tenantInfo.address.countryCode "PhoneNumber" = $tenantInfo.address.phoneNumber "FirstName" = $tenantInfo.address.firstName "LastName" = $tenantInfo.address.lastName } New-Object psobject -Property $attributes } } |