Browse Tag


SPTechCon Boston Slides & Scripts


Thanks to all who joined my session at SPTechCon Boston.  This was my first SPTechCon event and look forward to speaking/attending again.  The conference was ran great and had a great selection of content.  I did a presentation on a deep dive into Office 365 Groups.  I went through some high level management topics and then went deep into Powershell administration options. I put all of the scripts that I discussed onto Github so people can help contribute.  I will be trying add to this project as I find new handy scripts.

Here are the links to the slides and the slides and the scripts:



Here is my session abstract:

Office 365 Groups enable teams to work together by establishing a single identity in Office 365. Office 365 Groups are a new and modern solution for collaboration in Office 365. There is a lot of confusion on what Groups can do and should be used for. This session will be a deep dive into all things Office 365 Groups focusing on the technical aspects..
We will spend a large amount of this session demoing Office 365 Groups. This session will include demos of:

  • How to create, access, and navigate
  • What are the core things to do
  • How are they technically structured
  • What administration is available and how to do it
  • What extensibility options are there

I will also walk through the pros and cons of using Groups vs other collaboration options in Office 365. Groups are also one of the fastest changing solutions in Office 365, so this session will bring everyone up to speed on the most recent updates that Microsoft has rolled out and what innovations are next. By the end of the session you should have a better understanding of what Groups can do and if they are right for your enterprise right now or in the future!

Disabling Office 365 Planner Using PowerShell

Office 365 Planner is now rolling out to your tenant.  Microsoft announced this week that Planner is ready for showtime. As this is a product early in its life cycle, Microsoft is still looking for feedback through the Planner uservoice site. Over the next several weeks, Planner will roll out to all eligible Office 365 customers worldwide. At this time, Planner is included with:

  • Office 365 Enterprise (E1, E3, E4, and E5)
  • Office 365 Education (E1, E3, E4, and E5)
  • Office 365 Business Essentials
  • Office 365 Business Premium.

Microsoft Planner will not be available to users by default in the General Availability (GA) update in the following subscription plans:

  • Office 365 operated by 21Vianet
  • Office 365 Government

An important thing to note with this release…

Each user who has one of the Office 365 plans mentioned above has a Microsoft Planner license that is enabled by default.

If your enterprise is not ready, an admin can add or remove licenses for individual users, or to disable Planner to all users. I put a script together that you can run to disable Planner for all licensed users in your tenant.  This script will:

  1. Disable any plan entered into the $disabledplans variable, by default it is just Planner (PROJECTWORKMANAGEMENT)
  2. Disable the Planner Preview SKU if it was assigned
  3. ***Reassign all other services not declared as being disabled.*** <- important  
    • Add any other services you want to disable in the $disabledplans variable (i.e. YAMMER_ENTERPRISE)

Thanks to @vladcatrinescu and his script on disabling Yammer as a starting point

#If you don't know how check out: 
#The initial script was built for Yammer removal by Vlad Catrinescu and can be found here:
#Updated by Drew Madelung to support O365 Planner GA
#This script will go through all licensed users and first check if they have the planner preview license and remove it and then check for the GA O365 planner license and disable it
#This script will re-enable all other services EXCEPT planner, If you want to disable more add them comma seaparated to the $disabledplans variable. 
#For example to disable Yammer and Planner use this: $disableplans = "PROJECTWORKMANAGEMENT", "YAMMER_ENTERPRISE"
#Set disabled plans (only Planner to start)

#Get All Licensed Users
$users = Get-MsolUser | Where-Object {$_.isLicensed -eq $true}

foreach ($user in $users)
 Write-Host "Checking " $user.UserPrincipalName -foregroundcolor "Cyan"
 $CurrentSku = $user.Licenses.Accountskuid
 #If more than one SKU, Have to check them all!
 if ($currentSku.count -gt 1)
 Write-Host $user.UserPrincipalName "Has Multiple SKU Assigned. Checking all of them" -foregroundcolor "White"
 for($i = 0; $i -lt $currentSku.count; $i++)
 #Disable preview planner if it is assigned to this user
 if($currentSku[$i] -like "*PLANNERSTANDALONE*" )
 $pos = $currentSku[$i].IndexOf(":")
 $tenant = $currentSku[$i].Substring(0, $pos)
 $license = $tenant + ":PLANNERSTANDALONE"
 Write-host $user.Licenses[$i].AccountSkuid "has Planner Preview. Will Disable for" $tenant -foregroundcolor "Yellow" 
 Set-MsolUserLicense -UserPrincipalName $user.UserPrincipalName -RemoveLicenses $license
 Write-Host "Planner Preview disabled for " $user.UserPrincipalName " On SKU " $user.Licenses[$i].AccountSkuid -foregroundcolor "Green"
 #Loop trough Each SKU to see if one of their services has the word PROJECTWORKMANAGEMENT inside. This is the service for O365 Planner
 if($user.Licenses[$i].ServiceStatus.ServicePlan.ServiceName -like "*PROJECTWORKMANAGEMENT*" )
 Write-host $user.Licenses[$i].AccountSkuid "has Planner. Will Disable" -foregroundcolor "Yellow"
 $NewSkU = New-MsolLicenseOptions -AccountSkuId $user.Licenses[$i].AccountSkuid -DisabledPlans $disableplans
 Set-MsolUserLicense -UserPrincipalName $user.UserPrincipalName -LicenseOptions $NewSkU
 Write-Host "Planner disabled for " $user.UserPrincipalName " On SKU " $user.Licenses[$i].AccountSkuid -foregroundcolor "Green"
 Write-host $user.Licenses[$i].AccountSkuid " doesn't have Planner. Skip" -foregroundcolor "Magenta"
 $NewSkU = New-MsolLicenseOptions -AccountSkuId $CurrentSku -DisabledPlans PROJECTWORKMANAGEMENT
 Set-MsolUserLicense -UserPrincipalName $user.UserPrincipalName -LicenseOptions $NewSkU
 Write-Host "Planner disabled for " $user.UserPrincipalName -foregroundcolor "Green"

