Office 365 Advent Calendar – 15 Activating Publishing Features on SharePoint Online Sites with PowerShell



Activating SharePoint’s Publishing features can easily be done on a single site collection or site. But what if you need to activate Publishing on a hierarchy of subsites, or across multiple site collections?


Once again, we’re using the PnP PowerShell cmdlets.

First some basics. The ‘main’ feature to activate is the PublishingSite feature on the Site Collection level. After you connected to a site collection (Connect-PnPOnline), you can activate it as follows:

Enable-PnPFeature -Identity f6924d36-2fa8-4f0b-b16d-06b7250180fa -Scope Site

The -Scope Site parameter is important, as the default for this parameter is set to Web, and the feature wouldn’t get activated without specifying it correctly.

Once that’s done, we can activate the PublishingWeb feature for the current site (on a Web scope):

Enable-PnPFeature -Identity 94c94ca6-b32f-4da9-a9e3-1f3d343d7ecb

Office 365 Advent Calendar – 14 Exporting SharePoint Online List/Library Details


Well, this is a bit embarrassing. Yesterday, for the first time, I didn’t verify if my scheduled blog post got published properly. And yesterday, also for the first time, it didn’t get published. I made a small scheduling mistake (it’s not 2017 yet…), so the 14th December post comes a day late:


From time to time you may need an overview of all lists and libraries in your site together with the number of items in each list/library, and when an item in it was last modified. You can easily see this information from the Site Contents page:

But there are times when this information needs to be available in Excel, which is what I’ll show you today how to retrieve:


$cred = Get-Credential
Connect-PnPOnline -Url "https://mytenant.sharepoint.com/sites/demo" -Credentials $cred

#the following is required to load the corresponding list templates for each list/library
$ctx = Get-PnPContext
$templates = (Get-PnPWeb).ListTemplates

