How do you (quickly) count AAD B2C users? - microsoft-graph-api

We're trying to count the number of user objects in a B2C tenant, which is somewhat large. When it was small, the simple/obvious hack of just reading all the users worked easily and quickly.
Get-AzADUser | Measure-Object
Now this takes an absurd amount of time (30+ mins, and wastes AAD processing, network bandwidth, etc). Handily, the Graph API includes an endpoint to request the number of objects! Hooray! ;) https://learn.microsoft.com/en-us/graph/api/user-list?view=graph-rest-beta&tabs=http#example-6-get-only-a-count-of-users
Connect-AzAccount
Set-AzContext -Tenant <your 'normal' AAD tenant>
$AzToken = Get-AzAccessToken -ResourceUrl https://graph.microsoft.com
Invoke-RestMethod -Method Get -Authentication Bearer -Token (ConvertTo-SecureString -AsPlainText -Force -String $AZAccess.Token) -Headers #{ConsistencyLevel = 'eventual'} -Uri https://graph.microsoft.com/beta/users/`$count
1234
But! When using this method to attempt to find how many B2C accounts we have:
Connect-AzAccount
Set-AzContext -Tenant <your 'B2C' AAD tenant>
$AzToken = Get-AzAccessToken -ResourceUrl https://graph.microsoft.com
Invoke-RestMethod -Method Get -Authentication Bearer -Token (ConvertTo-SecureString -AsPlainText -Force -String $AZAccess.Token) -Headers #{ConsistencyLevel = 'eventual'} -Uri https://graph.microsoft.com/beta/users/`$count
Invoke-RestMethod: {"error":{"code":"Request_BadRequest","message":"$count is not currently supported.","innerError":{"date":"2021-04-29T07:06:09","request-id":"xxx","client-request-id":"xxx"}}}
So, how do you count users in a large B2C tenant?

Unfortunately the endpoint is not supported yet for B2C tenant. Neither does https://graph.microsoft.com/beta/users?$count=true.
It's only available in normal AAD tenant.
Currently you need to list all the users and get their count using method/function from other library.
A similar post and answer here for your reference.

This is a bit manual, but whenever I need a quick count, I do the following:
Go to Azure Portal (for B2C Tenant)
All Users
Bulk operations
Download users (This will get me an excel pretty quick)
Start
Takes about 2 minutes to finish (~40k users)
Go to Bulk operation results in page menu on the left
Download Excel
sum of UPNs in the excel

This should work for a B2C Tenant , using Connect-AzureAD in the AzureAD Module
Connect-AzureAD -tenant xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
(Get-AzureADUser -all $true).Count

Related

create mailbox along with Create users graph api in o365

We have a requirement to create office 365 user with mail account through create_user graph api. But user has been created successfully but mail account did not created.
Let us know api name to create user with mail account directly through api.
Microsoft Graph API doesn't has the feature. For mailbox creation, you need to use Exchange PowerShell to do it using New-Mailbox cmdlet. You can automate the Exchange PowerShell with .Net as well :)
For example,
$password = Read-Host "Enter password" -AsSecureString
New-Mailbox -UserPrincipalName chris#contoso.com -Alias chris -Database "Mailbox Database 1" -Name ChrisAshton -OrganizationalUnit Users -Password $password -FirstName Chris -LastName Ashton -DisplayName "Chris Ashton" -ResetPasswordOnNextLogon $true
To do this through the graph API you need to have a license that has Exchange Online as a service plan like Microsoft 365 F3 (SPE_F1), assign your new user one these licenses on creation and a Mailbox will be created for them:
Post the following:
{
"addLicenses": [
{
"skuId": "your SPE_F1 skuId number"
}
],
"removeLicenses": []
}
to:
https://graph.microsoft.com/v1.0/users/{user - id}/assignLicense/

How to specify git author/committer for PullRequest merge in Azure DevOps?

