In July 2022, Microsoft announced that they would stop the automatic provisioning of a wiki tab for new Teams channels. On 11 January 2023, Microsoft followed up with news of the retirement of the Teams wiki app in February 2023 (MC496248). OneNote is the replacement app and Microsoft plans to deliver an app to migrate wiki content to OneNote notebooks stored in SharePoint Online. The wiki content is already in SharePoint Online, so the migration moves whatever’s in the wiki to the default shared OneNote notebook. Once the migration finishes, Teams locks the wiki, and users work with OneNote from that point.
The migration app is due to roll out in mid-February. Eventually, Microsoft plans to remove the wiki app and tab from Teams.
The Need to Find Wikis
The reaction to Microsoft’s announcement has been positive. OneNote is a more functional application, and the Teams wiki never found much favor with customers. Although the change is good, some up-front work is necessary to prepare for the transition. One obvious question is what Teams channels have a wiki. The natural follow-up is to ask if any wikis contain something worth migrating.
Assessing the worth and importance of wiki content is not something that’s easy to automate. You could scan the SharePoint Online site and examine the date of the latest update for the wiki files to conclude if the wiki is active. Measuring what might be in the wiki is another matter. Beauty is very much in the eye of the beholder and what appears to be someone else’s rubbish might be critically important to them. But we can discover which Teams channels have wiki tabs and report that data to use as a guide to wiki migration.
Several years ago, I wrote a PowerShell script that uses Graph API requests to report the tabs and applications used by Teams channels. I took the code and amended it to generate a wiki report and replaced the Graph API requests with cmdlets from the Microsoft Graph PowerShell SDK to allow the script to run without needing to create a registered Azure AD app. Of course, if you want to, you can amend the original code and run it with a registered app. That’s an exercise for the reader.
Graph Documentation Improvements
Apart from not needing a registered app, using the Microsoft Graph PowerShell SDK illustrates how broadly the SDK extends. Microsoft is gradually updating Graph documentation to include PowerShell examples that feature SDK cmdlets. For instance, the Get channel API returns details of a channel in a team. Its examples include how to use the Get-MgTeamChannel cmdlet.
Another piece of essential information found in the Graph documentation is the application permission needed to run a request (or its matching cmdlet), like the ChannelSettings.Read.All permission needed to fetch channel settings. See this article for more information about figuring out Graph permissions.
Generating a Teams Channels with Wiki Report
Getting back to finding Teams wikis, the steps are simple:
Find all teams with the Get-MgTeam cmdlet. It’s critical to use the Select-MgProfile cmdlet to attach to the Graph beta endpoint because Get-MgTeam doesn’t support fetching all teams with the V1.0 endpoint.
For each team, find all channels with the Get-MgTeamChannel cmdlet.
For each channel, examine the tabs with the Get-TeamChannelTab cmdlet and collect information.
Examine each tab. If it’s a wiki tab, fetch details of the tab using some data exposed by the Get Tab Graph API (using the Get-MgTeamChannelTab cmdlet). For most wiki tabs, this returns a configuration property that holds a ‘hasContent’ value if anyone has edited the wiki. Some older wiki tabs don’t return a configuration property.
For wiki tabs with content, find the team owners because they are the best people to check the wiki to decide if it should be migrated to OneNote.
Generate the report of Teams wikis for checking. Figure 1 shows the output from the PowerShell list, which the code also saves to a CSV file. If you want something nicer, consider exporting to an Excel worksheet.
The script I used to create the report shown in Figure 1 is available from GitHub. Use the latest version from 26 January 2023 or later.
Figure 1: Reporting Teams channels with a wiki tab
The script is pure PowerShell so it’s easy to change to meet individual requirements. Have fun tracking down those pesky Wikis!
Make sure that you’re not surprised about changes that appear inside Office 365 applications by subscribing to the Office 365 for IT Pros eBook. Our monthly updates make sure that our subscribers stay informed.
This is one of those things that is technically possible but not worthwhile. You could find the files in SharePoint, but how could you assess the worth of their content?
Our objective is to inform the business user community (espcially those who’ve put info on Wikis) about the upcoming change to OneNote (or will Wikis users (Team owners/members) be informed automaticaly?
Loading...
Using GraphAPI I notice that each Wiki Tab has a property ‘hasContent’ which is equals false in case nothing is entered on that page.
That’s no indication of whether the content is valuable. It might help you understand which wikis to check, but someone who knows the content still needs to validate it.
Loading...
Hi Eric, I’ve been playing with the wiki hascontent configuration and found that not all wikis have the information and in some cases (older channels) it is blank. But it might be a good thing to check and I am updating the script so that people have a chance to use the information. Thanks for pointing it out…
Tony, I’m getting the following error when running your script:
PS C:\Windows\System32> .\wiki.ps1
Welcome To Microsoft Graph!
Finding Teams
Get-MgTeam : Requested API is not supported. Please check the path.
At C:\Windows\System32\wiki.ps1:9 char:1
+ [array]$Teams = Get-MgTeam -All
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: ({ Top = , Skip …ndProperty = }:f__AnonymousType29`8) [Get-MgTeam_List], RestException`1
+ FullyQualifiedErrorId : NotFound,Microsoft.Graph.PowerShell.Cmdlets.GetMgTeam_List
For some reason, I can’t find any Teams… exiting…
Hi Tony
I’m confused, every method i try to run this very needed script (thank you) just returns
PS C:\support\scripts> Select-MgProfile Beta
Select-MgProfile : The term ‘Select-MgProfile’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again
I assume I’m missing a module i need to load or something, but don’t know which one… yet??
James
Loading...
I get the same with the connect command
Connect-MgGraph : The term ‘Connect-MgGraph’ is not recognized as the name of a cmdlet etc etc
Hi Tony, tx for updating the script 👍🙏💪 > great help. In the mean time I used Power Automate w/t same instructions/methods as in your script to compile a list of Channels & Wiki tabs , possible having (useful) content and owners to inform🙂
Hi!
I’am having some problems running the script.
I’ve tried different versions of Microsoft.Graph module but with no luck.
If I run (Get-Command Get-MgTeam).parameters I cannot se the -All parameter.
I’ve tried both with and without MgProfile Beta.
Error Message:
Get-MgTeam : A parameter cannot be found that matches parameter name ‘All’.
At C:\temp\FindTeamChannelsWithWiki.PS1:21 char:28
+ [array]$Teams = Get-MgTeam -All
+ ~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-MgTeam], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Get-MgTeam
I ran the script against my test tenant and everything worked great. Now, I want to run the script against my production tenant but it automatically connects to my test tenant. I have closed out of PS and ended all PS sessions. Am I doing somthing wrong?
Thanks for writing this, really interesting. What happens if a company decides not to do anything I assume the wiki feature will stay in SharePoint and users can continue to use it from within SharePoint?
No. The only date stored is the created date (add $TabData.Configuration.AdditionalProperties.dateAdded to the fields reported if you want this information)
{"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}
Tx for sharing above interesting & valuable resources.
Is there a command/method to verify if there’s any content stored/entered on the Wiki tabs?
This is one of those things that is technically possible but not worthwhile. You could find the files in SharePoint, but how could you assess the worth of their content?
Our objective is to inform the business user community (espcially those who’ve put info on Wikis) about the upcoming change to OneNote (or will Wikis users (Team owners/members) be informed automaticaly?
Using GraphAPI I notice that each Wiki Tab has a property ‘hasContent’ which is equals false in case nothing is entered on that page.
That’s no indication of whether the content is valuable. It might help you understand which wikis to check, but someone who knows the content still needs to validate it.
Hi Eric, I’ve been playing with the wiki hascontent configuration and found that not all wikis have the information and in some cases (older channels) it is blank. But it might be a good thing to check and I am updating the script so that people have a chance to use the information. Thanks for pointing it out…
I updated the script. See what you think…
Tony, I’m getting the following error when running your script:
PS C:\Windows\System32> .\wiki.ps1
Welcome To Microsoft Graph!
Finding Teams
Get-MgTeam : Requested API is not supported. Please check the path.
At C:\Windows\System32\wiki.ps1:9 char:1
+ [array]$Teams = Get-MgTeam -All
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: ({ Top = , Skip …ndProperty = }:f__AnonymousType29`8) [Get-MgTeam_List], RestException`1
+ FullyQualifiedErrorId : NotFound,Microsoft.Graph.PowerShell.Cmdlets.GetMgTeam_List
For some reason, I can’t find any Teams… exiting…
Make sure that you’re connected to the beta endpoint.
Select-MgProfile Beta
It’s in the script now. I omitted the line when cutting and pasting into GitHub.
Thanks Tony! Looks like that did it.
Hi Tony
I’m confused, every method i try to run this very needed script (thank you) just returns
PS C:\support\scripts> Select-MgProfile Beta
Select-MgProfile : The term ‘Select-MgProfile’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again
I assume I’m missing a module i need to load or something, but don’t know which one… yet??
James
I get the same with the connect command
Connect-MgGraph : The term ‘Connect-MgGraph’ is not recognized as the name of a cmdlet etc etc
Have you installed the Microsoft Graph PowerShell SDK from the PowerShell Gallery? If you haven’t installed the SDK, you can’t run SDK cmdlets: https://www.powershellgallery.com/packages/Microsoft.Graph/1.21.0
Hi Tony, tx for updating the script 👍🙏💪 > great help. In the mean time I used Power Automate w/t same instructions/methods as in your script to compile a list of Channels & Wiki tabs , possible having (useful) content and owners to inform🙂
It’s great that there are several ways to get a job done.
Hi Tony, thanks for the script! Has Microsoft released the migration tool yet?
Haven’t seen it yet…
Hi!
I’am having some problems running the script.
I’ve tried different versions of Microsoft.Graph module but with no luck.
If I run (Get-Command Get-MgTeam).parameters I cannot se the -All parameter.
I’ve tried both with and without MgProfile Beta.
Error Message:
Get-MgTeam : A parameter cannot be found that matches parameter name ‘All’.
At C:\temp\FindTeamChannelsWithWiki.PS1:21 char:28
+ [array]$Teams = Get-MgTeam -All
+ ~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-MgTeam], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Get-MgTeam
According to the SDK documentation https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.teams/get-mgteam?view=graph-powershell-1.0, the -All parameter is supported. It seems like Microsoft has removed it in the latest version of the SDK.
The simple workaround is to use a Get-MgGroup call to find team-enabled Groups:
[array]$Teams = Get-MgGroup -Filter “resourceProvisioningOptions/Any(x:x eq ‘Team’)” -All
Just tried running it and I got “For some reason, I can’t find any Teams…” message. Did I miss configuring something?
Check your permissions. If you don’t have the necessary permissions, you can’t find any teams.
I ran the script against my test tenant and everything worked great. Now, I want to run the script against my production tenant but it automatically connects to my test tenant. I have closed out of PS and ended all PS sessions. Am I doing somthing wrong?
Did you run Disconnect-MgGraph to disconnect the Graph session?
That was it! Thank you!
Thanks for writing this, really interesting. What happens if a company decides not to do anything I assume the wiki feature will stay in SharePoint and users can continue to use it from within SharePoint?
The wiki feature remains in SharePoint. It is not affected by this decision.
Thank you
Are wiki’s in Teams Meeting notes impacted by this? If so, is there a way to search for those as well.
No, they’re not. However, Microsoft is moving towards using Loop components for meeting notes.
I ran the script but it gave an error on most of the Teams saying Forbidden,Microsoft.graph.PowerShell.Cmdlets.GetMGTeamChannel_List3
I am a Teams admin
It did return the Teams that I am a member/owner of.
The clue is the word forbidden. Your connection to the Graph doesn’t have the necessary permissions to allow the Get-MgTeamChannelTab cmdlet to run.
Thanks, I disconnected and reauthenticated and was able to run the script…thanks!
Hi Tony
Thank you for the script very helpful.
Is there way to get the last modified date on the Wiki tabs?
No. The only date stored is the created date (add $TabData.Configuration.AdditionalProperties.dateAdded to the fields reported if you want this information)