Get-PnPList | select Title, @{label="Url";Expression={$_.RootFolder.ServerRelativeUrl}},`
@{label="Type";Expression={$bt=$_.BaseTemplate;$templates |`
Where{$_.ListTemplateTypeKind -eq $bt} | foreach{$_.Name}}},`
ItemCount, LastItemModifiedDate | Export-Csv c:\ListInfo.csv

And here’s the output from the script:


Office 365 Advent Calendar – 13 Useful Office 365 Sessions from Microsoft Ignite


End of September, the Microsoft Ignite conference took place in Atlanta with hundreds of sessions across a huge rang of Microsoft products. The great news is that these sessions are available on demand for anyone to view! If you’re interested in taking them offline, have a look at the Ignite 2016 Slidedeck and Video downloader script.

Today, I’ll share with you some of my favourite sessions:

Drive productivity with OneDrive and SharePoint file collaboration

Files are at the core of the modern world. They reflect people’s and organizations’ aspirations, processes and outcomes. Making it easy to securely create and collaborate on important files such as budgets, reports, whitepapers and presentations is critical to organizational success. See all the options that Microsoft OneDrive and Microsoft SharePoint provide to enable people to work together more effectively to drive successful outcomes. We demonstrate all the possibilities available today for browser, mobile and desktop experiences and how this fits into productivity tools and essential business applications.

Why I recommend it:
 A great overview of OneDrive for Business and SharePoint and which route Microsoft is taking with them.


Build your intranet with Microsoft Office 365

There is a growing trend of organizations moving to the cloud to meet their intranet needs. While many organizations are running their intranets on premise, many are considering entirely cloud-based solutions or running them on platforms like Office 365. The question for many companies is “should our intranet be built with Microsoft Office 365?”

In this session, Richard Harbridge explores:
• The benefits Office 365 brings to an intranet
• Where the issues and challenges will lie
• When and how you may integrate Office 365 with your existing intranet today

Why I recommend it: Richard is a great guy and passionate presenter. He’s got a lot of experience and knows what he’s talking about. This topic here is one very close to my heart, as I’ve been working with SharePoint as an intranet platform since 2007.


Build business applications with Power Apps, Microsoft Flow, and Office 365

PowerApps and Flow are services for building and using custom business apps that connect to your data and work across the web and mobile – without the time and expense of custom software development. This session demonstrates how to build custom business applications, describes the vision behind PowerApps and Flow, and features key scenarios.

Why I recommend it: People have been looking for an InfoPath replacement every since it has been deprecated. While PowerApps is far from being one, it is at least the successor to InfoPath and may at some point in the future offer similar functionality. Either way, if you’re interested in forms and business processes, this is a good introduction to the latest Microsoft tools which became generally available in the meantime.


Improve Office 365 adoption: top 10 ways

How are organizations able to succeed with the constant change of Microsoft Office 365? Office 365 provides an incredible amount of value to individual employees, teams, departments and organizations. Much of this value is not realized immediately upon purchase or even deployment of Office 365. The value is realized as more and more users understand, adopt and embrace the technology that has been implemented. So how can organizations drive faster, sustainable and effective adoption? They perform campaigns, run activities, and take action. Join Kanwal Khipple as he shares industry leading real world experience, advice and activities that other customers are leveraging to get more from Office 365 and drive more meaningful adoption.

Why I recommend it: It’s a panel discussion by Susan Hanley, Richard Harbridge, Christian Buckley, and Kanwal Khipple! And if you do not just want to introduce some technology, but want to ensure that people use it and receive value from it, you should definitely watch this.


Learn about PnP and the new SharePoint Framework

Office 365 Dev and SharePoint Patterns & Practices (PnP) helps customers move forward whether building solutions for today or tomorrow. Get latest update on the provided samples, reusable components and practices. See also what the PnP team is doing to support the new Microsoft SharePoint Framework and how you can participate to this community driven initiative.

Why I recommend it: If you look at my other Office 365 Advent Calendar posts, you can see that I posted quite a good amount of samples for the PnP PowerShell cmdlets. But this is not the only thing coming from the PnP team, there’s lots more! Vesa shows you all the other awesome things, and gives some introduction on the new SharePoint Framework. If you’re a SharePoint developer, this is a session not to be missed.


Office 365 Advent Calendar – 12 Get External Sharing Details for SharePoint Online Sites



SharePoint Online allows you to share your content with external parties – that is, if sharing is allowed on the tenant level as well as on the site collection level. But if you allow external sharing on the tenant level, how can you easily see for which site collection you have which kind of external sharing level enabled?


Today’s script doesn’t make use of the PnP PowerShell cmdlets, but of the ‘standard’ Microsoft SharePoint Online Management Shell. You connect to your tenant, verify first if sharing is enabled generally, and if so, exports a list of all site collections together with their sharing level (Disabled, Authenticated External Users, Authenticated External Users and Anonymous Users, Existing External Users only) to a CSV file.

$cred = Get-Credential
Connect-SPOService -Url https://mytenant-admin.sharepoint.com -Credential $cred
$tenant = Get-SPOTenant

if($tenant.SharingCapability -eq "Disabled") {
	Write-Host "External Sharing is not enabled on this tenant" -ForegroundColor Red
} else {
	#External Sharing is enabled. We'll fetch the details for all sites in the tenant
	Get-SPOSite -Limit All | select Url, SharingCapability | Export-Csv externalsharingreport.csv

Note, the list of site collections does not include any OneDrive for Business sites. At the moment, simply refer to the mytenant-my.sharepoint.com site collection to see what kind of external sharing is enabled for OneDrive sites.

Office 365 Advent Calendar – 11 Adding sample items with random data to a SharePoint Online List



Sometimes you want to create some random sample data to be used in a SharePoint Online list. For example, in yesterday’s post I was using a list with some data which I entered manually, but I thought afterwards that I could’ve scripted it to create many more items in my demo list. Today, I show you how you can easily fill a list in SharePoint Online with as many sample items as you need, all with random values based on some predefined arrays.


The code below requires a few things from you:

  1. You need to define the number of items you want to create
  2. You need to define a few arrays with potential values for each of your columns (in my case, $Company, $Region, and $Product)
  3. You need to define the list where you want to add those items to
  4. Lastly, you need to update the -Values parameter with the correct column names for your list
$itemsToGenerate = 10
$listName = "Sales Pipeline"

# Sample data for the list
$Company = ("Ah Loong Pte Ltd", "Contoso Inc", "Fabrikam Corp", "Flowers by Irene",`
 "NorthSouth Trading Inc", "Petrox Oil Company", "Spacely Sprockets", "The Frying Dutchman")