I have defined a release pipeline to synchronize code between two git repositories in Azure DevOps. The process requires a PullRequest in the destination repo which is created and completed using the WebAPI.
The pipeline is executed by the build agent running using a Windows domain service account. So, the PullRequest is created and completed on behalf of the service account, which is also mentioned as author, committer, etc. in the git history after merge is completed. (According to our rules the PR must be merged using squash commit.)
I would like see a different user in the git history after (squash) merge.
Can I specify the user (e.g. the user triggering the release pipeline) using WebAPI?
I did not find such option in the API documentation.
Any other recommendation? Maybe convention like adding "co-authored-by" to commit message like github?
When you use Pull Requests-Create rest api to create a pull request, the pull request creator is determined by the creator of the PAT you used for authentication (e.g. I used the PAT of hughl01 user as the authentication to create the pull request, then the creator of the pull request is hughl01).
Test in Postman:
Sample test script in powershell task:
$token = "{User-created PAT}"
$url = "https://dev.azure.com/{org}/{pro}/_apis/git/repositories/{repoId}/pullrequests?api-version=6.0"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
$JSON = #'
{
"sourceRefName": "refs/heads/dev2",
"targetRefName": "refs/heads/master",
"title": "ForTest",
"description": "Adding a new feature"
}
'#
$response = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Post -ContentType application/json -body $JSON
You can create a variable group, with the release trigger as the variable name, and the PAT corresponding to the user as the variable value and set the value of the variable to secret. Then get the name of the triggerer through the predefined variable $(Release.RequestedFor) in the script, then obtain the corresponding PAT according to the trigger name to create pull request.

Microsoft Graph API duplicate users

I’m calling the Microsoft graph restful api in powershell to receive users from my organisation and all works splendidly when i want to use a full import. But when I try /users/delta I receive a large number of duplicates.
In my test environment it’s not an issue (the script runs for a couple of seconds long for a thousand users) but in the production environment of 70k users it returns 160k records. I need to use delta so that I can store the delta token somewhere and for future delta not require reading all 70k users again needlessly.
I have tried adding /users/delta?$Filter=&$distinct(UserPrincipalName) also with id and it still returns the duplicate users. Does anyone have a clue about how I can filter out the duplicates in the api call?
$Version = ‘Beta’
$BatchSize = 500
$Uri = "https://graph.microsoft.com/$Version/Users/delta?top=$BatchSize"
$users = $null
do{#read all pages into a single array
try
{ #Get api data
$response2 = Invoke-RestMethod -Method Get -Uri $Uri -Headers $Global:AuthHeader
}
catch
{
Log -ExtraLogging $Global:Debug -LoggingLevel 1 -ErrorCode 2 -Message "$($_.Exception). terminating run profile"
exit
}
if($response2 -ne $null) #if multiple pages read all pages at once
{
$Uri = $response2.'#odata.nextlink'
$users = $users + $response2.value
}
}until ($Uri -eq $null -or $Uri -contains 'Error')
How are you returning all the users? since there is a 999 return limit per page for the users graph endpoint. I have a feeling that your own code is causing duplicates and not the graph endpoint. I tried running the command on a huge tenant and I don't get duplicates at all, but then again it only shows max 999 at a time. then you have to use the nextlink to get the next batch of users. most likely somewhere in your powershell logic you ended up returning the same thing twice somewhere.
But you would have to give more details about your script if you want more help.

How to get RecipientTypeDetails through the MS Graph API

