Jira Cloud: Update MS365 User Groups using Automation and Azure Runbooks

We’ve already discussed automating user creation in Microsoft Entra with Jira or Jira Service Management (JSM). Now, let’s look at another automation opportunity: dynamically adding users to specific groups (Teams, distribution, or security) upon creation or other triggers. By integrating Jira automation with Azure Runbooks, we can significantly improve the efficiency of MS365 group management, minimizing the need for manual intervention from your helpdesk. Let’s explore how to set this up!


 

Create the Azure Automation Account

First up, if you haven’t already, we’ll need to set up an Azure runbook. This will use a PowerShell script to create the new user account.

  • Log in to the Azure Portal.
  • Navigate to Automation Accounts:
    • Search for “Automation Accounts” in the search bar.
    • Click + Create to set up a new Automation Account.
  • Provide the required details:
    • Subscription: Select your Azure subscription.
    • Resource Group: Choose or create a resource group.
    • Name: Enter a name for your Automation Account.
    • Region: Select your preferred region.
    • Click Next

  • Under Advanced, choose System Assigned under Managed Identities.  We will go over why this may be your best option later.
  • Networking tab, ensure you have public access enabled for your connectivity configuration.
  • Setup your Tags (Highly recommended for housekeeping).
  • Click Review + Create and then Create.

After your Automation Account has been created, Go to the resource.


 

Create Runbook

Now, to set up your new runbook.  Under the Process Automation blade, click the arrow to expand and choose Runbooks.

  • Next, click + Create to create a new runbook.

Provide the needed details

  • Click Create new.
  • Enter a name for your runbook.
  • Select PowerShell as the runbook type.
  • Choose ‘Select from existing’ for the runtime environment and select PowerShell-7.2 (or the latest release). This is necessary to use the MS Graph API.
  • Add a description for your runbook.
  • Optionally, add tags to categorize your runbook.
  • Click Review + Create.
  • Once validation is complete, click Create.
  • Allow 2-3 minutes for the runbook to be created.

Our runbook will need specific PowerShell modules that aren’t installed by default.

To add them:

  • Click the + Add a module button at the top.

  • Click ‘Browse from the gallery.’
  • Search for ‘Microsoft.Graph.Authentication’ in the module gallery.
  • Select the latest version of the module.
  • Click
  • Choose the latest runtime version for your module.
  • Click Import.

It might take a little while to import the Microsoft.Graph.Authentication module. You can check its progress by searching for it in the module gallery. Once it says ‘Available,’ you’re ready to use it!

Continue the same steps above to add the other modules you may need:

  • Microsoft.Graph.Users
  • Microsoft.Graph.Groups

You should have a similar view:

To enable your runbook to add groups to users, we need to grant it permissions:

  • Go to Account Settings, choose Identity.
  • You’ll see a system-assigned managed identity is already enabled.
  • Click Add role assignment.
  • Set the scope to your Azure subscription.
  • Assign the Contributor role (or create a custom role with necessary permissions which is recommended).

a screenshot of a computer

  • Click Save.
  • Copy the object ID of the managed identity for future reference. We’ll be using this coming up.

 

Quick Discussion: Why Use A Systems Assigned Managed Identify?

System-assigned managed identities are a powerful tool for securing and simplifying Azure Automation Runbooks. Here’s a few reasons why:

We have one more step: Give our new Managed identity permissions to create users.  Ensure you have the Object ID from your Managed Identity from the steps above.

  • In a new tab, Go to the Azure portal.
  • Choose the Microsoft Entra ID blade
  • Expand Manage, choose Enterprise applications.
  • On the search bar, search for the Object ID you have copied.
  • An application should show up; click on the name.
  • Expand the Security area, choose Permissions, and you’ll notice there are no Permissions set for your application.

Since we are adding items to an already created user, we need to give this application Microsoft Graph – User.ReadWrite.All permissions.  We also need the Group.ReadWrite.All permissions since we will be adding groups to the user account. There is currently only one way to do this: through PowerShell.

The easiest way to do this is to open the Cloud Shell at the top of your Azure portal.  

Run the following PowerShell Script. Make sure you replace **SUPERCOOLOBJECTID** with the Object ID of the application you just searched for.

				
					Install-Module Microsoft.Graph -Scope CurrentUser

Connect-MgGraph -Scopes Application.Read.All, AppRoleAssignment.ReadWrite.All, RoleManagement.ReadWrite.Directory

$managedIdentityId = "SUPERCOOLOBJECTID"
$roleNames = @("User.ReadWrite.All", "Group.ReadWrite.All")

$msgraph = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"

foreach ($roleName in $roleNames) {
    $role = $Msgraph.AppRoles | Where-Object {$_.Value -eq $roleName}

    if ($role) {
        New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $managedIdentityId -PrincipalId $managedIdentityId -ResourceId $msgraph.Id -AppRoleId $role.Id
    }
    else {
        Write-Warning "Role $roleName not found in Microsoft Graph service principal roles."
    }
}