$Region = ("North", "East", "South", "West")
$Product = ("Admin ToolKit", "EZClean", "WonderTool 2000", "Business Process WonderKit")

$cred = Get-Credential
Connect-PnPOnline -Url https://mytenant.sharepoint.com/sites/demo -Credentials $cred

foreach($i in 1..$itemsToGenerate) {
	#Update the -Values below with the correct column names from your list
	Add-PnPListItem -List $listName -Values @{`
		# I'm assigning a randomly chosen value from the $Company array to the item column
		"Title" = $Company[(Get-Random -Minimum 0 -Maximum ($Company.Count))];`
		"Region" = $Region[(Get-Random -Minimum 0 -Maximum ($Region.Count))];`
		"Product" = $Product[(Get-Random -Minimum 0 -Maximum ($Product.Count))];`
		# Here, I want to create a random number between 150 and 99999
		"Potential_x0020_Value" = (Get-Random -Minimum 150 -Maximum 99999);}

Office 365 Advent Calendar – 10 SmartFilters and Grouping in SharePoint Online Modern Lists


Microsoft has just started rolling out a new feature called Smart Filters to SharePoint Online tenants with First Release enabled, all tenants will see it in January. Smart Filters are available in Modern Lists, and allow you to filter from a sidebar pane to easily and quickly find items you’re looking for.

What’s the difference to the existing filtering functionality on columns? Smart Filters are not just shown for a single column, but for all supported columns in the current view, so that you can easily filter your data from a single pane. However, not all types of columns can be filtered. In the recording below, the column ‘Company’ is a ‘Single Line of Text’ column, which currently can’t be used. I suspect that we will see some improvements here soon. Lastly, once you’ve found a nice set of filters that you find useful, you can save them as a new View.


The nice thing about Smart Filters is that they also work with the new Grouping functionality in Modern Lists. You can use both of them at the same time to drill down into your data and hopefully gain some valuable insights:

Office 365 Advent Calendar – 09 Staying up to date on Office 365 Changes

When you use Office 365, there’s on thing that’s certain: change is constant, new functionalities get introduced all the time, and the pace of updates is much higher than in your own environment. In this post, I’m showing you how you can stay up to date on any changes to Office 365 to ensure that you can provide a great service to your users.

With your on-premises systems, you are in control of what’s happening when. You can define when a specific update gets installed, or when you introduce some new functionality. You’ve got time to prepare for these changes, inform all relevant stakeholders, and you can ensure that an adequate level of support gets provided.

But when it comes to Office 365, it’s Microsoft who defines the pace – and they are fast! New features and functionalities, as well as improvements to existing solutions are rolled out on a nearly daily basis – as an example, more than 350 features were introduced between 7/2015 and 6/2015. Some of them may only have a very small impact on your users, but others may make a big difference to your environment and your users. Think about the introduction of Delve – this is not just a small new feature that a few of your users may use, but rather a new way of discovering information for the whole organization. A change of this size and impact needs to be handled properly, and therefore you need to ensure that you (and your organization) are always aware of any major changes that are happening in your Office 365 tenant.

Do you have to stay up to date on every single change introduced to Office 365? As mentioned, there are new changes occurring all the time, which would make it both difficult and troublesome to monitor all of them. In my opinion, it is counterproductive to do so, and it’s better to focus only on the bigger changes, especially on those that have a larger impact on your organization.

One other thing to note is that features can get released earlier to specific tenants or users. If you’re interested in reviewing new functionalities before the rest of your organization receives them, make sure to enable “First Release” on your tenant for a specified set of users.

How do you manage change? This is something that goes far beyond the scope of this blog post. Most organizations already have some roles and procedures established for this purpose, and managing the change coming from Office 365 would be not much different than the changes that occur elsewhere. If you’re still looking for some guidance, here’s some introductory material from Microsoft: Change Management for the Enterprise


What follows are some of the Microsoft resources which provide further information about planned, current, and past changes:

Office 365 Roadmap

Get prepared for future changes by looking at what is on the roadmap. Microsoft updates http://roadmap.office.com regularly to show what they are currently working on, what they are planning to release in the upcoming months, and what has been introduced recently. Note that not every single update or new functionality will make it in here.


Office 365 Message center

When you log on to your Office 365 Admin center, you can find the ‘Message center’ towards the middle of the page. In here, you will find a lot of updates that occurred recently and which have an impact on your environment. Check this regularly to see what has been introduced to your Office 365 tenant recently.


Office Blogs

Lastly, Microsoft also published some general information on new functionalities on https://blogs.office.com/. This is the place where you can find information about new features in a very user-friendly format, so that you can share this information easily with your stakeholders. There is also an RSS feed which you can subscribe to. This way, you don’t have to visit the page on a daily basis, but you can get notified whenever there’s a new article.

Office 365 Advent Calendar – 08 Get Versioning Details for all Lists in a SharePoint Online Site


By default, libraries in SharePoint Online keep the last 500 major versions of a item, but lists have no versioning turned on. And while you can easily finetune the settings for all lists and libraries in a site, it may be good to know how versioning is set on each library before you look at changing those settings. Today’s post provides you with a script that retrieves all versioning related information (everything you seen on the ‘Versioning settings’ page of a list/library) from all lists and libraries within a given site.


$cred = Get-Credential
Connect-PnPOnline -url https://mytenant.sharepoint.com/sites/testsite -credentials $cred

$lists = Get-PnPList

$VersioningDetails = @()
foreach($list in $lists) {
	$VersioningDetails += New-Object PSObject -Property @{
		'List' = $list.Title
		'Require Content Approval' = $list.EnableModeration
		'Versioning Enabled' = $list.EnableVersioning
		'Major Version limit' = $list.MajorVersionLimit
		'Draft Version limit' = $list.MajorWithMinorVersionsLimit
		'Drafts visible to' = $list.DraftVersionVisibility
		'Checkout required' = $list.ForceCheckout

$VersioningDetails | Select 'List', 'Require Content Approval', 'Versioning Enabled',`
'Major Version limit', 'Draft Version limit', 'Drafts visible to', 'Checkout required'`
| Export-Csv versioningdetails.csv

Note: By default, all system libraries such as Solutions Gallery, Master Page Gallery, Web Part Gallery, User Information List, etc. are included.

Here’s a sample output, excluding the system libraries:

Office 365 Advent Calendar – 07 External Sharing for SharePoint Online FAQ

SharePoint Online provides you with the option to share content (sites, lists/libraries, documents) with externals – partners, vendors, customers, basically anyone outside your organization. Here are some Frequently Asked Question I’ve seen regularly:


How do I get started with learning more about External Sharing?

To get started, review the following 2 Microsoft support articles:

  1. Manage external sharing for your SharePoint Online environment
  2. Share sites or documents with people outside your organization


How is an external user actually defined? And what kind of license do they need?

An external user is someone who is not an employee of your company, and who has an account that is not created within your own tenant. Or in other words: an account that is not set up within any of your verified domains (mycompany.com, mycompany.de) and your tenant domain (mytenant.onmicrosoft.com).

For more details (e.g. what can an external user do), review the ‘What is an external user?’ section on Manage external sharing for your SharePoint Online environment

I want to enable external sharing for selected site collections only, how can I do that?

First, you need to activate external sharing for the tenant. This does not automatically enable external sharing on all your sites, the default setting is ‘Don’t allow sharing outside your organization’.

Once that’s done, you can then define per site collection whether sharing with externals is enabled, and with which configuration.


If I add an external user to a single site collection, does he have access to other site collections as well?

Please note that users added via the second step are always added to the “Everyone” as well as the “Everyone except Externals” groups. Users invited via the first step are only added to the “Everyone” group. These groups can be used to grant permissions to all users.


I want to enable external sharing on OneDrive for Business sites, how can I do that?

This can be achieved by modifying the sharing settings for your https://mytenant-my.sharepoint.com site collection. ‘Within’ this site collection, you have all your personal OneDrive for Business sites. Once you enable external sharing for it, your employees will be able to share content through here with external parties.


I want to enable external sharing with specified domains only, is this possible?

Yes, this can be done! In the SharePoint Admin portal under ‘Sharing’, you can configure this via the ‘Limit external sharing using domains (applies to all future sharing invitations). Separate multiple domains with spaces.’ setting. You could also do the reverse and define domains for which sharing is blocked.
You can find more information here: Restricted Domains Sharing in Office 365 SharePoint Online and OneDrive for Business


Can I set an expiry date on a link which I want to send to an external partner?

Yes, this can be done, but only for shared files and folders and only for anonymous links. When you share a file/folder with someone via their account, the sharing invitation and the link won’t expire.

On a tenant level, you can define when these links will expire via the ‘Anonymous access links expire in this many days’ setting. When you create a link to a file, you can then also define again when it will expire.


Can I get a list of all the external users?

Yes, you can use the Get-SPOExternalUser cmdlet for this.



Do you have any additional questions? Post them below as a comment

Office 365 Advent Calendar – 06 Bulk-Uploading Files with Metadata to SharePoint Online



A very common scenario is that you have multiple files that need to be added to SharePoint together with some metadata.  One way of achieving this is by uploading all files to the target library, and then using the Quick Edit functionality to update the metadata for them. However, this is a bit cumbersome, especially when you do not just have a few documents but potentially hundreds of them.

This solution provides an easy way to upload as many documents as wanted together with their corresponding metadata to to a single library in SharePoint Online. You’ll first need to prepare a CSV file with all relevant data, and then run a script to upload the documents and add their individual metadata.


To demonstrate the script, I created a document library and added two columns called ‘Country’ and ‘Customer’.



First, you need to prepare the CSV file with all the relevant data – the path to the files you want to upload as well as the metadata you want to use for each file. This data will then be used by the script by first uploading the files mentioned in the CSV file, and adding the corresponding metadata. Here is my example CSV:

Invoice 18932.pdf,Singapore,Qi Feng Pte Ltd
Cost Calculations.xlsx,USA,Contoso Inc.
Sales Agreement Template.docx,Germany,Fabrikam GmbH

The first row, the header row, is very important here. As you can see, I have three columns: ‘file’, ‘Country’, and ‘Customer’. ‘file’ is used to point to the file that should be uploaded. In my case, they are in the same folder as the script and the CSV, but you could also add an absolute path to a file somewhere else (C:\Users\rmodery\Desktop\MyFile.docx). This is the only column that is referenced directly in my script, and you should keep it.

Country and Customer are the additional columns from my document library. Important to note is that you need to use the internal names for your columns in the CSV file, not the display names (here‘s how you can find it out). You can replace these two columns with any of your columns without having to modify the code, it will read and use the available columns dynamically. So your structure could look like file,Status, DueDate,AssignedTo.

After you created your CSV file, modify the following code to match your environment. Replace ‘mytenant.sharepoint.com’ with the site you want to upload files to, rename ‘filestoupload.csv’ with your CSV filename, and lastly replace ‘Metadata Test’ further below with the path to your document library. You could also specify a path to a specific folder in a document library here, please review the Add-PnPFile documentation for more details.

$cred = Get-Credential
Connect-PnPOnline -Url https://mytenant.sharepoint.com -Credentials $cred

$files = Import-Csv filestoupload.csv
$metadatacolumns = $files | Get-Member -MemberType 'NoteProperty' | Select-Object -ExpandProperty 'Name' | Where {$_ -ne "file"}

foreach($file in $files) {
 $values = @{}
 foreach($metadatacolumn in $metadatacolumns) {
  $values.Add($metadatacolumn, $file.$metadatacolumn)
 Add-PnPFile -Path $file.file -Folder "Metadata Test" -Values $values


And here’s my library after I ran the script with the CSV file above, three documents were uploaded with the corresponding metadata: