Article Published DIWUG Magazine 14 – Management of Host Named Site Collections

A while ago I wrote an article about the management of host named site collections in SharePoint 2013. The magazine it was written for was released today.

If you want to read the article you can download it here, you can find my article on page 35:

Management of Host Named Site Collections

The PDF is the complete DIWUG magazine that you can also download from the DIWUG website. The complete magazine contains the following articles:

    • Exploring the changes to how Office 365 uses SharePoint to manage documents in Dynamics CRM – Peter Baddeley
    • SharePoint 2013 Search Find Content – Ronald Laan
    • In a nutshell: Identity delegation leveraging the Claims to Windows Token Service – Spencer Harbar
    • 10 tips to drive user adoption – Jasper Oosterveld
    • Management of host-named site collections – Maik van der Gaag
    • Are “Out of the Box” SharePoint solutions right for you? – Neil Richards
    • SharePoint Lists in Access Apps – Christiaan Blaauw

Let me know what you think about the article!!

logo

Share Button

Adjust the ReleaseTfvcTemplate.12.xaml build template to work with the BizTalk Deployment Framework

If you want to use the BizTalk Deployment framework in combination with Release Management you need to adjust the default build template that comes with Release Management.

If you did not find it already you can find the default build template in the installation folder of release management.

C:\Program Files (x86)\Microsoft Visual Studio 12.0\Release Management\Client\bin\ReleaseTfvcTemplate.12.xaml

Copy this template to TFS and open it to make a small adjustment. In the workflow explorer Navigate to the following sequence component:

“Overall Build Process” – “Run on Agent” – “Try” – “Compile, Test and Publish”.

Whit this component selected, select “Variable” in the lower left corner.

image

In the popup window create a new “Variable” by clicking “Create Variable” and call it “BinariesDirectory” and make it of the type “String”.

image

This variable will be used to save the directory in which the Deployment Framework components can be found.

Next step is to add a “GetEnviromentVariable<T>” action just above the “Run MSBuild” action. Select the type “String” and call the action “Get Binaries Directory”.

To get the Binaries Directory we want to make use of a WellKnownEnvironmentVariable (MSDN). To use such a variable you need to import a assembly reference. You can add a assembly reference by clicking on “Import” next to “Arguments” in the footer of the workflow screen.

image

Import the “Microsoft.TeamFoundation.Build.Activities.Extensions” namespace to make use of the WellKnownEnvironmentVariables. Know you can set the properties of the “Get Binaries Directory” action to get the “WellKnownEnvironmentVariables.BinariesDirectory” environment variable.

image

With this value we can change the MSBuild argument to build the MSI from the BizTalk Deployment Framework. Select the “Run MSBuild” action and adjust the “CommandLineArguments” property to the following value.

String.Format("/p:SkipInvalidConfigurations=true;TeamBuildOutDir=""{0}"" {1}", BinariesDirectory, AdvancedBuildSettings.GetValue(Of String)("MSBuildArguments", String.Empty))

Save and Check In the build template. If you use this build template to define a build definition you are able to use a Release within Release Management that uses the output of this build.

One thing to keep in mind that you will have to set the following properties on your build definition:

  • MSBuild platform: X86
  • Output location: AsConfigured

image

Share Button

Customize the Release Management Build template – Part 1

To setup a build in combination with Release Management you need the Release Management build template. This template looks like the default build template but has an additional sequence action to start the release after the build is succeeded. The Release Management Build template can be found within the install location of release management.

C:\Program Files (x86)\Microsoft Visual Studio 12.0\Release Management\Client\bin\ReleaseTfvcTemplate.12.xaml

We will use this template and rename it to “BuildTemplate-Release-General.xaml”. As location for the build template we will use TFS project called: “Build Templates”. By using a central location we make sure we will not have duplicate build templates within our Team Foundation Server environment.

For different types of builds you would like to add files to your drop location that you save within a solution folder for this we will have to make a small adjustment to our build template. To make this adjustment open the Build template and navigate to the sequence activity that contains the “msbuild” action.

You can find the “msbuild” activity by following the following path:

“Overall Build Process” – “Run on Agent” – “Try” – “Compile, Test and Publish”.

In the sequence activity that contains the “msbuild”  action we will add two argument by selecting “Compile, Test and Publish” and then Arguments in to lower left corner. If you scroll down the list click on “Create Argument” to add a new argument.

