After a while, you discover the holes in any technology. In the case of the Microsoft Graph PowerShell SDK, some inconsistencies await unwary developers. The SDK doesn’t like $Null, doesn’t support pipelining, insists on specific property casing at times, sometimes accepts user principal names and sometimes doesn’t, and sticks valuable data in hash tables hiding in a property you might know nothing about. Good as it is to have the SDK cmdlets, they need to be treated with care as you transition from the old Azure AD and MSOL modules.
Azure AD registered devices store some information about the operating system and version used when registration occurs. Although this information changes over time and isn’t updated by Azure AD, it might be of some interest and use to tenant administrators, so we show how to report it here. If you want accurate information, you’ll need to use Intune.
As developers update PowerShell scripts in preparation for the deprecation of the Azure AD and MSOL modules, they might need to insert new code to retrieve the membership of Azure AD groups for specific accounts. We cover that topic here, including the interesting case of the AdditionalProperties property returned by several Microsoft Graph PowerShell SDK cmdlets and the valuable information found there.
Azure AD Guest Accounts have a habit of becoming stale or obsolete as time progresses. Guest accounts created to share documents or to be a member of a long-forgotten team or group remain in Azure AD until someone comes to clean them up. This article explains how we refreshed a popular script to use cmdlets from the Microsoft Graph PowerShell SDK to report guest accounts with different degrees of staleness.
A December 2 post by the Microsoft Graph development team clarifies how it plans to charge for some Microsoft 365 APIs. The three-tier model Microsoft plans to use is logical and the default will remain free access to customer data. However, the way Microsoft has communicated the introduction of a charging model for some high-capacity APIs is a model of how not to manage change.
This article offers some tips about working with the Microsoft Graph Usage Reports API. In particular, we cover how to detect if the concealment of display names setting is active and how to reset it to allow display names appear in reports. We also cover the strangeness of some of the numbers reported for Teams message counts.
The new tenant admin Microsoft Graph API allows access to read and update SharePoint Online tenant settings. Although the API offers limited capabilities for now, it marks the start of Graph support for tenant settings that are currently managed through admin portals or PowerShell. It’s a welcome development.
Cmdlets in the Microsoft Graph PowerShell SDK module can interact with many types of Microsoft 365 data using Graph API requests. Adding the Debug parameter gives you an insight into what happens when SDK cmdlets run Graph requests. The knowledge can help you write better code and avoid mistakes, and that’s always a good thing.
Microsoft has launched application access to Exchange Online via IMAP4 and POP3 using modern authentication. The approach Microsoft takes is reasonable and pragmatic and should be simple enough for app developers to implement. However, with an eye on the future, maybe this isn’t the best strategic choice to make. Moving to the Graph APIs will take more work, but it’s a better long-term solution.
The Microsoft Graph continues to grow in importance, as do tools like the Graph Explorer web application. The Explorer has received a couple of new and useful features recently, including the generation of PowerShell code snippets. This doesn’t work for every Graph API, but it’s a start and a great enhancement to what’s already a very useful tool.
The new Graph X-Ray extension available for the Chrome and Edge browsers gives developers an insight into how the Azure AD admin center uses Graph API commands to retrieve user and group objects. The insight is invaluable when teasing out some of the syntax needed to get work done with the Graph. It’s much appreciated.
Lots of news has emerged from Microsoft recently regarding the deprecation of the Azure AD PowerShell module and the older MSOL module. Although dates have slipped from the original June 30, 2022 deadline, the signs are that Microsoft will retire the modules in early 2023. However, the Azure AD and MSOL license management cmdlets will stop working on August 26, 2022, so that’s the immediate priority for script upgrades.
By now, Microsoft 365 tenant administrators realize the need to understand how apps use consent to access Microsoft 365 data. App certification helps by reassuring tenant administrators that third-party apps meet certain criteria set by Microsoft. Achieving Microsoft 365 certification is the highest bar in the program. It’s just a pity that many of the apps now appearing in the ecosystem don’t achieve this level of app certification.
A new Microsoft Teams feature means that local time zone information appears on user profile cards. While it seem simple, the feature is very useful when arranging meetings because you know up-front about the working hours of your colleagues. It’s a detail that makes sense!
Access tokens are an important part of accessing data using modern authentication through APIs like the Microsoft Graph. But what’s in an access token and how is the information in the access token used by PowerShell when the time comes to run some Graph queries in a script? In this article, we look behind the scenes to find out what’s in the JSON-structured web tokens issued by Azure AD.
Message center notifications for service changes posted to the Microsoft 365 admin center will include monthly active user counts for affected workloads. That sounds good, until you realize some of the downloads incurred by depending on the Microsoft Graph Reports API as the source of user data. Still, it’s better than nothing and a welcome advance.
Finding the age of a Microsoft 365 tenant isn’t an important administrative operation. However, understanding how to retrieve this information (if asked) is an interesting question, which is why we spent several hours playing around with PowerShell and the Microsoft Graph to figure out how to answer the question. It’s the kind of in-depth analysis we do all the time to build content for the Office 365 for IT Pros eBook.
Microsoft is removing TLS 1.0 and 1.1 from Microsoft 365. This has been well flagged, but tenants might not understand the impact on PowerShell scripts which send email using the Send-MailMessage cmdlet and SMTP AUTH. In a nutshell, unless you force PowerShell to use TLS 1.2, attempts to send messages via Exchange Online will fail. It’s time to check those scripts and ,consider how to move away from SMTP AUTH and Send-MailMessage.
A reader asked how to find when Azure AD accounts received certain licenses. As it turns out, this isn’t as simple as it seems. PowerShell can tell use when user accounts are enabled with service plans, but to get dates for licenses (products or SKUs), we need to go to the Graph API, and those dates aren’t quite there yet. In any case, it’s an interesting question which deserves some exploration to see if we can find an answer.
A Microsoft October 5 announcement gives a clear signal that Exchange Web Services is on a short runway to oblivion. The first step is the removal of 25 APIs on March 31, 2022. It’s all part of the master plan to get Office 365 tenants and ISVs to move to the Microsoft Graph APIs. This is a perfectly laudable ambition but it’s complicated because of the lack of suitable Graph APIs to handle the volume of Exchange data involved in scenarios like backup/restore and migration. Teams has a new Graph Export API, but it introduces consumption metering and charging. Is a new Exchange API coming and will it use the same charging mechanism? We live in interesting times…
Understanding how to create effective queries using the Microsoft Graph APIs takes some work, especially with some of the more complex filters used to refine the data returned by the Graph. In this article, we look at how filters using lambda qualifiers work and explore some examples of these qualifiers in use.
The usage reports available in the Microsoft 365 admin center, Teams admin center, and other places now include anonymized user information by default. The new default became active on September 1, 2021 and the organization setting applies to any usage data generated by the Microsoft Graph usage reports API, which means that some scripts might create reports less interesting and useful than before. It’s a good change for privacy, but will organizations persist with the new default?
You can now access videos and slides for sessions given at The Experts Conference 2021. The sessions cover a wide range of technology from Azure AD to Microsoft 365 to infrastructure modernization. And you can now register for TEC 2022, which will run as an in-person event in Atlanta on September 20-21, 2022. It should be great fun!
Microsoft has replaced the controls which disabled document insights in Delve with new Graph-based settings. However, you might still have a bunch of users with the Delve settings who need to migrate to the Graph settings. In this article, we explore how the settings work and how to query the Graph to find the set of users who disabled the setting in Delve. We can then use PowerShell to add those accounts to the group of disabled insights users for the Graph-based settings.
The message center in the Microsoft 365 admin center will soon use a new data privacy tag to highlight specific service updates to tenant administrators. No messages with the new tag have yet appeared, so it’s hard to know how Microsoft plans to use the new tag or what kind of attachments it will make available to administrators to help understand the sensitive data involved in data privacy. While we’re waiting, we took at look at the tags in use today and wrote some PowerShell to report which tag is most popular.
The thoughts of using Microsoft Graph API calls with PowerShell might seem to be too much trouble, but used correctly, Graph API calls help scripts speed up and get to some data that is not reachable through a cmdlet. I have a simple four-step approach that I use to figure out if I need to include some Graph API calls. The routine works for me. Feel free to disagree.
Sometimes it’s wise to give PowerShell scripts a turbo boost. This is certainly true for the Groups and Teams Activity report script, where a large amount of PowerShell processing has been replaced with speedy Microsoft Graph API calls. The result is much faster processing, which means that the script is more useful in large tenants. I still wouldn’t try to run it against 100,000 groups, but anything smaller should be OK. I think!
Sensitivity labels are a great way to protect confidential documents stored in SharePoint Online. Sometimes the documents must be decrypted. This article explains how to build a PowerShell script which uses Graph API calls to navigate to a folder in a SharePoint Online document library and decrypt the protected documents found in the folder.
{"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}