Friday, January 24, 2020

How to set Always On for Azure Function app via PowerShell

If you run Azure functions on dedicated App service plan (vs Consumption plan) of Basic pricing tier and above you may speed up warmup time of Azure functions by enabling Always On setting (Azure Function app > Configuration > General settings):

If you need to automate this process here is the PowerShell script which can be used in order to set Always On for Azure Function app:

$resourceGroupName = ...
$functionAppName = ...
$webAppPropertiesObject = @{"siteConfig" = @{"AlwaysOn" = $true}}
$webAppResource = Get-AzureRmResource -ResourceType "microsoft.web/sites" -ResourceGroupName $resourceGroupName -ResourceName $functionAppName
$webAppResource | Set-AzureRmResource -PropertyObject $webAppPropertiesObject -Force

After that you Function app will have Always On setting enabled.

Tuesday, January 21, 2020

Get Azure AD groups images from Graph API using delegated permissions

In order to get Azure AD group image you need to use the following Graph API endpoint:

GET /groups/{id}/photo/$value

If you checked my previous blog post Why you should be careful with /groups/{id}/photo and /users/{id}/photo endpoints in MS Graph or unintentional getting photos of big sizes in Graph then you probably know that it is better to specify group size in endpoint – otherwise you will get biggest available high resolution image for the group. E.g. this is how you may get image with 64x64 px size:

GET /groups/{id}/photos/64x64//$value

However there is another problem with fetching groups images from Graph API which you have to care about: it should be done using delegated permissions. I.e. it is not possible to retrieve AAD groups images from Graph API using application permissions (at least on the moment of writing this blog post).

If you use Graph client library for C# you first need to create GraphServiceClient object and provide instance of class which implements IAuthenticationProvider interface and contains logic for authenticating requests using delegated permissions (via username and password). Here is how it may look like:

public class AzureAuthenticationProviderDelegatedPermissions : IAuthenticationProvider
{
 public async Task AuthenticateRequestAsync(HttpRequestMessage request)
 {
  var delegatedAccessToken = await GetGraphAccessTokenForDelegatedPermissionsAsync();

  request.Headers.Add("Authorization", "Bearer " + delegatedAccessToken);
 }

 public async Task<string> GetGraphAccessTokenForDelegatedPermissionsAsync()
 {
  string clientId = ...
  string userName = ...
  string password = ...
  string tenant = ...
  
  var creds = new UserPasswordCredential(userName, password);
  var authContext = new AuthenticationContext(string.Format("https://login.microsoftonline.com/{0}", tenant));
  var authResult = await authContext.AcquireTokenAsync("https://graph.microsoft.com", clientId, creds);
  return authResult.AccessToken;
 }
}

var graphClientDelegated = new GraphServiceClient(new AzureAuthenticationProviderDelegatedPermissions());

After that we may fetch group image from Graph API like that:

                var stream = Task.Run(async () =>
                {
                    var photo = await graphClient.Groups[groupId].Photos["64x64"].Content.Request().GetAsync();
                    return photo;

                }).GetAwaiter().GetResult();

Actual user account which is used for fetching groups images doesn’t need any special permissions: it may be regular user account without any admin rights.

Friday, January 17, 2020

Problems with Teams creation via beta teams Graph endpoint with owner without O365 license

When you create Team by sending HTTP POST request to beta Graph endpoint /beta/teams (see Create team) you need to specify exactly 1 user as an owner of the new team:

POST https://graph.microsoft.com/beta/teams
Content-Type: application/json
{
  "displayName": "Test",
  "owners@odata.bind": [
    "https://graph.microsoft.com/beta/users('userId')"
  ]
}

where userId is login name of the user which will be owner of the group. However this request may fail with the following error:

Invoking endpoint 'https://graph.microsoft.com/beta/teams/' didn't succeed
Response status code 'Forbidden', reason phrase 'Forbidden'
Response content '
"code": "AccessDenied",
”message": "Failed to execute Templates backend request CreateTeamFromTemplateRequest

It may happen if user which is specified as owner of the team doesn’t have O365 license. In order to avoid this error use users with O365 license as team owners.