image

Add the following arguments:

  • CopySolutionFolder: Will be used to save the location of the Solution folder relative to the Team Foundation server.
  • DropLocation: Will be used to save the drop location of the build.
  • CustomBuildDirectory: Will be used to save the location of the Solution folder on the build server.

image

Know that we have created the argument we can add actions to set the values of the arguments. Drag a “GetEnvironmentVariable<T>” action to the top of the “Compile, Test and Publish” sequence and call it “Get Drop Location Folder” and set the properties as you can see in the image.

image

The “WellKnownEnvironmentVariables.DropLocation” is the environment variable we need in order to get the drop location of the build. In the result property define the argument (“DropLocation”) in which you want to save the value.

Place an “If” control flow underneath the “GetEnvironmentVariable” action to check whether the value of the argument “CopySolutionFolder” is not null or empty. This because we will define this argument within the build definition interface. You can add an argument to the build definition interface by updating the Metadata Argument. Select this argument and edit it by selecting the three dots within the default value column.

image

Scroll down the list of parameters and check whether the argument you created is in the list. If this argument is not already in the list add it.

 

image

In the If control flow we check if the value of the “CopySolutionFolder” argument is not null or empty by defining the following condition:

String.IsNullOrEmpty(CopySolutionFolder)

If the argument is null or empty we will not take any action and if it contains a value we will try to get the local path of the solution folder in order to copy the contents to the drop location. To achieve this we need to add a sequence action to the else branch.

image

To retrieve the local path of the solution folder we place the “GetLocalPath” activity in the sequence. This action will allow us to add a TFS project relative path in the build definition. For example the value could be: “$/SharePoint Portal/MSFTPlayground.SharePoint.Farm/Deployment Configuration”. The result of the “GetLocalPath” action will be saved in the CustomBuildDirectory argument.

image

To finalize the build definition we add the “CopyDirectory” activity to the sequence. The source of the activity will be the solution folder (“CustomBuildDirectory”) and the destination will be the drop location (“DropLocation”).

image

Save the build template and check the file in into TFS. With the file in TFS you are able to use this template within a build definition. This template can be used by selecting show details in the process tab of a build definition and then selecting “New” to browse to the location were you have saved the build template within TFS.

image

Underneath the template selection you can see the parameters of the build template.

image

The categories 1,2,3,4,5 are the default categories. The Release category is the category that can be used to define the parameters regarding “Release Management”. The “Extra Files” category this is the category for our added argument.

In the next couple of post we will see how this build template will be used to start off a “Release” within “Release Management” order to start a SharePoint deployment.

Share Button

Deploy SharePoint Solutions with Release Management

In one of my previous post (Configuring Web Site Binding with Release Management) I showed how you can make a custom action for Release Management to configure web bindings.

As described in that post Release Management is a tool that provides a continuous deployment solution that makes release cycles repeatable, visible, and more efficient by automating deployments through every environment from test to production.

When you want to make use of Release Management in a scenario were you will deploy your SharePoint solutions within your DTAP environment you have to make some custom actions / components in order to facilitate this functionality.

In a upcoming series of posts I will work you trough the process of making and adjusting the TFS Build template in order to build your SharePoint solutions and how to make a custom PowerShell component for Release Management to deploy your SharePoint solutions.

  1. Part 1 – Customize the Release Management Build template.
  2. Part 2 – Create a custom component to deploy the SharePoint Solutions.
  3. Part 3 – Creating the Release Template that runs after the Build.

In this series of posts I assume that you have setup your build server in order to build SharePoint solutions. If not read this article on MSDN:

The individual parts will be written down in the upcoming weeks. I will try to write a Part a week but I also have to attend to the TechEd in Barcelona so I don’t know If I will be able to write down a post in that week.

Share Button

Offline Installation SharePoint 2013

In many situation you would like to do a offline installation of SharePoint 2013 or you are required to do a offline installation because you do not have a network connection on the server.

The prerequisites installer of SharePoint 2013 downloads the requirements directly of the internet. So we will have to make sure this will not be done.

But first off all we will have to install several Windows Server features. You can install these features by using the following PowerShell command:

Import-Module ServerManager
Add-WindowsFeature Net-Framework-Features,Web-Server,Web-WebServer,Web-Common-Http,Web-Static-Content,Web-Default-Doc,Web-Dir-Browsing,Web-Http-Errors,Web-App-Dev,Web-Asp-Net,Web-Net-Ext,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Health,Web-Http-Logging,Web-Log-Libraries,Web-Request-Monitor,Web-Http-Tracing,Web-Security,Web-Basic-Auth,Web-Windows-Auth,Web-Filtering,Web-Digest-Auth,Web-Performance,Web-Stat-Compression,Web-Dyn-Compression,Web-Mgmt-Tools,Web-Mgmt-Console,Web-Mgmt-Compat,Web-Metabase,Application-Server,AS-Web-Support,AS-TCP-Port-Sharing,AS-WAS-Support, AS-HTTP-Activation,AS-TCP-Activation,AS-Named-Pipes,AS-Net-Framework,WAS,WAS-Process-Model,WAS-NET-Environment,WAS-Config-APIs,Web-Lgcy-Scripting,Web-AppInit,Windows-Identity-Foundation,Server-Media-Foundation,Xps-Viewer 

Note:In this PowerShell command I also included: “Web-AppInit” . This is the Application Initialization feature (This is not a prerequisites) but can come very handy for warming up your web applications (IIS 8.0 Application Initialization reduces response time for SharePoint 2013).

When this is done we can make use of the prerequisites installer that is included on the SharePoint 2013 installation drive. By supplying the executable with certain arguments it will look for the installation files on the locale drive.

Argument Installation
SQLNCli Microsoft SQL Server 2008 R2 SP1 Native Client
IDFX11 Microsoft Identity Extensions
IDFX Windows Identity Foundation (KB974405)
Sync Microsoft Sync Framework Runtime v1.0 SP1 (x64)
AppFabric Windows Server AppFabric
KB2671763 Cumulative Update Package 1 for Microsoft AppFabric 1.1 for Windows Server (KB2671763)
MSIPCClient Microsoft Information Protection and Control Client
WCFDataServices Microsoft WCF Data Services 5.0
WCFDataServices56 (Added in the SP1 installation) Microsoft WCF Data Services 5.6

When you have downloaded the prerequisites by using the below links:

Share Button

Configuring Web Site Binding with Release Management

Release Management provides a continuous deployment solution that makes release cycles repeatable, visible, and more efficient by automating deployments through every environment from test to production.

Within Release Management you have al large set of default Actions and Components to configure a release cycle. On MSDN you can find a list with some common actions that are available within Release Management:

In this list you will find a action for creating a web site “Create Web Site”  and configure a web site “Configure Web Site”. By using the create web site action you will create a web site with default bindings and you would expect to be able to change the bindings by using the “Configure Web Site” action but this is not the case. If you would like to configure the binding on the web site you will have to create a custom action.

You can create a custom action by navigating to the “Inventory” tab and in the action window selecting new.

image

Selecting new will open up a new window in which you are able to configure a new action. In this new action we will start PowerShell and make use of the “WebAdministration” module to add a new binding.

image

As you can see in the image above everything in the “General Information” section speaks for it self. In the example we choose to add the action to the already existing category “IIS” because it is a “IIS” action.

In the “Execution” section specify what the action should execute. In the “Command” field specify the command for execution. For PowerShell specify “powershell” and in the “Arguments” field specify the argument for the command:

-Command "& { Import-Module WebAdministration; New-WebBinding -Name '__SiteName__' -IPAddress '__IPAddress__' -Port '__Port__' -HostHeader '__HostHeader__' -Protocol '__Protocol__'}" 

As you can see in the code we Import the “WebAdministration” module and use the “New-WebBinding” function for adding a new binding with the following parameters:

Parameter Value
Name __SiteName__
Protocol __Protocol__
IPAdress __IPAdress__
Port __Port__
Hostheader __HostHeader__

By using the format __[Name]__ (before and after 2 underscores) Release Management knows that these values can be used as parameters in order to make the action reusable.

When you save this action it will become available to add in your release template.

image

You can drag and drop the action within your release flow and configure it by double clicking the action.

image

When you add a new Binding you will probably also want to be able to remove a binding. You can do this by creating a new action and adding the following argument.

-Command "& { Import-Module WebAdministration; Remove-WebBinding -Name '__SiteName__' -IPAddress '__IPAddress__' -Port '__Port__' -HostHeader '__HostHeader__'}"

Note:When using the create web site action it will create a web site with the default binding. If you add a new binding to the web site you will also have to remove the default binding or else it could be in conflict with other web sites.

