The Microsoft Graph API offers a fast and easy way to find and modify Office 365 data. Combining the Graph with Microsoft Flow makes it possible to automate the steps in a task. Some impressive results can be created even by people who don’t have a programming background.
The Microsoft Graph API is a unified programmatic RESTful interface for all the components of Office 365. Via a single REST endpoint. Microsoft Graph API provides access to objects such as users, groups, mail, messages, notes, tasks, calendar, and Office Graph. Data can be retrieved from multiple Microsoft cloud services such as Exchange, OneDrive, SharePoint, OneNote, Planner and Azure Active Directory. One of the Microsoft Graph components is the Security API, an interface and schema used to integrate security solutions from Microsoft and other vendors.
Office 365 Flow
Microsoft Flow is the automation engine in
Office 365. A flow is a workflow that combines tasks and data from multiple
Office 365 applications and services to get work done. To create a flow, the
user specifies what action should take place when a specific event occurs. No
programming experience is required.
Once a flow is built, it can be managed on the desktop or through a mobile device. Flow integrates out-of-the-box with many Office 365 services and apps, including SharePoint, Power BI, PowerApps, and Dynamics 365, but can be extended to reach other systems.
Putting Graph and Flow Together
After a tenant is up and running, it’s good
to know the current state of the Office 365 services consumed by users. But
monitoring services and taking any necessary actions can be a boring and
tiresome activity. This kind of repetitive work can be automated using tools as
Flow and Graph. And, because the creation of flows can be done by
non-programmers, a flow can be quickly built by administrators.
In this article, we will use the Office 365 Secure Score as an example. Secure Score is a self-assessment tool to test the security level of an Office 365 tenant and generates an assessment of how well the tenant is protected against the risk of a security breach or attack. Secure Score is available in the Security & Compliance Center or this link. Click the Improvement actions tab to see recommendations to improve tenant security and increase the tenant’s Secure Score (Figure 1).
Figure 1: Viewing improvement actions for Secure Score
Our aim is to get the recommendations using
the Microsoft Graph Security API. The idea is to generate a weekly report
containing security recommendations and email it to the administrator.
First Step: Register an application in Azure Active
Directory
Because Flow communicates with Graph as an “external” component, it needs to be authenticated and authorized to get information from Office 365. This is done by registering the application in the Azure AD and assigning the app the needed permissions. The first step is to open the Azure Active Directory portal and select “App registrations” and then “New registration” (Figure 2). Give the app a name, select the account type and leave the Redirect URL empty.
Figure 2: Registering an Azure AD app
After the app is registered, note the “Application (client) ID” and “Directory (tenant) ID” values (Figure 3) because these data are used later in the process.
Figure 3: Noting important app data
Next, grant the registration permissions to access the Graph, selecting the option “API Permissions” on the left side menu. Click on “Add permissions”, then “Microsoft Graph” and, in the new window, “Application permissions”. Because we will use the “Secure Scores” of the Security API, scroll down in the window, open the “Security” section, and select the option “SecurityEvents.Read.All” (Figure 4). Always the lowest possible access level for any app you register. Save the changes.
Figure 4: Selecting the Secure Score permissions for the app
Remember to grant the permissions assigned to the application using the button in the “Grant consent” section (Figure 5).
Figure 5: Granting consent for the app to receive permissions
The next step is to create a secret that allows the application to run without any user credentials. Select “Certificates and secrets” on the menu at the left side, and then click the button “New client secret.” A popup window will start asking for how long the secret will be valid: one, two years, or never expires. Select one of the options and generate the secret. Make a note of the secret along with the Client and Tenant IDs (Figure 6).
Figure 6: Viewing the client secret for the app
Creating the Flow
It is now time to create the Flow and get the information required. Open https://flow.microsoft.com and go to “My flows”. Select “+ New” and “Scheduled – from blank.. Assign a name to the Flow and select how often, and when, it will start (Figure 7).
Figure 7: Creating a new scheduled Flow
The Flow designer starts. The “Recurrence” step should be already populated using the information in Figure 7. Use the “+ New step” button to create a “Initialize variable” step to contain the first value needed (the Client ID) to use the Azure AD registration, giving it a name, selecting “String” as “Type”, and copying its value into the Flow. Repeat the operation to add two variables for the Tenant ID and the Secret (Figure 8).
Figure 8: Creating Flow variables for the Graph app
Add a new variable to contain the filter for the query to Graph. This is necessary because URLs in Flow don’t allow to use whitespaces, and Graph doesn’t understand the convention to use “_x020_” to encrypt the spaces. The value for the variable will be “?$filter=userImpact eq ‘High'” (Figure 9).
Figure 9: Adding a filter for the Graph app
Now add a new step to the Flow, this time of type “HTTP” to send the request to Graph. This activity requires a “Premium” account for Flow (Plan 1 or Plan 2). In the step, click on the “Show advanced options”. In the “Authentication” box select “Active Directory oAuth”. Configure the options using the following values:
Because the query is filtered to get a similar response as the response given by the Office 365 user interface (User Impact High), we are using a combination of the string for the query and the value of the variable for the filter (Figure 10).
Figure 10: Inserting the Graph URI into the Flow
Save the Flow and run it because we need the output for the next step. From the output result window of the Flow, copy the “Body” response (Figure 11).
Figure 11: Checking the Graph response
The Graph response is in JSON form, and it contains a plethora of data. We are interested in only the Title (that contains the description of the issue) and Remediation fields. Return to the Flow and open it for editing. Add a new action of the type “Parse JSON” at the end of the flow to extract the needed data. Use the “Body” of the HTTP query output as “Content” and click on the “Use sample payload to generate schema.” Flow opens a pop-up window where you can paste the result of the query run (Figure 11). Flow will generate the schema for the parser and create objects for each item in the response automatically (Figure 12).
Figure 12: Flow creates objects from the Graph JSON response
The parser presents the data as text without any formatting. To create something that a user can read, add a new step in the Flow of the type “Create HTTP table”. For the data source (“From” field) select the “value” tag of the parser and select “Custom” in “Columns”. Create two columns, one called “Title” that uses the “title” object created for the parser, and other called “Remediation” for the “remediation” object (Figure 13).
Figure 13: Creating a HTML table in Flow
Save and run the Flow again. Open the result and in the Table step you will see the data that we want to have, rendered in the correct format (Figure 14).
Figure 14: Examining the Secure Score Information Retrieved from the Graph
To send a message to the system administrator with the query results, add finally a “Send an email notification” step to the Flow. Use the “Output” of the table for the Body of the Email (Figure 15).
Figure 15: Creating an email notification in the Flow
Save the Flow and run it manually. An Email will be received in a couple of seconds with the recommendations found by Graph (Figure 16).
Figure 16: The email with Secure Score information as received by the admin
From now on, the Flow will run
automatically each month based on the configured schedule.
Conclusions
The Microsoft Graph offers a unified way to approach and interact with Office 365. At the other side of the equation, Flow allows us to use Graph, not only to get information from Office 365 but also to take decisions and make modifications if necessary. Both systems combined give the administrators of Office 365 a powerful tool to automate monitoring and maintenance activities.
Gustavo writes Chapter 23 of the Office 365 for IT Pros eBook, where he discusses the finer points of Microsoft Flow and PowerApps. If you haven’t tried to create anything with Flow, you might be surprised at what’s possible.
{"id":null,"mode":"button","open_style":"in_modal","currency_code":"EUR","currency_symbol":"\u20ac","currency_type":"decimal","blank_flag_url":"https:\/\/office365itpros.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/office365itpros.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":100,"top_media_type":"featured_image","featured_image_url":"https:\/\/office365itpros.com\/wp-content\/uploads\/2022\/11\/cover-141x200.jpg","featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":true,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Virtual Tip Jar","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"Office 365 for IT Pros","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"Office 365 for IT Pros","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for supporting the work of Office 365 for IT Pros!","payment_confirmation_title":"Office 365 for IT Pros","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":null,"terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}