Disconnect-MgGraph
				
			

The Cloud console will run. 

Choose A for Yes to All to install all the required Graph modules.  This will run for a few minutes.

It will then prompt you to Sign into a web browser and enter a code.   Simply copy the URL (or click the URL) and type the code into your browser.

  • Enter the code to allow access. Click Next

  • The next screen will ask you to sign into your account to verify.
  • After you log in, you will need to consent on behalf of your company to give permissions to the Graph Command Line Tools. If you are okay with this, click Accept.

You can now close the tab where you granted admin consent. Return to the tab where your Azure Cloud Shell is running. The permission grant process should be complete, and cloud shell should be disconnected from Microsoft Graph.

To verify that the permissions have been added successfully:

  • Navigate back to the Permissions tab of your enterprise application.
  • You should now see the User.ReadWrite.All and Group.ReadWrite.All permissions listed, with admin consent granted.


 

Setup Runbook Script

Let’s go back to our runbook that we created.  Click the runbook and make sure you’re in the runbooks Overview view.

To edit your runbook:

  • Navigate to our runbook in the Azure portal.
  • Click ‘+ Edit’ and choose Edit in the portal.
  • Expand the Runbooks section on the left and select the correct runbook.
  • We’re ready to add our PowerShell script.
				
					# This is our Runbook to add user to multiple groups using Microsoft Graph PowerShell
param (
    [Parameter(Mandatory=$true)]
    [string]$UserPrincipalName,   #This is typically the email address of the user.
    
    [Parameter(Mandatory=$true)]
    [string]$GroupDisplayNames # Comma-separated string of group names
)

# Ensure TLS 1.2 is used
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Import Microsoft Graph modules
Import-Module Microsoft.Graph.Users
Import-Module Microsoft.Graph.Groups

# Authenticate using managed identity
Connect-MgGraph -Identity

try {
    # Find the user by UserPrincipalName
    $User = Get-MgUser -UserId $UserPrincipalName
    if (-not $User) {
        throw "User $UserPrincipalName not found"
    }

    # Split the comma-separated group names and trim whitespace
    $GroupArray = $GroupDisplayNames.Split(',') | ForEach-Object { $_.Trim() }
    
    # Track results
    $Results = @{
        Successful = @()
        Failed = @()
    }

    # Process each group
    foreach ($GroupName in $GroupArray) {
        try {
            # Find the group by display name
            $Group = Get-MgGroup -Filter "displayName eq '$GroupName'"

            if ($Group) {
                # Check if user is already a member
                $ExistingMember = Get-MgGroupMember -GroupId $Group.Id | Where-Object { $_.Id -eq $User.Id }
                
                if ($ExistingMember) {
                    Write-Output "User $UserPrincipalName is already a member of group $GroupName"
                    $Results.Successful += "$GroupName (Already Member)"
                }
                else {
                    # Add user to the group
                    New-MgGroupMember -GroupId $Group.Id -DirectoryObjectId $User.Id
                    Write-Output "Successfully added $UserPrincipalName to group $GroupName"
                    $Results.Successful += $GroupName
                }
            }
            else {
                Write-Error "Group '$GroupName' not found"
                $Results.Failed += "$GroupName (Group Not Found)"
            }
        }
        catch {
            Write-Error "Error adding user to group '$GroupName': $_"
            $Results.Failed += "$GroupName (Error: $($_.Exception.Message))"
        }
    }

    # Output summary
    Write-Output "`nOperation Summary:"
    Write-Output "Successful operations: $($Results.Successful.Count)"
    if ($Results.Successful) {
        Write-Output "Successfully processed groups:"
        $Results.Successful | ForEach-Object { Write-Output "- $_" }
    }
    
    if ($Results.Failed) {
        Write-Output "`nFailed operations: $($Results.Failed.Count)"
        Write-Output "Failed groups:"
        $Results.Failed | ForEach-Object { Write-Output "- $_" }
    }
}
catch {
    Write-Error "Error in main script execution: $_"
}
finally {
    # Disconnect from Microsoft Graph
    Disconnect-MgGraph
}
				
			
  • Click Save.  Click Publish.

 

Test Runbook

Before proceeding, we should test our runbook to ensure it works as expected. After all, if it doesn’t work here, the Jira automation definitely wont work.  

  • In the runbook editor, navigate to the Test pane.
  • Fill in the necessary parameters for the runbook to execute.
    • To add mutliple groups, you need to seperated them out by comma.  Example: slack-users,jira-users.
  • Click the Start button to initiate the test.
  • Please allow up to 3-5 minutes for the test to complete.
  • Once the test finishes, review the output to verify that it ran successfully and without errors.

