Home‎ > ‎

Create subsite with PowerShell and Task Scheduler in SharePoint Server 2016

posted Dec 7, 2016, 2:58 AM by Benny Skogberg
This is a common scenario, which I’ve come across several times. You have a list of subsites to be created. It contains all the properties needed to create the subsite, but you don’t know how to do it. Either your stuck with creating a Workflow using Visual Studio or SharePoint Designer. If you use SharePoint Designer, you can use REST API. But it’s limited to 50 properties, which you will reach soon if your creating unique permissions, custom groups, adding users, and custom template. I’ve tried this approach for a couple of weeks, and it’s a daunting task. Further, the workflow manager farm or the workflow itself is pain to work with. It works on Monday, but not on Tuesday. So, I’ve decided to take this “creating subsite” task out of the workflow and are using PowerShell instead.

To me, it’s better, since I’m more skilled with PowerShell – and once you get it to work – it never fails. Never!

So, here’s what we’ll do in our script. Create a subsite that has a 
  • Custom template
  • Unique permissions (doesn’t inherit permission from the root web)
  • Adding groups and permissions 
  • Adding users to groups
In plain English, this script creates a subsite, owner, member and visitor group. Set permission on each group and add one site owner and several members – all based on my Custom List of Subsites.

The Task Scheduler
Create a new Task, where you make sure you trigger the 32-bit version of PowerShell which lives in System32 subfolders.

General

Trigger

Action

The action can be tricky to get right. First see too that you run with bypass executionpolicy and point to your PowerShell script.

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
-executionpolicy bypass -file C:\tasks\New-SPWeb-CustomTemplate.ps1

The script mentioned above is quite long, so don’t just copy-paste. Make sure you use your values in variables and fields.

The Script
if ($ver.Version.Major -gt 1) {$host.Runspace.ThreadOptions = "ReuseThread"} 
if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) 
{
     Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}

# Instance variables
$web = Get-SPWeb "http://SiteCollection"
$list = $web.Lists["Project"]
$fields = $list.fields
$items = $list.items
$subsite = $null
$createWeb = $false
$webs = Get-SPSite "http://SiteCollection" | Get-SPWeb

foreach($item in $items)
{
    if($item["subsiteCreated"] -eq $false)
    {
        Write-Host $item["SubsiteURL"] $item["subsiteCreated"] $item["Projektledare"]
        $subsite = $item
        $createWeb = $true

        # If we find an item, we use that one and skip the rest until next run
        break
    }
}

# To see wether or not there alredy is an subsite on the same URL
$newWeb = "http://SiteCollection" + $item["SubsiteURL"]

