Vue normale

Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.
À partir d’avant-hierFlux principal

Find All the Stream (Classic) Web Parts During Migration to Stream in SharePoint

Another day, another opportunity to spackle the walls of SharePoint where there’s a hole. Wouldn’t it be great if you could go somewhere in the SharePoint Admin Center to see all the places you’ve used a particular Web Part in pages? Well, you can’t, so PowerShell. PnP.PowerShell, in fact.

You may be considering migrating your videos from Stream Classic to Stream in SharePoint. After all, it’s got to happen sooner or later, and the migration tool is now available for everyone. At Sympraxis, we’ve started to help our clients with these migrations, usually in the context of other work.

One thing you’re likely to want to know is where you have used the Stream (Classic) Web Part in your pages. Depending on how you do the migration, it is likely going to be a good idea to visit many of those pages to either switch to the Document Library Web Part or at least validate the Stream (Classic) Web Parts are working.

Just as I did when I upgraded from the PnP Modern Search Web Parts v3 to v4 (See: Upgrading the PnP Modern Search Web Parts from v3 to v4: Where are they?), I turned to PowerShell. I grabbed that same script and buffed it up a bit to find the Stream (Classic) Web Parts this time.

I took a bit of a different approach with this iteration, though. Rather than using search to find the pages with the Web Parts (I found it was missing some), I switched to using Get-PnPPageComponent | PnP PowerShell. This allows me to get the Web Parts (aka Page Components) in a page directly.

The script below is what I used. I’ve included some comments to indicate where you might choose to do things a bit differently, depending on your environment and your goals. I’m just outputting the info to the console, as the tenant where I’m working isn’t that dense. You may choose to output to a CSV file or something else.

Want to know more about migrating to Stream in SharePoint? Watch the recording of our AskSympraxis from November 30, 2022: Migrating from Stream Classic.

# findStreamClassicWebParts.ps1 - Inventory Stream Classic Web Parts to ensure they still work after migration

# Connect to your tenant here. This should be the only change you need to make to use this script.
$tenant = "sympmarc"
$adminConnection = Connect-PnPOnline -Url "https://$($tenant)-admin.sharepoint.com" -Interactive  -ReturnConnection

# Get all the sites to check
# Checking all the Communication Sites and Team Sites
# $sites = Get-PnPTenantSite | Where-Object { $_.Template -eq "SITEPAGEPUBLISHING#0" -or $_.Template -eq "GROUP#0" }

# Checking sites associated with the Intranet (Home Site)
$sites = Get-PnPHubSiteChild -Connection $adminConnection -Identity "https://$($tenant).sharepoint.com" | Sort-Object

# You may choose to exclude some subsets of sites
$filteredSites = $sites | Where-Object { $_ -eq "https://$($tenant).sharepoint.com/sites/Exec-BoardRelations" }

foreach ($site in $filteredSites) {
    Write-Host -BackgroundColor White -ForegroundColor Black "Looking in $($site)"

    # Get the pages
    $siteConnection = Connect-PnPOnline -Url $site -Interactive -ReturnConnection
    $pages = Get-PnPListItem -Connection $siteConnection -List "Site Pages" | Where-Object { $_.FieldValues.File_x0020_Type -eq "aspx" }

    foreach($page in $pages) {
        #Write-Host -BackgroundColor White -ForegroundColor Black "Checking $($page.FieldValues.FileLeafRef)"
        $streamPage = Get-PnPPageComponent -Connection $siteConnection -Page $page.FieldValues.FileLeafRef | Where-Object { $_.Title -eq "Stream" } | Select-Object Title, WebPartId
        if($streamPage) {
            Write-Host -BackgroundColor Green -ForegroundColor Black ">>> Found Stream Classic Web Parts in this page: $($page.FieldValues.Title) - $($page.FieldValues.FileDirRef)"
        }

    }

}

Using PnP.PowerShell in Visual Studio Code