Within the Azure Portal, expand the Microsoft Entra bade, expand Manage, and choose Users. 

Search for the user you just added the groups to.  Click the Groups blade and verify the groups were added. 


 

Setting up Jira Automation

Ok, we have set up and tested our Azure runbook.  Now, let’s move on to the easier part of setting up the Jira Automation.  What’s our scenario?  How do we want this to play out within Jira?

Our Scenario

User or Manager creates Jira ticket asking to be added to a couple groups that gives them access to applications. Once the fields are reviewed on the ticket, a member of Helpdesk moves the ticket status from Review to Assign Groups. At this point our Jira automation kicks in and triggers the Azure runbook and adds the groups to the users account.
  • Click your Project settings and go to Automation.
  • Choose Create Rule.
  • Our trigger will be when the Issue is Transitioned; select this option.
    • Our criteria are from status: Review to status Assign Groups.
    • Click Next.

Let’s add a safeguard to ensure somebody has reviewed the info and set the review field to yes.

  • Add the IF: Add a condition
  • Choose Issue fields condition.
    • Under Field, we choose the Issue Type
    • Condition, equals
    • Value is Group Change
    • Click Next.
 
We’re going to add an Action to log what groups are being added.  This can be handy, as well show you later, to audit not only what is being sent to Azure but the format as well. 
  • Add a Then: Add an action condition. 
  • Search and choose Log Action.
  • We’ll create a log message that states “Groups being added: and well insert the customfield ID of our groups field on our ticket screen.
  • Click Next.

Let’s add a branch component to work only off the issue that triggered it.  Choose FOR EACH: Add a branch, and select the Branch rule / related issues.   Choose Current Issue (default) on the next screen and click Next.

  • Click the Add to branch under your new Branch. Select the THEN: add an action. 
  • Search or scroll down to the Start runbook in Azure and choose it.
  • Next, we need to Connect our Azure account to our Jira account. Click the Connect   This will open a new window.
  • Sign in to your MS365 account if you’re not already signed in.
  • Review and approve the permissions request on behalf of your organization. Click
  • This tab should close out, taking you back to your Jira Automation.

a screenshot of a phone

  • Within Jira Automation, Select your Azure Subscription name
  • Select the Resource Group that has your automation account.
  • Select the Automation account that holds your runbook.
  • Lastly, select the runbook we just set up for this task.

The last thing we need to do is bind the Key-value pairs so the payload we send to Azure has the information to give to our runbook script.

In our simple example, we’re going to map two pairs of values (attributes).

  • UserPrincipalName

  • GroupDisplayNames

The key-value pairs are going to be mapped like the table below:

UserPrincipalName

String

{{issue.customfield_10060}}

GroupDisplayNames

String

{{issue.customfield_10061}}

You must insert the custom field IDs that your Group Change tickets use.  I have a handy guide here if you need help finding the Jira custom field IDs.

Once you’ve added all your key-value pairs, select Next.

Click the Rule Details at the top.

  • Name your rule
  • Set a description. (please do this for good housekeeping).
  • Set the Automation Owner.
  • Set the Actor (typically Automation for Jira)
  • Select if you want an email if this rule errors out.
  • Who can edit the rule?
  • Lastly, click Turn on Rule.

Your Jira automation rule should look something like this: 


 

Let’s Test It!

The last thing to do is test your automation and runbook! We’ll test with the newly created Group Change ticket with the required information filled out. 

Per our scenario, the ticket gets transitioned from Review to Assign Group which kicks off our automation. 

If we go to our Jira Automation rule and click the Audit log, we can see the runbook request was submitted.  Also note the Log Action has written the two groups we are testing this with. 

Back in the Azure portal, if we open our runbook, we should see our Runbook either running or completed already. If you click the Completed Status, you will see our Inputs, Errors, etc.

Last step, you should see the groups added to your MS365 user within the Azure Portal. 

That’s all there is to it!  You now have automation to add users to groups via Jira automation. 

If you have Jira Enterprise licensing, you can add the capability of allowing the runbook to reply back as a comment on the ticket with the status and information.  Hopefully this gets added to the Standard and Premium tiers as soon. 


 

Wrap up notes:

This guide covers how to add groups to your Entra ID users by teaming up Jira automation and Azure runbooks. 

A couple ways to enhance this automation:

  • Make use of Jira Service Managements Assets portal:  By having a list of your groups within the portal tied to applications.  For example in the on-boarding ticket you choose Slack and Zoom. Within Jira automation, you do an object lookup that writes the group name associated with the object into your Key Value Pairs.  

Example JSM Assets application entry with Entra ID Group

  • Implement Jira workflow conditions to allow managers or other groups/users ability to transition the ticket, taking even more off your helpdesk team. 

I hope you found this helpful!