Share Button

Custom list view by using the “JS Link” property.

Customizing a list view could be done by using XSLT in previous version of SharePoint. In SharePoint 2013 this van be done by using the “JS Link” functionality. The “JS Link” functionality is included in list view web parts of SharePoint.

You can use this property for adding specific JavaScript files. You can add 1 or multiple when you want to add multiple you will have to separate them using the “|”  symbol. On the internet you can find a lot of articles on how to use the “JS Link” functionality. Normally the “JS Links”  functionality is used to adjust the rendering of a specific field type in my scenario I had to change the complete list view.

In this article I will show you how to define a custom list view using the “JS Link” functionality according to a specific scenario: On project sites we want to follow the status of site migrations (for example SharePoint sites). The status of these migrations can be saved within SharePoint lists:

clip_image002

In this list you will need to have two fields:

  • Title: The title of the site that needs to be migrated.
  • Status: The status of the migration. In this example we will have three statuses: “Not started”, “In progress” en “Done”.

Using this list we can manage the status of the migrations. At this moment we only have to add functionality to see the migration status of all sites in one view without the use of a farm solution.

clip_image004

In the above image you can see the same list but a altered view with the use of “JS LInk”. This view shows a doughnut view with three different colours. So how can we achieve this without creating a full trust solution.

First off all we searched for a JavaScript library to be able to create a doughnut chart. We choose the following library:

Now that we have a library we can start writing a JavaScript file that we need to load within the “JS Link” property. Within the JavaScript file we first off all register a namespace to not get in the way of other JavaScript code besides that we also define a view variables that we can  use within the namespace.

var migrationStatus = migrationStatus || {};

migrationStatus.InProgressString = 'In progress';
migrationStatus.DoneString = 'Done';
migrationStatus.NotStartedString = 'Not started'; 
migrationStatus.ListName = 'Migration';
migrationStatus.ItemsDone = 0;
migrationStatus.ItemsInProgress = 0;
migrationStatus.ItemsNotStarted = 0;

To be able to define template you will need to define specific overrides. These overrides can be defined by using the “RegisterTemplateOverrides” method on the “SPClientTemplates.TemplateManager” object. This method needs one object that defines what needs to be overridden. We will define this within the method: “CustomizeViewRendering”.

// Create a function for customizing the view rendering of the list
migrationStatus.CustomizeViewRendering = function () {
    var migrationStatusContext = {};
    migrationStatusContext.Templates = {};
    migrationStatusContext.Templates.View = migrationStatus.RenderMigrationViewBodyTemplate;
    migrationStatusContext.OnPostRender = migrationStatus.OnMigrationViewPostRender;
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(migrationStatusContext);
};

In the “migrationStatusContext” object needs to be defined which rendering methods needs to be overridden. As you can see in the above snippet the “OnPostRender” and the “Templates.View” will be overridden. These methods we will discuss in the upcoming paragraphs.

Note:When you override the rendering methods, this will be for every list view on a page. If you want to override the view rendering of one specific list you will have to build in a check if you are performing the action on the correct list.

migrationStatus.RenderMigrationViewBodyTemplate = function (ctx) {
    if (ctx.Templates.Body == '') {
        return RenderViewTemplate(ctx);
    }

    if (ctx.ListTitle == migrationStatus.ListName) {
        var listData = ctx.ListData;

        for (var idx in listData.Row) {
            var listItem = listData.Row[idx];

            if (listItem.Status == migrationStatus.InProgressString) {
                migrationStatus.ItemsInProgress++;
            } else if (listItem.Status == migrationStatus.NotStartedString) {
                migrationStatus.ItemsNotStarted++;
            } else if (listItem.Status == migrationStatus.DoneString) {
                migrationStatus.ItemsDone++;
            }
        }

        var htmlOutput = [];
        htmlOutput.push('<div id="listData"><a href="' + ctx.listUrlDir + '"> View this list</a></div>');
        htmlOutput.push('<div id="migrationstatusView" style="height:400px;width:400px;margin-top:10px;float:left;margin-bottom:10px;display:block;">');
        htmlOutput.push('<canvas id="myChart" width="250" height="250"></canvas>');
        htmlOutput.push('<div id="chartLegend" style="width:150px;float:right;" />');
        htmlOutput.push('</div>');
        

        var retVal = htmlOutput.join('');
        return retVal;
    }
    else {
        return RenderViewTemplate(ctx);
    }
}

