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.
Microsoft wants to eliminate the Search-Mailbox cmdlet, but it’s still very valuable when the time comes to remove mailbox items because of a spam attack or similar reasons. The suggested replacement is Core eDiscovery searches and associated content search purge actions, but these are slower and less effective than Search-Mailbox. To prove the point, we’ve put together a demonstration script to show how to compose a search query and run it against a set of mailboxes.
Microsoft is preparing to enable lightweight plans soon. The new plans are managed via the Planner app and should turn up in Teams meetings as a fluid component to allow meeting participants to capture tasks assigned during calls. It’s a neat way to use a plan that isn’t associated with a Microsoft 365 group. We’ll see what happens in September/October when the functionality lands. Also, a new cmdlet is available to export Planner data for a user. You never know where this might be useful.
In this post, we describe how to use PowerShell to remove a single service plan from Microsoft 365 licenses using PowerShell. The script can remove any service plan from any SKU (license) in a tenant. You might want to do this to disable access to an obsolete feature (like Sway) or to prevent access to a new feature until the organization is ready to support user activity.
In this post, we explore how to use PowerShell to create a report about distribution lists and their owners. The script is quick and dirty, but it works, and the code will run on both Exchange Online and Exchange Server and generates both HTML and CSV outputs. We also look at whether it’s possible to speed things up by using Microsoft Graph API calls. As it turns out, because we’re interested in owner information, it’s no faster to retrieve distribution lists using the Graph. However, as shown in a second script, the Graph is great at retrieving membership information.
Controlling the creation of Microsoft 365 Groups might seem complex, but it’s not as complicated as it might seem. Make sure Azure AD allows group creation, and then you can either allow everyone to create new groups or restrict the right to a limited set of accounts (a capability requiring Azure AD Premium licenses). And don’t forget OWA, because it’s got its own mailbox policy with a group creation setting. All good, clean, honest fun.
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.
Many PowerShell scripts which access Office 365 data could do with a speed boost. Replacing cmdlets with Microsoft Graph API calls is one way to get extra speed. In this article, we take a PowerShell script to report the memberships users have of Microsoft 365 groups and replace some important cmdlets with Graph API calls. The result is a big speed increase.
Office 365 tenants users will soon be able to execute self-service purchase Windows 365 licenses. That is, unless you stop them by running some PowerShell commands to disable the capability. In this article, we explain the Windows 365 options available for self-service purchase and the PowerShell commands necessary to disable the option, if you think it’s a bad idea (as some do).
The latest version of the SharePoint Online PowerShell module reveals some new site properties to inform administrators if sites are connected to teams or even team channels (both private and shared). There’s also some changes coming to the SharePoint Online admin center, all of which are very useful in terms of tracking the sites used by Teams.
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.
New teams created using Teams clients are hidden from Exchange Online, but those created using administrative interfaces are not. The result is potential confusion. in this post, we describe a PowerShell script to find any team-enabled Microsoft 365 Groups which are visible to Exchange and hide them. It’s easy scripting, but you need to run the script periodically to update the settings for new teams.
How do you create a report of all the Teams in a tenant and their SharePoint Online sites? As it turns out, a two-line script does the job. We make the script slightly prettier, but it’s still simple. And because it’s PowerShell, anyone can change the code to make it work the way they want it to.
Auto-label policies are a good way to assign retention labels to important files stored in SharePoint Online and OneDrive for Business. The big problem is tracking the progress of auto-labeling. In this article, we explore how to use events logged in the Office 365 audit log to figure out what files are labeled and how long it takes the auto-label policies to process the files. The example explored here is an auto-label policy for Teams meeting recordings.
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!
New PowerShell commands for sensitivity labels can configure default sharing link settings for SharePoint Online sites. Any site assigned a label configured for default sharing links inherits those settings within 24 hours. Also available is the ability to apply default sharing link settings at a per-document basis.
Finding out which Azure AD accounts have licenses (service plans) for different applications isn’t difficult. You can do it with either PowerShell or the Microsoft Graph API. This article explains how to use PowerShell (and the equivalent Graph API call) to find accounts which have a certain license (service plan) enabled or disabled. Once you know how to navigate license data in Azure AD accounts, you can take the code and adapt it for different purposes.
Anyone writing PowerShell code against Azure Active Directory probably uses the Azure AD module. In June 2022, Microsoft will deprecate the API underpinning the Azure AD module. Tenants who want to use PowerShell to create scripts to automate administrative processes will need to move to Graph API calls or use the Microsoft Graph PowerShell SDK. Either way, there’s a bunch of work to do to upgrade scripts.
Compliance role groups control access to Microsoft 365 compliance functionality. A new permissions page makes it easier to manage these groups in the Microsoft 365 compliance center, where you can also manage the Azure AD roles used by Microsoft 365 compliance. If you want to generate a report about who holds what role, you’ve got to use PowerShell. The code is easy once you know which roles you want to report.
Blocking domains through the Azure AD B2B collaboration policy stops group owners adding new guest accounts from certain domains. It does nothing about existing guests from those domains. Fortunately, it’s relatively easy to check the guest membership of Groups and Teams to find guests from the blocked domains. And once you know those problem guests, you can decide what to do up to and including removing guest accounts from the tenant.
This page describes the latest version of the Microsoft Teams (MicrosoftTeams) PowerShell module. If we know about problems with versions of the module, we note them here.
Without warning (for security reasons), Microsoft stopped the Exchange Online Set-User cmdlet being able to update the work and mobile numbers for Azure AD accounts. We don’t know what kind of security concerns caused Microsoft to take this action, but it might be associated with administrative roles. In any case, this disappointing example of how to communicate with customers might end up with people having to update some PowerShell scripts – and no one likes unexpected work.
Azure B2B collaboration is used by Microsoft 365 Groups-based apps like Teams, Planner, and Yammer to create new guest accounts. You can update settings in the Azure AD portal to stop new accounts from specific domains or restrict guests to a list of known domains. But before you go ahead and update the settings, it’s a good idea to know where existing guest accounts come from. It’s easy to create a report with PowerShell. The next step might be to remove guests from offending domains.
For whatever reason, Microsoft decided to cancel plans to remove the Top Senders and Recipients report from the SCC, citing customer feedback as the reason. The thing is that the SCC report and its underlying cmdlet use an old data source. The Microsoft Graph Reports API is the modern approach and an adequate replacement usage reports is available in the Microsoft 365 admin center. I really can’t understand why anyone would want to keep the old report as it’s not very good at all.
Office 365 administrators can update Azure AD guest accounts with photos. Guests can do the job themselves using three PowerShell commands. Other approaches work too, but this is the easiest and quickest method to do the job, especially if you have guest accounts in multiple tenants.
PowerShell pros know the secrets of typed variables and why this matters when cmdlets return data, but some of us have been doing things wrong for years. Which is why I spent a couple of hours contemplating the differences between typed and untyped variables when handling items returned by cmdlets. They say that old dogs can’t learn new tricks. I beg to differ…
Azure AD holds information about managers and their direct reports. It’s easy for that data to go out of date, so we create a report to tell us who are the managers and how many direct reports they have. Azure AD has some cmdlets to retrieve information about managers and direct reports, but as it turns out, the older Get-User cmdlet is the best way to proceed.
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.
Microsoft has released V2.0 of the Teams PowerShell module. It brings some welcome improvements, notably the inclusion of all the management cmdlets, but has a downside too. The new cmdlets for managing teams templates are not easy to use and some authentication issues affect the Connect-MicrosoftTeams cmdlet after a change in authentication libraries. Microsoft has some work to do to improve this version of the module.
Microsoft is changing the way new teams are created in the Teams admin center to make sure that their settings are consistent with teams created in other interfaces. It’s a good idea because it means that all teams are then created equal. Organizations who wish to use different settings can update teams once they’re created using either PowerShell or the Graph API.
There are many examples of PowerShell scripts which create reports about the membership of Microsoft 365 Groups. Most are slow. This version is faster because of its per-user rather than per-group approach to processing. The output is a nice HTML report and two CSV files containing a list of memberships in Microsoft 365 Groups and summary data for each user in the tenant.
Many people want to print off membership details of Microsoft 365 groups, which makes it curious why Microsoft doesn’t support the option in Teams, OWA, or other applications. Fortunately, it is very easy to extract and report membership with PowerShell. Here’s how to generate a HTML report with a CSV file on the side.
Audit records are a great way to gain an understanding of what happens inside Office 365. We use PowerShell to report actions taken with sensitivity labels such as protecting files and containers. The latest development is the addition of support in the Microsoft 365 apps for enterprise (Office desktop) to log audit events when users interact with sensitivity labels. Unsurprisingly, more events are often logged by the desktop apps than their online equivalents.
The inbound webhook connector used by Teams and Microsoft 365 Groups to accept information from external sources is getting a new format. Existing connectors must be updated by April 11, 2021. If not, data will stop flowing into the target channel or group, and that would be a bad thing.
You can create an Azure AD Access Review for all guests in teams and groups in your tenant and then see what’s happening with the Graph API. In this case, we use PowerShell with the API to grab the access review data and create a report about the overall status of the review in a tenant.
Need a PowerShell script to do something with Office 365? You might find a script or at least an idea – in the Office 365 for IT Pros GitHub Repository. We have created over 80 scripts as examples and demonstrations of how to get stuff done in an Office 365 tenant with PowerShell. You’re welcome to use anything in the repository and especially welcome to fix our bugs.
Sometimes delegate access for an Exchange Online calendar goes awry due to corrupted items in the mailbox. To help sort out problems, Microsoft has upgraded the Remove-MailboxFolderPermission cmdlet to do the work that used to be done by a multi-phase fix performed using the MFCMAPI or EWS editor utilities. The nice thing is that this method is quick, simple, and works well.
Exchange Online now insists on TLS 1.2 connections between email clients and servers. PowerShell scripts using the Send-MailMessage cmdlet will fail. The problem is easily solved by forcing PowerShell to use TLS 1.2 to connect, but it does mean that some work is needed to check scripts (before they fail).
All services suffer outages or incidents. The Service Communications API allow Office 365 tenants to retrieve information about incidents programmatically and report details in whatever way they want. In this post, we show how to use PowerShell to fetch service messages with the API and filter for recent incidents. After that, it’s just a matter of presenting the details.
Bing publishes a new image daily in its home page. You can download the images and use them as custom background for Teams meetings. A PowerShell script automates the task and downloads the images for the last seven days and cleans up any Bing images older than 30 days.. It’s a nice way to use some attractive images to liven up Teams meetings.
{"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}