#Create a subsite from a new item if it's not already present
if($createWeb -and $newWeb -notin $webs.Url)
{
    ### Create subsite ###
    # If we use the -template property when we use New-SPWeb, the script fails. That's why we need to apply template
    # after the subsite is created
    Write-Host "Creating Web" $item["SubsiteURL"] -ForegroundColor Green
    $mainurl = "http://SiteCollection" + $subsite["SubsiteURL"]
    $template = $web.GetAvailableWebTemplates(1053) | Where-Object {$_.Title -eq "subsiteWeb"}
    $web = New-SPWeb $mainurl -Language 1053 -Name $subsite["SubsiteURL"] -UniquePermissions -UseParentTopNav 
    $web.ApplyWebTemplate($template.Name)
    
    
    ### Create Owner Group ###
    Write-Host "  Creating Owners group" -ForegroundColor Yellow
    $groupName = "Owner of " + $subsite["SubsiteURL"]
    $ownerName = $item["Projektledare"].split("#")
    $memberName = $item["Projektledare"].split("#")
    $description = "Owner of subsite " + $item["SubsiteURL"]

    if ($web.SiteGroups[$groupName] -ne $null)
    {
        throw "Group $groupName already exists!"   
    }

    $op = New-SPClaimsPrincipal $item["ProjectManager"] -IdentityType WindowsSamAccountName
    $mp = New-SPClaimsPrincipal $item["ProjectManager"] -IdentityType WindowsSamAccountName
    $users = $web | Get-SPUser

    foreach($user in $users)
    {
        if($user.DisplayName -eq $ownerName[1])
        {
            $op = $user
        }
        if($user.DisplayName -eq $memberName[1])
        {
            $mp = $user
        }

    }

    $owner = $web | Get-SPUser $op
    $member = $web | Get-SPUser $mp

    # Add user to group
    Write-Host "  Adding user to group" -ForegroundColor Yellow
    $web.SiteGroups.Add($groupName, $owner, $member, $description)
    $SPGroup = $web.SiteGroups[$groupName]
    $web.RoleAssignments.Add($SPGroup)
    $web.Update()

    # Set permission on group
    Write-Host "  Setting permissions on group" -ForegroundColor Yellow
    $role = $web.RoleDefinitions["Full Control"]
    $RoleAssignment = New-Object Microsoft.SharePoint.SPRoleAssignment($SPGroup)
    $RoleAssignment.RoleDefinitionBindings.Add($role)
    $web.RoleAssignments.Add($RoleAssignment)
    $web.Update()


    ### Create Member Group ###
    Write-Host "  Creating Member group" -ForegroundColor Yellow
    $groupName = "Medlemmar i " + $subsite["SubsiteURL"]
    $ownerName = $item["ProjectManager"].split("#")
    $memberNames = $item["Projektdeltagare"].User.UserLogin
    $description = "Medlemmar i projektet " + $item["SubsiteURL"]

    if ($web.SiteGroups[$groupName] -ne $null)
    {
        throw "Group $groupName already exists!"   
    }

    $owner = $web | Get-SPUser $op
    $member = $web | Get-SPUser $memberNames[0]

    # Add user to group
    Write-Host "  Adding user to group" -ForegroundColor Yellow
    $web.SiteGroups.Add($groupName, $owner, $null, $description) # Setting members to null, since we'll add them later
    $SPGroup = $web.SiteGroups[$groupName]
    $web.RoleAssignments.Add($SPGroup)
    $web.Update()

    # Add more users to group
    foreach($memberName in $memberNames)
    {
        $member = $web | Get-SPUser $memberName
        $SPGroup.AddUser($member)
    }
    $web.Update()

    # Set permission on group
    Write-Host "  Setting permissions on group" -ForegroundColor Yellow
    $role = $web.RoleDefinitions["Contribute"]
    $RoleAssignment = New-Object Microsoft.SharePoint.SPRoleAssignment($SPGroup)
    $RoleAssignment.RoleDefinitionBindings.Add($role)
    $web.RoleAssignments.Add($RoleAssignment)
    $web.Update()


    ### Create Visitor Group, with no users ###
    Write-Host "  Creating Visitor group" -ForegroundColor Yellow
    $groupName = "Visitor in " + $subsite["SubsiteURL"]
    $ownerName = $item["ProjectManager"].split("#")
    $description = "Visitor in subsite " + $item["SubsiteURL"]

    if ($web.SiteGroups[$groupName] -ne $null)
    {
        throw "Group $groupName already exists!"   
    }

    # Add user to group
    Write-Host "  Adding group" -ForegroundColor Yellow
    $web.SiteGroups.Add($groupName, $owner, $null, $description)
    $SPGroup = $web.SiteGroups[$groupName]
    $web.RoleAssignments.Add($SPGroup)
    $web.Update()

    # Set permission on group
    Write-Host "  Setting permissions on group" -ForegroundColor Yellow
    $role = $web.RoleDefinitions["Read"]
    $RoleAssignment = New-Object Microsoft.SharePoint.SPRoleAssignment($SPGroup)
    $RoleAssignment.RoleDefinitionBindings.Add($role)
    $web.RoleAssignments.Add($RoleAssignment)
    $web.Update()

   
    $item["subsiteCreated"] = $true
    $item.Update();
    $web.Dispose();
}





Comments