The “migrationStatus.RenderMigrationViewBodyTemplate” function needs to be used to adjust the view. This method also receives the context (ctx) object in which all information regarding the context (in this example list) is saved. From this context we can retrieve all of the list data.

But first we will have to check if the body of the template isn’t empty. When it is empty we will have to call the default renderer. After that we can check if the list we are performing the actions for is our migration list: “ctx.ListTitle == migrationStatus.ListName” if this isn’t the case we also call the default rendering function:

return RenderViewTemplate(ctx);

When this list is our list we count all of the statuses and place them in the specific variables. When all this is done we write out the HTML we need for the rendering of the graph and legend and we return this.

De “PostRender” function will be called as last. In this function the graph will be loaded with the correct data and besides that we will also load the legend of the graph.

migrationStatus.OnMigrationViewPostRender = function (ctx) {
    if (ctx.ListTitle == migrationStatus.ListName) {

        var pieData = [
        {
            value: migrationStatus.ItemsNotStarted,
            color: "#F7464A",
            highlight: "#FF5A5E",
            label: migrationStatus.NotStartedString
        },
        {
            value: migrationStatus.ItemsDone,
            color: "#46BFBD",
            highlight: "#5AD3D1",
            label: migrationStatus.DoneString
        },
        {
            value: migrationStatus.ItemsInProgress,
            color: "#FDB45C",
            highlight: "#FFC870",
            label: migrationStatus.InProgressString
        }];
        
        var options = {
            //Boolean - Whether we animate the rotation of the Doughnut
            animateRotate: true,
            //String - A legend template
            legendTemplate: '<ul style="list-style-type:none;" class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="width:20px;height:10px;display:block;background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'
        };

        //get the chart element and setup the doughnut chart
        var ctxChart = document.getElementById("myChart").getContext("2d");
        var myPie = new Chart(ctxChart).Doughnut(pieData, options);

        //generate the legend html
        var legend = document.getElementById("chartLegend");
        legend.innerHTML = myPie.generateLegend();
    }
};

In the “PostRender” function we also need to check if we are performing the action for the correct list.

The final thing we need to adjust to the JavaScript file is adding the following line:

migrationStatus.CustomizeViewRendering();

This line of code will be called on the moment the file is loaded and by calling this function is will make sure that the overrides for the list views will be registered.

Know that the files are ready we only need to specify the files in the “JS Link” property of the list view.

clip_image006

In the “JS Link” we have specified the following value:

/siteassets/Migration/Chart.js|/siteassets/Migration/MigrationStatus.js
  • /siteassets/Migration/Chart.js: JavaScript library for the generation of graphs.
  • /siteassets/Migration/MigrationStatus.js: JavaScript file for the list view.
Share Button

User automatically removed from SharePoint Group

During my current project we received an access request from a user. We did what we normally do, we checked the request and added the user in the appropriate SharePoint Group and notified the user.

After 15 minutes the user told us that it wasn’t working. We looked at the User Group and found out that the user was not in the group. So we added the user again because we thought that we forgot this step. After some time we received another mail from the user telling us that it still wasn’t working.

We requested the account details from the user and tried it our self, we found out that the user was missing again and added the account again. We logged in with the user opened a document with Office Web Applications and took another look at the members of the specific SharePoint group. WTF the user was gone!

After digging into the ULS files and looking in the Event log we did not found a clue of what was happening. After a small conversation with the user she told us that everything worked fine before and that she had several problems since see re-joined the company.

What happened was the following the user was removed from the active directory and when she got back a new account was created with the same login name.

When the user re-joined the account had the same login name but did not have the same SID. SharePoint saves information about an account by using the login name and the SID (Security Identifier) of a user. Because of the mismatch SharePoint was removing the applied security rights.

This issue can be fixed by using different commands:

The commands look as followed:

$user = Get-SPUser -Web [SiteUrl] -Identity [Login Name]
Move-SPUser -Identity $user -NewAlias [Login Name] -IgnoreSID

For the PowerShell commando you will first need to retrieve the specific user.When retrieving the user and setting the new alias you should always use the claim login name: “i:0#.w|Domain\user”.

stsadm -o migrateuser -oldlogin [Login Name] -newlogin [Login Name] -ignoresidhistory

