SharePoint 2013 Site Provisioning with Powershell and install/upgrade App
Usually one of the biggest tasks for On-premise SharePoint development is for custom site provisioning. Clients usually want all branding, configuration, and permission hardening done automatically when the site collection or web is created.
Since Microsoft has been pushing to move away from the farm solution and suggesting App Model, a lot of techniques (such as feature event receiver) that we used to depend on cannot be used anymore. It is a big change for On-premise SharePoint development.
Here is an approach that I think will work for the App model to provision a site if the requirements are not crazy in customizing OOTB SharePoint behaviour.
The solution will include
Below is the sample script that creates host-named site collection and installs App
$newSite = New-SPSite "http://test.com" -HostHeaderWebApplication "http://localhost" -Name "Community" -Description "It's a community" -OwnerAlias 'domain\account' -language 1033 -Template "COMMUNITY#0"
$myapp = Import-SPAppPackage -Path "D:\SiteProvisioning.app" -Site $newSite -Source ([microsoft.sharepoint.administration.spappsource]::CorporateCatalog) -confirm:$false
Install-SPApp -Web $newSite.RootWeb -Identity $myapp
if there is something needs to be updated through the App (i.e. upload updated master page), you can use the following sample script
$site = Get-SPSite "http://test.com"
$myapp = Import-SPAppPackage -Path "D:\SiteProvisioning.app" -Site $site -Source ([microsoft.sharepoint.administration.spappsource]::CorporateCatalog) -confirm:$false
$appInstance = Get-SPAppInstance -Web $site.RootWeb | where-object {$_.Title -eq "SiteProvisioning"};
$app = Update-SPAppInstance -Identity $appInstance -App $myapp -Confirm:$false
*** Update ***
Unfortunately, the PowerShell script above can't trust your App for you. So in order for your App to work, you'll have to at least manually install/trust you app to one of the site collection within the Tenant (Web application). This way your app will have the Tenant Full Control and the powershell will work for the future site collection creation. You'll get the access denied error like below if your App is not trusted.
Exception Details: Microsoft.SharePoint.Client.ServerUnauthorizedAccessException: Access denied. You do not have permission to perform this action or access this resource.
** Update November 6***
You can actually use the following powershell script to grant permission to the app
$clientID = "5d790577-015d-4d1d-9af8-b0818907b03a"
$AppIdentifier = $clientID + "@" + $authRealm
$appPrincipal = Get-SPAppPrincipal -Site $newSite.RootWeb -NameIdentifier $AppIdentifier
write-host $appPrincipal.DisplayName
write-host $appPrincipal.NameIdentifier
Set-SPAppPrincipalPermission -Site $newSite.RootWeb -AppPrincipal $appPrincipal -Scope SiteCollection -Right FullControl
The scope can be Site or SiteCollection or SiteSubscription
Here is a good article with how to use PowerShell to register, install, and provide trust to the App
Since Microsoft has been pushing to move away from the farm solution and suggesting App Model, a lot of techniques (such as feature event receiver) that we used to depend on cannot be used anymore. It is a big change for On-premise SharePoint development.
Here is an approach that I think will work for the App model to provision a site if the requirements are not crazy in customizing OOTB SharePoint behaviour.
The solution will include
- A provisioning App that has AppInstalled event that handles the provision tasks such as branding, create/break permissions, create list/library ...etc (you can refer to another of my post about the branding such as master page and theme)
- Powershell script that creates the site collection and installs the provisioning App
Below is the sample script that creates host-named site collection and installs App
$newSite = New-SPSite "http://test.com" -HostHeaderWebApplication "http://localhost" -Name "Community" -Description "It's a community" -OwnerAlias 'domain\account' -language 1033 -Template "COMMUNITY#0"
$myapp = Import-SPAppPackage -Path "D:\SiteProvisioning.app" -Site $newSite -Source ([microsoft.sharepoint.administration.spappsource]::CorporateCatalog) -confirm:$false
Install-SPApp -Web $newSite.RootWeb -Identity $myapp
if there is something needs to be updated through the App (i.e. upload updated master page), you can use the following sample script
$site = Get-SPSite "http://test.com"
$myapp = Import-SPAppPackage -Path "D:\SiteProvisioning.app" -Site $site -Source ([microsoft.sharepoint.administration.spappsource]::CorporateCatalog) -confirm:$false
$appInstance = Get-SPAppInstance -Web $site.RootWeb | where-object {$_.Title -eq "SiteProvisioning"};
$app = Update-SPAppInstance -Identity $appInstance -App $myapp -Confirm:$false
*** Update ***
Unfortunately, the PowerShell script above can't trust your App for you. So in order for your App to work, you'll have to at least manually install/trust you app to one of the site collection within the Tenant (Web application). This way your app will have the Tenant Full Control and the powershell will work for the future site collection creation. You'll get the access denied error like below if your App is not trusted.
Access denied. You do not have permission to perform this action or access this resource.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.Exception Details: Microsoft.SharePoint.Client.ServerUnauthorizedAccessException: Access denied. You do not have permission to perform this action or access this resource.
** Update November 6***
You can actually use the following powershell script to grant permission to the app
$clientID = "5d790577-015d-4d1d-9af8-b0818907b03a"
$AppIdentifier = $clientID + "@" + $authRealm
$appPrincipal = Get-SPAppPrincipal -Site $newSite.RootWeb -NameIdentifier $AppIdentifier
write-host $appPrincipal.DisplayName
write-host $appPrincipal.NameIdentifier
Set-SPAppPrincipalPermission -Site $newSite.RootWeb -AppPrincipal $appPrincipal -Scope SiteCollection -Right FullControl
The scope can be Site or SiteCollection or SiteSubscription
Here is a good article with how to use PowerShell to register, install, and provide trust to the App
Comments