PnP.PowerShell is one of my favorite tools of the trade. I’ve had to set up multiple machines for myself or others for this lately, and I always find myself looking for the fastest path to glory. Usually, it takes about 9 articles and 15 blind alleys, so I figured I’d capture what seems to work for me. Hopefully I can keep this up to date if things change.

Install Visual Studio Code

Visual Studio Code aka VS Code aka VSCode aka Code (which I’ll use in the rest of this post) is the “modern”, free code editor from Microsoft. I’ve used dozens of code editors over the years and Code is one of the best. Plus, everyone else is using it!

Obviously, you need to have VS Code installed to start. You can download it from Download Visual Studio Visual Studio Code – Mac, Linux, Windows.

Set Execution Policy

This one gets me every time. You’ll want your Execution Policies set like this:

This allows you to install PowerShell modules with less friction. It’s possible your organization won’t let you make this change. You can see your current settings by typing

Get-ExecutionPolicy -List

in a terminal window. To open things up, run this cmdlet:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine

I’m sure there are reasons to set this in different ways based on your organization’s view of security. I’m not going to get into that here: heed your governance rules.

Install PowerShell 7

If you’re running a Windows machine, you’ve most likely got PowerShell 5 (PS5) installed by default. PowerShell 7 (PS7) has more capabilities and is required for PnP.PowerShell to run successfully. Some cmdlets may run just fine with PS5, but don’t be fooled: you want PS7.)

Installing PowerShell on Windows – PowerShell | Microsoft Docs

Install the PowerShell Extension

One of the great things about Code is the rich ecosystem of extensions. The PowerShell extension from Microsoft makes Code smart about PowerShell. You want it.

PowerShell – Visual Studio Marketplace

Switch Code to PS7

I find the instructions for this confusing. PS5 is also called Windows PowerShell (x64) and PS7 is also called PowerShell (x64). In other words, the 5 and 7 don’t show un in the instructions in Using Visual Studio Code for PowerShell Development – PowerShell | Microsoft Docs.

This part is clear:

Use the following steps to choose the version:

  1. Open the Command Palette on Windows or Linux with Ctrl+Shift+P. On macOS, use Cmd+Shift+P.
  2. Search for Session.
  3. Click on PowerShell: Show Session Menu.
  4. Choose the version of PowerShell you want to use from the list.

You’ll want to choose PowerShell (x64), if it isn’t already selected.

Pro tip: When you’ve got a PowerShell file (.ps1, .psm1, etc.) open, you can also get to the PowerShell Session Menu by clicking on the squiggly brackets next to PowerShell in the bottom toolbar. Plus, the version is there!

Install PnP.PowerShell

Finally, the piece de resistance: PnP.PowerShell. This is the module that lets us do so much with Microsoft 365. If you’re using the SPO module instead, I say switch.

You need to run Code as an administrator if you want to install modules. To do this, I usually just type Code in the search box in Windows 11, right click the result, and choose Run as administrator.

From here, follow the instruction on the Installing PnP PowerShell | PnP PowerShell page.

Happy PowerShelling!


This article is for those of you on a Windows machine. I don’t have a Mac, nor do I want a Mac. I also don’t run Linux. Or a Sinclair Z-80 (though I loved the one I had way back when, it wouldn’t run PowerShell).

I expect I’ve missed a few little bits here. Feel free to tell me so in the comments, and I’ll make updates. Also, let me know if this is helpful!

References

Replace that Classic SharePoint Root Site

Working in a client tenant today, I noticed a new suggestion in the SharePoint Admin Center I hadn’t seen before. It’s certainly possible it’s been around for a while, but it was new to me.

The tenant where I’m working has been around since at least 2015. That means it was created with a classic SharePoint site as the root site. Back then there was no such thing as a modern SharePoint site, and Microsoft hasn’t forced us to replace what we got when we created the tenant. In the message above, they are suggesting site modernization. Interesting, I thought.