The STSADM command looks almost the same as the PowerShell command if you also look at the parameters they both have something to Ignore the SID history. The parameter is included because if you do not include the parameter it will check the SID references and as we all know they do not match.

Possible Problem: When performing one of these options you can receive a “Object reference not set to an instance of an object”. The solution to this problem is pretty simple, When it happens your user does not have enough rights. Try it with another account or give your current user rights to the User Profile Service Application.”

Share Button

Warm Up Form Based Web Application

Normal warm up scripts for SharePoint open a site object or web object and make a request to that specific site. When you use form based authentication and do not allow anonymous access, you would only warm up the login page.

In order to warm up a application form based SharePoint site you would have to apply your credentials. All off this can be done by using PowerShell and specific COM objects. This script can then be scheduled with “Task Scheduler” that is included in windows.

function Warm-FBASite{
    [CmdletBinding()]
    param (
        [string] $RootUrl = $(Read-Host -prompt "Root Url"),
        [string] $LoginUrl = $(Read-Host -prompt "Login Url"),
        [string] $SiteUrl = $(Read-Host -prompt "Site Url"),
        [string] $UserName = $(Read-Host -prompt "Username"),
        [string] $Password = $(Read-Host -prompt "Password"),
        [bool] $loggedIn = $(Read-Host -prompt "Already logged in")
    )
    $ieMain=New-Object -ComObject "InternetExplorer.Application";
    if($loggedIn -ne $true){
        Login-FBA -RootUrl $RootUrl -LoginUrl $LoginUrl -UserName $UserName -Password $Password -Browser $ieMain;
    }
    Navigate-Site -RootUrl $RootUrl -SiteUrl $SiteUrl;
    $ieMain.Quit();

}

The Warm-FBASite function is the main function that calls other functions. This function needs the following parameters:

  • RootUrl: The root URL of the application you would like to warm up.
  • LoginUrl: The relative URL to the login page.
  • SiteUrl: The relative URL to the site you would like to warm up.
  • UserName: The username off the forms user.
  • Password: The password off the forms user.
  • LogginIn: Boolean value whether the user has already been logged in.

In this function we open a Com object of internet explorer and provide it as a parameter to the function “Login-FBA”.

function Login-FBA{
    [CmdletBinding()]
    param (
        [string] $RootUrl = $(Read-Host -prompt "Root Url"),
        [string] $LoginUrl = $(Read-Host -prompt "Login Url"),
        [string] $UserName = $(Read-Host -prompt "Username"),
        [string] $Password = $(Read-Host -prompt "Password"),
        $Browser = $(Read-Host -prompt "Browser")
    )

    $url = $RootUrl + $LoginUrl;

    Write-Host "Trying to login the user:" $UserName " on the Url: " $url -ForegroundColor Green
    $Browser.navigate($url);
    $Browser.visible=$false;

    if ((Wait-Browser $Browser -Url $url ) -eq $false){
        Write-Host "Something went wrong with requesting the page";
        return
    }else{
        $doc=$Browser.Document
    }

    $txtUsername=$doc.getElementByID("ctl00_PlaceHolderMain_signInControl_UserName"); #Replace by your own ID
    $txtPassword=$doc.getElementByID("ctl00_PlaceHolderMain_signInControl_password"); #Replace by your own ID
    $btnSubmit=$doc.getElementByID("ctl00_PlaceHolderMain_signInControl_login"); #Replace by your own ID
    
    $txtUsername.value=$UserName;
    $txtPassword.value=$Password;
    $btnSubmit.click();
    if ((Wait-Browser $Browser -Url $url ) -eq $false){
        return;
    }
}

This function tries to open the login page in the com object you send in the parameters. When this page is loaded it inserts the username and password in the login controls by finding these controls by there id.

In this function you will have to insert your own Id’s of the username textbox, password textbox and submit button. In this function you also see a reference to the “Wait-Browser” function. This function is created to make sure the site you are requesting in the COM object is fully loaded.

function Wait-Browser{
    [CmdletBinding()]
    param (
            $Browser = $(Read-Host -prompt "Browser"),
            $Url = $(Read-Host -prompt "Url")
    )

    $maxRetries=50;
    $retry = 2;
    $retryCount = 0;

    while ($Browser.Busy -eq $true){  
        Write-Host "Waiting for browser: " $URl  -ForeGroundColor Yellow;
        
        if ($retryCount -gt $maxRetries){
            return $false;
        }
        
        $retryCount++;
        start-sleep $retry ;
    } 

    return $true;
}