Is it possible to get the RecipientTypeDetails property of a mailbox through any (Graph) REST API? From my research I've been seeing No's as answers, but I didn't find any recent confirmation.
Thanks in advance!
I use exchange-online-powershell to get RecipientTypeDetails to retrieve all the mailboxes of a recipient type. I couple this with MS Graph. However, I couldn't retrieve the mailboxes of a certain type using MS graph.
So you can do something like this in powershell.
$recipientTypes = Get-Recipient -ResultSize unlimited
Then use it to retrieve mailboxes of a type and output to file. Unsure how you want to use it.
foreach($recType in $recipientTypes)
{
$mailboxes = (Get-Mailbox -Filter '(RecipientTypeDetails -eq $($recType))')
ConvertTo-Json -InputObject $mailboxes | Out-File ".\Mailboxes-$($recType).json"
}
The module I use is:
Install-Module -Name ExchangeOnlineManagement -RequiredVersion 2.0.4-Preview2 -AllowPrerelease`
it seems to be something exposed for Exchange on premises via a powershell cmlet named Get-Recipient. It is not exposed via Graph Rest Apis after inspecting the docs and playing around with graph explorer. The user object doesn't have a mailbox property, it has a messages collection.
In the docs there is guidance indicating that for cloud environments you can invoke the cmdlet with the RecipientTypeDetails set to GroupMailBox.

Error 400 Bad Request when attempting to pull Skype for Business activity via Graph API

Alright, so after chatting with Microsoft "Professional Support" they couldn't help me. Told me to access the reports via the SfB Report GUI and export to Excel.
Yeah that's completely worthless to me.
After doing a lot more reading, my 1st example to authenticate was out of date.
Now I have a fully functional oAuth2 PowerShell script that gets me a valid token.
But I'm having the same issue when I use the Graph Explorer (403 Forbidden).
I know the token is working because I can query other information \ if I take away the VAR for the token from the GET header it errors stating the the Bearer Token is empty so everything is right.
Microsoft, if you're out there can someone please confirm that the SfB Report API is up and running for the statistics I'm attempting to pull?
UPDATED SCRIPT
#Obtaining oAuth2 Token from Microsoft Azure \ communicate with Microsoft Graph API
$ClientID = "MyID"
$client_Secret = "MySecretKey"
#Define URI for Azure Tenant
$Uri = "https://login.microsoftonline.com/MyTenantID/oauth2/token"
#Define Microsoft Graph - Skype for Business reports interface URI
$exportSfB = "https://graph.microsoft.com/beta/reports/SfbActivity(view='Detail',date='2017-04-11')/content"
#Define the body of the request
$Body = #{grant_type='client_credentials';client_id=$ClientID;client_secret=$client_secret;resource='https://graph.microsoft.com'}
#Define the content type for the request
$ContentType = "application/x-www-form-urlencoded"
#Invoke REST method. This handles the deserialization of the JSON result. Less effort than invoke-webrequest
$admAuth=Invoke-RestMethod -Uri $Uri -Body $Body -Method Post
#Construct the header value with the access_token just recieved
$HeaderValue = "Bearer " + $admauth.access_token
#Query Microsoft Graph with new Token
$result = Invoke-RestMethod -Headers #{Authorization=$HeaderValue} -Uri $exportSfB –Method Get -Verbose
#Results should be a .CSV
$result.string.'#text'
ORIGINAL THREAD
Can someone please have a look at this REST code and tell me what they think?
I'm receiving:
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
CategoryInfo : InvalidOperation
I haven't been able to pull a single Skype for Business activity report using Graph.
$tenant = "MyTenant.onmicrosoft.com"
function GetAuthToken
{
param
(
[Parameter(Mandatory=$true)]
$TenantName
)
$adal = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$adalforms = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll"
[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null
[System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null
$clientId = "MyID"
$redirectUri = "urn:ietf:wg:oauth:2.0:oob"
$resourceAppIdURI = "https://graph.microsoft.com/"
$authority = "https://login.windows.net/$TenantName"
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId,$redirectUri, "Auto")
return $authResult
}
# Set Token var
$token = GetAuthToken -TenantName $tenant
# Building Rest Api header with authorization token
$authHeader = #{
'Content-Type'='application\json'
'Authorization'=$token.CreateAuthorizationHeader()
}
$uri = "https://graph.microsoft.com/beta/reports/SfbActivity(view='Detail',date='2017-04-11')"
$output = (Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get –Verbose).value
You're missing /content in your URI. See doc here.
$uri = "https://graph.microsoft.com/beta/reports/SfbActivity(view='Detail',date='2017-04-11')/content"
Ok so after messing with the API and reading I decided to start over from scratch.
Turns out the problem the entire time was the App type in Azure. I was using an app that someone had created prior to me taking on the project. It's application type was set to "Web \ API" in Azure which was incorrect apparently. I created a new App with application type "Native", altered my code with the new secret access key and application client ID and I was able to start pulling down .csv files. The problem now is that the PSTN data isn't there. I created a ticket with the Microsoft Graph group on GitHub requesting information about whether or not they're aware of this problem. At this time, I'm unable to find a programmatic method of exporting PSTN call details via the API. You can keep an eye on their progress here for that request but beyond that I'm stuck until Microsoft Dev makes the SfBActivity detail report include those data fields: https://github.com/microsoftgraph/microsoft-graph-docs/issues/1133

Resources