We do this modernization all the time as we help people build new Intranets or try to get more from their investment in the Microsoft 365 platform. It’s not at all unusual for an organization to have been using Microsoft 365 for years but maybe only using it for Exchange. Or maybe using one Document Library in the root site to store ALL the organization’s documents. Believe me, we’ve seen all sorts of things which would surprise you. It’s one of the reasons we’re so passionate about the Microsoft 365 Maturity Model.

The great thing about this recommendation is it actually steps you through the process. I figured it might be useful to know how it works for those of you who aren’t into the platform up to your elbows like we are.

When you click the View recommendation button, you get a nice set of suggested steps to follow to set up and configure a new modern site for the root.

Here are those steps and links. Generally, organizations will want a modern Communication Site in the root of their tenant. This site tends to be the launchpad for the organization’s Intranet. At the very least, it can be a launchpad into Team Sites where people do their work.

  1. Plan the site content. This step includes understanding the goals of stakeholders and the needs of users. Learn more
  2. Build the site. Create a communication site, customize the design, and add your content. Learn more
  3. Prepare to launch. Set site permissions and test the site. Learn more

The process of building out the new Communication Site need not be complex, but usually you’re planning an entirely new Intranet or set of access paths for folks to get their work done. Thus, while building the new site isn’t complex (you can create a new Communication Site in about 7 seconds!), deciding how it should look, what navigation it should have, what content it should house, etc. can take some real planning. Let’s gloss over all that, shall we?

Once you have the new Communication Site – we tend to build it in a location like /sites/NEWIntranet – you’ll come back and click the Replace root site button. On the following screen, you simply provide the URL to the Communication Site you’ve just built. Note the caveats: the new site can be a Communication Site or a Team Site, but it can’t be a Hub Site or connected to a Microsoft 365 Group. This is because swapping a site into the root means fixing up a lot of links and other stuff under the covers.

Also note the existing root site will be moved to an archive location. You won’t lose the site or its contents – but it won’t be in the same spot anymore.

At this point, I’ve stopped my exploration because clicking that Save button is going to initiate what we call a “site swap”. Once it’s done, your new site will be in the root location, the old site will be in the archive location, and everything should work just great. You’ve put a whole communication plan about this is place before you click the button, right?


If you want more control over this process, you can do what some of us have been doing for several years now: you can use the PnP.PowerShell Invoke-PnPSiteSwap cmdlet. You still build the new site in a new location, but when it comes time to do the site swap, you simply call the cmdlet, something like this:

$tenant = "mytenant"
$adminSiteUrl = "https://$($tenant)-admin.sharepoint.com"

Connect-PnPOnline $adminSiteUrl -Interactive