When the login request succeeds it is time to open the site and let that document load within the COM object. When the site is loaded it will write the page title to the PowerShell window.

function Navigate-Site{
    [CmdletBinding()]
    param (
        [string] $RootUrl = $(Read-Host -prompt "Root Url"),
        [string] $SiteUrl = $(Read-Host -prompt "Site Url")
    )

    $url = $RootUrl + $SiteUrl;

    $iePage=New-Object -ComObject "InternetExplorer.Application";
    $iePage.navigate($url);
    $iePage.visible=$false;
    $retryCounter=0
    
     if ((Wait-Browser $iePage -Url $url ) -eq $false){
        Write-Host "Something went wrong with requesting the page" -ForegroundColor Red;
        return
    }else{
        $doc=$iePage.Document
        Write-Host "Site Loaded: " $doc.title -ForegroundColor Green;
    }

    $iePage.Quit();    
}

To make use of these functions you only have to add these functions in PowerShell and call the “Warm-FBASite” function just like below.

Warm-FBASite -RootUrl "https://sharepointsite.com"  -LoginUrl "/_layouts/15/login.aspx" -SiteUrl "/client/35" -UserName "[form account name]" -Password "[password]" -LoggedIn $false;
Share Button

Limitations of a Public Facing Website in Office 365

Update :Microsoft is stopping with public facing websites for new Office 365 clients, existing ones will have another 2 year support. http://www.zdnet.com/article/microsoft-confirms-it-is-dropping-public-website-feature-from-sharepoint-online/

When you buy an Office 365 tenant you get the option to build a Public website within the SharePoint administration panel.

Creating a website will give you the following URL by default:

  • http://[tenant]-public.sharepoint.com.

Within SharePoint 2013 they have extended the options to build massive websites where you had to do a lot of customizations in SharePoint 2010. There are already many site available for example (http://www.motion10.nl ) but most off these websites are build on SharePoint 2013 on premise. This is all because building a public website within Office 365 has a lot of limitations. In this blog post I will try to list the limitations I know. If you find any other limitations or they have changed something on the Office 365 platform to make it work and I haven’t alter the blog post please add a comment or send me a email.

Site Settings

Multiple site settings screens are missing from the administration menu. Some of these pages can be accessed by the Url and some of them don’t even exist.

Site Setting Public Website Office 365

  1. Manage Site Collection Features: The link and the page are missing for a public website.
  2. Manage Site Features: The link and the page are missing for a public website.
  3. Site Content Types: The link and the page are missing for a public website.
  4. Site Columns: The links is missing for a public website you can access the page by using the following URL: [URL]/_layouts/15/mngfield.aspx.
  5. Solution Gallery: The links is missing for a public website you can access the page by using the following URL: [URL]/_catalogs/solutions/Forms/AllItems.aspx.
  6. Web Part Gallery: The links is missing for a public website you can access the page by using the following URL: [URL]/_catalogs/wp/Forms/AllItems.aspx.
  7. List Template Gallery: The links is missing for a public website you can access the page by using the following URL: [URL]/_catalogs/lt/Forms/AllItems.aspx.
  8. Term store management: The link and the page are missing for a public website.

If you would like to activate or see which features are activated on the SharePoint Public site take a look at this blog post:

Variations

Many website on the internet are created in multiple languages. Looking at SharePoint you would then maybe would like to use Variations. In Office 365 variations cannot be used.

Managed Metadata

As you can see on point 8 within the site settings section you are not able to access the Term Store Management. This also makes it that one off the amazing new features off SharePoint 2013 taxonomy-based navigation cannot be used on a Office 365 public website.

Besides that more taxonomy based features do not work as for example the product catalog functionality.

Sub Sites

From the UI you cannot create a sub site.  You will have to use SharePoint Designer in order to create a sub site. But even then you are not able to use every site template. In my situation I tried to create a Publishing Site and it got immediately deleted from my tenant.

The only templates that can be used on the online version are:

  • Team Site
  • Basic Search Site
  • Content Search Web Part:One of the web parts you had to develop for previous version of SharePoint (At least I did) now came to SharePoint 2013 and that is the “Content Search Web Part”. This web part is not available on the public web site of Office 365.

Online you can find great tips to deal with the limitations of the Public website:

Share Button