Create SharePoint Subsites with Custom Permissions & Templates Using Powershell

powershell2I had a situation recently in which we were performing a migration from SharePoint Services 2.0 up to SharePoint 2013. When testing the path of copying the sites directly from 2.0 to 2013 they didn’t come across very clean. One of the main reasons was the way permissions was done in 2.0 does not directly match 2013. If we would have performed a migration like this they would have had a working environment but it would have been very hard to manage moving forward. Knowing that we didn’t want to copy the sites we decided to try to create all the new sites prior to the migration and then only copy the content.

When performing our pre-migration analysis we found around 2,000 sites and subsites. We performed multiple information architecture planning workshops to figure out the new site structure for 2013. Once we had the agreed upon new site structure we could then map the sites that needed to be migrated to their new locations. Once we had this kind of data I knew I could automate the creation of all the sites. Now I never like to start my scripts from scratch if I don’t have to and there are a lot of very smart people out there posting helpful info. I found some scripts online and put them together with my own special inserts and use cases. To give the proper credit to where I got this script started.

  • This is a great codeplex solution from @PhillipChilds that will create subsite structure as a CSV. This was a good start but would require me to enter all the information for the SharePoint groups that I needed.
  • I then found this script from @PointBeyond which would create the 3 default SharePoint groups I was looking for.

So now I had a script that would create subsites based on a CSV and create 3 default SharePoint groups if stated, awesome!

My last issue I ran into was the ability to apply a custom site template on the subsite. (here is a list of available site templates in SharePoint 2013 thanks to @vladcatrinescu) When you try to create a subsite using Powershell and pass through a custom site template it will not actually apply the template. The way to get this to work was to apply the site template after the subsite was created. So now all templates being applied whether default or custom will be applied after the site is created. Here is a little trick on how to get a custom site template ID without using Powershell.

I also included the enabling and disabling of a few site features.

  • Minimal Download Strategy will be disabled
  • Getting Started will be disabled
  • Publishing will be enabled

Here is a link to the script and the CSV to get started.


There are other areas that I would like to expand on this script but if you have any ideas please let me know!

Adjusting Email Notifications For SharePoint 2013 Task Lists

When looking at the settings of a SharePoint 2013 task list you no longer have the option to enable email notifications.  This used to be found under List Settings -> Advanced Settings -> Send e-mail when ownership is assigned.

This is what it looks like in 2010.


This can be still be turned on using Powershell in SharePoint 2013.  Here is the powershell to perform that task along with a link back to the source of the script.  Thanks to the creator of the script karimSP!

$site=Get-SPSite "http://sharepoint2013/"
if($list -ne $null)
 $list.EnableAssignToEmail =$true

Adjusting when the assigned to task email is fired

20  Fortunately we have the ability to change the types of event that fire these emails in powershell.  The primary use case I used this for is too only send task emails on creation of the item (Add).

The available options for when notifications are sent are listed in the SPEventType enumeration and they are:

Member Name Description
Add Additions to the list or list item. (0x00000001)
Modify All changes made in a list or list item. (0x00000002)
Delete Deletion of a list or list item. (0x00000004)
Discussion Changes in Web discussions. (0x00000FF0)
All All events pertaining to the list or list item. (-1)


Powershell to update the events

I have included variables at the top of the script that you can enter depending on the location of the task list(s) along with which ones you want to update.  Make sure you run the powershell to activate the assigned to email, the script above, prior to running this script.

# NAME: SharePoint2013TaskAlertEventTypes.ps1
# DESCRIPTION: Script to adjust SharePoint 2013 task list email notifications on different events
# AUTHOR: Drew Madelung
# LAST UPDATED: 11/11/2015

# ***IMPORTANT*** The powershell to enable assigned email notifications must be done prior to this script being ran

Add-PSSnapin Microsoft.SharePoint.Powershell

# Set variables - EXAMPLE variables are set
$sitecollectionUrl = "http://sharepoint2013"
# Eventtypes can be: All, Add, Modify, Delete, Discussion
$eventType = "Add"

# Optional variables - if not used, all event types for all assigned to task alert email notifcations on the listed site will be updated
$subsiteUrl = "/subsite"
$listUrl = "lists/tasks"

$site = Get-SPSite $sitecollectionUrl

# Get subsite if entered
if ($subsiteurl -eq "") { $web = $site.OpenWeb() } else { $web = $site.OpenWeb($subsiteUrl) }

$a = $web.Alerts

foreach ($alert in $a)
 $alerttemplate = $alert.DynamicRecipient
 if ($alerttemplate -eq "AssignedTo") {
 if ($listUrl -eq "") {
 $alert.EventType = [Microsoft.SharePoint.SPEventType]::$eventType
 Write-Host 'Updated event type to' $eventType 'for the list' $alert.list
 else {
 if ($alert.ListUrl -eq $listUrl) { 
 $alert.EventType = [Microsoft.SharePoint.SPEventType]::$eventType
 Write-Host 'Updated event type to' $eventType 'for the list' $alert.list
$site.Dispose()            Write-Host 'Updated event type to' $eventType 'for the list' $alert.list
        else {
            if ($alert.ListUrl -eq $listUrl) { 
              $alert.EventType = [Microsoft.SharePoint.SPEventType]::$eventType
              Write-Host 'Updated event type to' $eventType 'for the list' $alert.list

Link to download powershell script


If anyone has any thoughts or suggestions for this script please let me know!