Invoke-PnPSiteSwap `
    -SourceUrl "https://$($tenant).sharepoint.com/sites/Intranet" `
    -TargetUrl "https://$($tenant).sharepoint.com/" `
    -ArchiveUrl "https://$($tenant).sharepoint.com/sites/Archive"

This may appeal to you because you can specify the archive destination, but the net effect is exactly the same. Note that you can only use this cmdlet to swap a site into the root; you can’t arbitrarily swap two other sites. (You can however, rename them.)


It’s great to see suggestions like this coming into the admin UIs. It’ll help a lot of organizations with a support staff of one – and there are more of those than most people think!

Changing a SharePoint Site URL When Connected to Microsoft Teams

I shot myself in the foot today and I figured I’d share how I bandaged it back up. In actual fact, the healing was automagical.

We had a Microsoft Team with its usual backing SharePoint site, and we wanted to reclaim the URL from that SharePoint site. This isn’t an unusual occurrence when there isn’t much governance around Team or site creation. People create Teams with whatever names – and thus URLs – makes sense to them. Retrofitting some governance can take some renaming.

Changing a SharePoint site’s URL isn’t that hard these days. I changed the URL in the SharePoint Admin Center easily. See Change a site address – SharePoint in Microsoft 365 | Microsoft Docs for the steps.

Since we wanted to reuse the URL, the next step was to delete the redirect site which is left behind for the old URL PnP.Powershell. See my post Cleaning Up Redirect Sites in SharePoint Online for how and why you might want to do this.

After the deletion of the redirect site, we realized the team had been accessing the SharePoint site exclusively in Microsoft Teams, so we went to check that the files were still available in Teams. Uh-oh. No, they weren’t.

In Microsoft Teams, the Files tab in each channel was now broken, which is understandable – in retrospect. When we clicked into a Files tab, we got one of the standard “cute” error messages for a Document Library.

Panic ensued, at least on my end. I don’t like it when I break stuff.

I talked to my very smart colleagues at Sympraxis and we couldn’t come up with a reasonable fix for this. It was a good discussion, though, and showed the breadth of knowledge we have among us. I spent some time in Binglage, too, of course.

After a while, I was looking at the Files tabs again, and I noticed the in the General channel’s Files tab was working fine. Hmm. I tried another channel (this Team has 13 channels), and it was broken. I tried another Files tab – also broken. I went back to the first non-General Files tab, quite by accident, and it was working fine again.

Turns out, Teams was able to heal each Files tab by itself. By navigating to each of the Files tabs, navigating to another tab, and navigating back to the Files tab, Teams “fixed up” its connection to the corresponding folder in the SharePoint site’s Documents library. If I caught it right, on a few of the clicks into a Files tab, I saw the following message screen, showing that Teams was working on it.

I’m extremely relieved that Teams was able to self-heal in this situation. While I was incautious in my actions, Teams was smart enough to fix itself for me. This is a sign of the good stuff Microsoft is doing these days, realizing end users make mistakes, and so do people like me, even with a lot of experience.

Get All the Public or Private Team Sites in SharePoint with PnP.PowerShell

When you create a Team Site in SharePoint, you have an option to set the Team Site as:

  • Public – anyone in the organization can access this site, or
  • Private – only members can access this site

Many people don’t know what the effect this setting has – I need to remind myself from time to time.

Private means the site is not discoverable; only people who are assigned specific permissions for the site can find it – even if they happen to guess the URL. Private Team Sites make sense when even knowing the name of the Team Site might be problematic. “Surprise Birthday Party” or “Firing People” come to mind.

Public means the site is discoverable; anyone in the organization can find the site using search or even just guessing the URL. More important, when you create a site as Public, the Everyone except external users pseudogroup is added to the Members for the site. This means every licensed user can add and edit content – unless you change the permission settings.

If any of the above is a surprise to you, well I’m not surprised by that. I don’t think the wording on the Create site dialog is all that clear, and unless I’m missing something, I can’t find a Microsoft article which explains it in the amount of detail I give above.

If you’d like to know what the setting is for any particular site, here’s how you’ll know. As of this writing (it’s moved around a bit in the past and can vary based on your header settings for the site), you can tell if a site you’re visiting is Public or Private by looking in the upper right on the home page:

That’s well and good if you have a site or two to check. But what if you’d like to know how all your sites are set up? Time to turn to trusty PnP.PowerShell. I needed to do this today and it was really hard to figure out where the setting was available. Turns out, it’s not a setting on the site itself, but on the underlying Microsoft 365 Group.

Once I knew that, easy-peasy.

This single line of PnP.PowerShell will retrieve all the Microsoft 365 Groups where the Visibility property is set to Private. If you want the Public sites, well I’ll leave that to you, dear reader.

Get-PnPMicrosoft365Group -IncludeSiteUrl | Where-Object { $_.Visibility -eq "Private"}

Of course, you’ll need the appropriate permissions and you’ll need to have connected to the SharePoint Admin site with Connect-PnPOnline first.


If you’d rather not use PowerShell (and Todd will be offended of you don’t!), you can also see this setting in the Exchange admin center (microsoft.com) in the Groups listing. That listing can be exported to Excel if you’d like to do more slicing and dicing.

References

❌
❌