Use case: List Posts – Using Widget Wrangler and AngularJS in the web part development

In this post, I will show you how you can create a widget or web part that show you a list of posts from SharePoint blog site. The element is done purely as client side coding. One thing that is true with SharePoint is the fact that you can do the same things in multiple ways. Same goes here with this example, but my aim here is to demonstrate how you can create plugins, web parts, apps however you want to call them, easily and purely as client side development. I think that a word widget is most descriptive, and that is what we will be using here.

This example is based on real life solution that I made on my last project on top of SharePoint 2013 on-prem. The widget is also tested to be working in SharePoint Online. Technically you could use it any other web platform, and that is the key why I want to present you a framework called Widget Wrangler.

What is Widget Wrangler?

Why try to summarise something when it’s done perfectly in the actual source? “The Widget Wrangler is a lightweight framework for managing the loading of javascript “widgets” on a web page.”. With the framework, you can create isolated widgets and control the loading of each file and dependency you need for the element.

With Widget Wrangler (later ww) you can encapsulate the functionality of the widget so that different, or even multiple of the same kind, elements won’t be interference with the hosting page and other widgets. This way the isolation and creation of truly separated UI and functionality are easier to do. The framework also manages the efficient loading when multiple web parts on a page use the same javascript libraries or CSS files.

<div class="latestPostWP">
 <div posts-element></div>

 <script type="text/javascript" src="/ourfirm/offices/SiteAssets/js/pnp-ww.min.js" 
 ww-appname="LatestPostWPApp" 
 ww-apptype="Angular"
 ww-appcss='[{"src": "/ourfirm/offices/SiteAssets/webparts/LatestPost/latestPost.css", "priority":0}]'
 ww-appScripts='[{"src": "/ourfirm/offices/SiteAssets/js/angular.min.js", "priority":0}}
 ]'>
 </script>
</div> 

You can download Widget Wrangler and find more information from here:
https://github.com/Widget-Wrangler/ww

There’s also more deeply demonstration available in Channel9 PnP Web Cast:
PnP Web Cast – Introducing Widget Wrangler for SharePoint development

Post-Listing Widget

To demonstrate the use of ww, let’s create a simple widget that lists blog post from SharePoint blog site. Actually, I have built this type of functions multiple times before so this is a real world example. I will use my favored framework AngularJS and SharePoint REST API to accomplish the actual functionality. This way we can create a solid client side solution and have a flexible separation of functionality and presentation. And that should be the starting point for every customization IMO.

Requirements

  • Get blog post from SharePoint blog site.
  • Show three latest post and other through pagination.
  • From each post title (link to post) 365 first characters from the blog post.
  • Show to order an email alert for new posts.
  • Show link to RSS feed.

The whole solution can be found from my GitHub repository https://github.com/MikkoKoskinen/WW-Demo-ListPost

From there you can find four files:

  • WWPostsWPHTML.html – File containing the ww implementation that was saved on the script web part.
  • listPost.js – The angular application that implements the widget functionality.
  • listPost.html – The presentation layer of the widget.
  • listPost.css – Styling of the widget.

I’m also using following frameworks and extensions:

Widget Wrangler Section

<div class="latestPostWP">
 <div posts-element blogSiteURL='' listTitle='Posts' listID='74DF3BE3-5536-45B6-B171-B97C1BCD61D1'></div>

 <script type="text/javascript" src="/ourfirm/offices/SiteAssets/js/pnp-ww.min.js" 
 ww-appname="LatestPostWPApp" 
 ww-apptype="Angular"
 ww-appcss='[{"src": "/ourfirm/offices/SiteAssets/webparts/LatestPost/latestPost.css", "priority":0}]'
 ww-appScripts='[{"src": "/ourfirm/offices/SiteAssets/js/angular.min.js", "priority":0},
 {"src": "/ourfirm/offices/SiteAssets/js/truncate.js", "priority":1},
 {"src": "/ourfirm/offices/SiteAssets/js/dirPagination.js", "priority":1},
 {"src": "/ourfirm/offices/SiteAssets/webparts/LatestPost/latestPost.js", "priority":2}
 ]'>
 </script>
</div> 

Above you can see the WW section of the solution that has to be added to the page. This code will handle the loading of the widget. I’m a fan of script web part, so I have placed that code in the snippet section. You could, of course, use other methods of adding the code of course. As we can see, you can control very well on what you want to load and in which order. Key things in the code are.

  1. Everything has to be wrapped inside a div. Div with class ‘latestPostWP’ in our case.
    1. This is an important thing to remember because ww won’t work without it.
  2. Ww implementation is done inside the script tag that is calling the library on the source attribute. After that, you can give the necessary settings.
  3. ww-appname = The name of your widget application. In Angular implementation, this has to match with the module name.
  4. ww-apptype = Type of the framework used on the widget. On the time of writing this, only Angular is supported.
  5. ww-appcss = List of CSS style sheet you want to be loaded for the widget. You can give multiple files and control the loading order with the parameter.
  6. ww-appScripts = List of script files sh you want to be loaded for the widget. You can give multiple files and control the loading order with the parameter.

And that’s it. It’s just that simple.

Now, if look at the browser console after page load, you can see that ww has initialized a widget on the page. As you can see our widget has an index number 0. If there were multiple of these elements on the page, all of them would have them own number. This is the power of ww and encapsulating of the widgets.

Presentation

<div class="resultItem announcementItem" dir-paginate="post in posts | itemsPerPage: 2" pagination-id="posts"> 
 <div class="resultTitle"> 
 <a class="" href="{{viewItemURL}}{{post.ID}}">{{post.Title}}</a> 
 </div> 
 <div class="resultContent"> 
 <span class="resultDate" ng-bind="post.PublishedDate | date:'LLLL dd, yyyy'"></span> 
 <br>
 <div class="resultDetail">{{ post.Body | htmlToPlaintext | characters:350 :true}}</div> 
 <div class="resultMore"><a href="{{viewItemURL}}{{post.ID}}">More≫</a></div> 
 </div> 
</div>
<div class="blogActions">
 <div class="action">
 <a class="ms-calloutLink" target="_blank" href="{{listRSSURL}}">
 <span style="height:16px;width:16px;position:relative;display:inline-block;overflow:hidden;" class="s4-clust ms-blog-linkCommandImage">
 <img src="/ourfirm/offices/_catalogs/theme/Themed/4D8112E7/spcommon-B35BB0A9.themedpng?ctag=3" style="position:absolute;left:-236px !important;top:-66px !important;border-width:0px;"></span>&nbsp;<span class="ms-splinkbutton-text">RSS Feed</span></a>
 </div>
 <div class="action">
 <a class="ms-calloutLink" href="{{postAlertURL}}">
 <span style="height:16px;width:16px;position:relative;display:inline-block;overflow:hidden;" class="s4-clust ms-blog-linkCommandImage"><img src="/ourfirm/offices/_catalogs/theme/Themed/4D8112E7/spcommon-B35BB0A9.themedpng?ctag=3" style="position:absolute;left:-236px !important;top:-30px !important;border-width:0px;"></span>&nbsp;<span class="ms-splinkbutton-text">Alert Me</span>
 </a>
 </div>
 <div class="ms-clear"></div>
</div>
<dir-pagination-controls pagination-id="posts"></dir-pagination-controls>

Here you can see the presentation layer. Technically it’s just plain HTML with some Angular code. But I would like to highlight few relevant things, though.

I’m not using the default repeater to show a list of fetched post. The code is using pagination extension for that. This will provide us an easy way to divide the result to a different section. Pagination is done in the first div element “dir-paginate=”post in posts | itemsPerPage: 2″ pagination-id=”posts””. The first setting is the same than in default repeater telling to loop through all the post in posts variable. Next, we will give the amount of visible items per page. Finally, we give a unique id for the pagination element. This way we can connect the repeater, and the pagination action element added as the last element on the widget (dir-pagination-controls div). The extension is also handling all the necessary functions like showing the page count and back and forward links.

Next thing to notice here is that we are modifying the date format for better visibility with ng-bind element.

 ng-bind="post.PublishedDate | date:'LLLL dd, yyyy'"
{{ post.Body | htmlToPlaintext | characters:350 :true}}

Lastly, we are showing a short teaser from post body with element above. We can truncate the text with Angular Truncate filter and give the amount of character shown to the user. True settings tell that also complete words can be cut. htmlToPlaintext is our custom filter that takes out any HTML elements form the body text. More about this soon.

Functionality

(function() {
  angular
    .module('LatestPostWPApp', ['truncate','angularUtils.directives.dirPagination'])
    .filter('htmlToPlaintext', function () {
        return function(text) {
            return  text ? String(text).replace(/&amp;lt;[^&amp;gt;]+&amp;gt;/gm, '') : '';
        };
    })
    .directive('postsElement', function() {
        return {
            restrict : 'EA',
            transclude : false,
            templateUrl: '/ourfirm/offices/SiteAssets/webparts/LatestPost/latestPost.html',
            controller: function ($scope, $log, $q, $http, $attrs) {

                $scope.getEvents = function getEvents() {
                    return $http({
                        method : &amp;quot;GET&amp;quot;,
                        url: _spPageContextInfo.webAbsoluteUrl + &amp;quot;/&amp;quot; + $attrs.blogsiteurl + &amp;quot;/_api/web/lists/GetByTitle('&amp;quot; + $attrs.listtitle + &amp;quot;')/items?$orderby=PublishedDate desc&amp;quot;,
                        headers: { &amp;quot;Accept&amp;quot;: &amp;quot;application/json;odata=verbose&amp;quot; }
                    })
                    .then(function sendResponseData(response) {
                        // Success
                        return {
                            Items: response.data.d
                        }

                    }).catch(function(response) {
                        $log.error('HTTP request error: ' + response.status)
                        return $q.reject('Error: ' + response.status);
                    });
                };

                $scope.getEvents()
                .then(function(data) {
					//Get list items
					$scope.posts = data.Items.results;

					if ($scope.posts.length &amp;gt; 0) {
                        $scope.viewItemURL = _spPageContextInfo.webAbsoluteUrl + &amp;quot;/&amp;quot; + $attrs.blogsiteurl + &amp;quot;/Lists/&amp;quot; + $attrs.listtitle + &amp;quot;/Post.aspx?ID=&amp;quot;;
                        $scope.listRSSURL = _spPageContextInfo.webAbsoluteUrl + &amp;quot;/&amp;quot; + $attrs.blogsiteurl + &amp;quot;/_layouts/15/listfeed.aspx?List={&amp;quot; + $attrs.listid + &amp;quot;}&amp;quot;;
                        $scope.postAlertURL = _spPageContextInfo.webAbsoluteUrl + &amp;quot;/&amp;quot; + $attrs.blogsiteurl + &amp;quot;/_layouts/15/SubNew.aspx?List={&amp;quot; + $attrs.listid + &amp;quot;}&amp;amp;Source=&amp;quot; + _spPageContextInfo.serverRequestPath + &amp;quot;&amp;quot;;
                    }
					else {

					    $scope.noItemsFound = true;
					}
				});
            }
        };
    }); // End directive()
}()); // End IFFE

The functionality of the widget is done as an Angular application. On the first rows of the code, we are giving a name for the application and loading the necessary extension. First thing on the code is a custom filter called htmlToPlaintext. You may call this function with a parameter holding some text content. The function will strip out all HTML elements with a regular expression and return a pure text content. This is used in the presentation layer.

 .directive('postsElement', function() {
 return {
 restrict : 'EA',
 transclude : false,
 templateUrl: '/ourfirm/offices/SiteAssets/webparts/LatestPost/latestPost.html',
 controller: function ($scope, $log, $q, $http, $attrs) {

After this, we have created a directive element named ‘postsElement’ that is will be called on the script web part.

Important things for the directive are to give the right path to the template file and pass-through the variables with $attrs parameter. As we can see from the directive element, we are passing a couple of parameters to be used during the functionality.

  • blogSiteURL = If the widget is placed on another web than in blog site, you can give the URL with this parameter. URL is used during the REST call to get the post. URL should be given as relative against site collection root.
  • listTitle = Title of the list where posts are read. The title is used during the REST call to get the post.
  • listID = Id of the list where posts are saved. This is used in email alert and RSS functions.

In the first section of the code, we are creating a function called ‘getEvents’ that makes and REST API call against SharePoint and gets all the posts from a given list. The call is using the parameters mentioned above to do the call. If the call is successful, the found data items will be returned.

Next, the code will construct a deferred object from the function above. We are catching the promise and saving the found data items to the ‘posts’ variable. Also if some items were found, we would construct few parameters for view item, RSS and alert links. These parameters are used in the template during the construction of the widget.

<div class="resultMore"><a href="{{viewItemURL}}{{post.ID}}">More≫</a></div>

And that’s it. Here you have a relative simple POC of client-side widget that is reading information from SharePoint and using Widget Wrangler framework for better maintenance.

Your Day with Microsoft NextGen Portals

Microsoft Ignite 2015 last month was huge. Basically everything from Microsoft stack was presented there. For me all things related to modern workplaces, meaning Office 365 and SharePoint, was under the microscope. But I have to say that the information flow was a blast and it was almost impossible to digest all the new things and news that were presented.

We heard about Groups, Delve, Infopedia, SharePoint 2016, Yammer etc. Microsoft is building their cloud and portal solutions based on following strategy – Cloud first, mobile first. You definitely saw in Ignite.

After the conference many may wonder that how is this all wrapped around together and what tools I should use? I don’t have a clear answer to that. There’s always the one and only “It depends” factor. But now after a while of reading and thinking all the new, I decided to give it a try. On one point of view at least.

I made a presentation of one full day for typical information worker and how these new or currently existing tools can be used and how they may help users during the day. At the same time you can see the main published NextGen portal tools from Ignite.

One new cool tool available for both public Office 365 and for enterprise Office 365 is Sway. With Sway you can quickly create nice looking mobile ready presentation. That is why I used that also. Remember to add Sway to your tool box.

>> Your Day with Microsoft NextGen Portals

Display Template and Current Item Index

A little while ago we had request where we were spouse to build a content lift up that displays the latest news pages. Very common and nothing new. The solution should be done with SharePoint OOTB features (be Office 365 compatible), so I decided to use a search and search web parts like I have done a multiple times before. What customer wanted was something like in this wireframe.

(Again here’s the link to source code used in this example: GitHub Mikko Koskinen)

The news post should be listed from newest to oldest. The most recent one should have a title, some text and image when others should show only title and short text from the news body. Because I wanted to keep things light from performance point of view I wanted to accomplish this with one web part only. You could do this with two separated web part for sure.

But if we think of the concept of search web part and display templates we know that we have two elements in template; a control display templates and item display templates. This concept is explained nice in Paul Matthews display template series where the following image can be found. If the concept of display templates and using them is new to you please read Matthews posts first.

searchTempaltesControltem

Same item template is used to every single item that is returned to us from the index. If so how can we style the first item element differently than others?

After going through basically every single value from ctx.CurrentItem I finally found the answers. The detail I need is not in CurrentItme but in context it self. There is a value for current item id found and we can use that to solve our small problem.

Only thing we need to do is to check what is the idx value of the current item in display template and change the styling based on that.


var shortText = String.format('&lt;div class=&quot;ms-noWrap newsBody&quot; title=&quot;{0}&quot; id=&quot;{1}&quot; &gt;{2}...&lt;/div&gt;',
				$htmlEncode(line2.defaultValueRenderer(line2)), line2Id, line2.toString().substring(0,100));


var index = ctx.CurrentItemIdx;

if (index == 0){
_#--&gt;
	&lt;div class=&quot;mainNews&quot; id=&quot;_#= containerId =#_&quot; data-displaytemplate=&quot;_#= $htmlEncode(dataDisplayTemplateTitle) =#_&quot;&gt;
			&lt;div class=&quot;newsImage&quot; id=&quot;_#= pictureContainerId =#_&quot;&gt;
				&lt;!--#_
				if(!linkURL.isEmpty)
				{
				_#--&gt;
				&lt;a href=&quot;_#= linkURL =#_&quot; title=&quot;_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_&quot; id=&quot;_#= pictureLinkId =#_&quot;&gt;
				&lt;!--#_
				}
				_#--&gt;
					_#= pictureMarkup =#_
				&lt;!--#_
				if(!linkURL.isEmpty)
				{
				_#--&gt;
				&lt;/a&gt;
				&lt;!--#_
				}
				_#--&gt;
			&lt;/div&gt;
			&lt;div class=&quot;newsTitle&quot; id=&quot;_#= dataContainerId =#_&quot;&gt;
				&lt;!--#_
				if(!linkURL.isEmpty)
				{
				_#--&gt;
					&lt;a href=&quot;_#= linkURL =#_&quot; title=&quot;_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_&quot; id=&quot;_#= line1LinkId =#_&quot;&gt;
				&lt;!--#_
				}
				_#--&gt;
					&lt;h2 class=&quot;ms-noWrap&quot; id=&quot;_#= line1Id =#_&quot;&gt; _#= line1 =#_&lt;/h2&gt;
				&lt;!--#_
				if(!linkURL.isEmpty)
				{
				_#--&gt;
					&lt;/a&gt;
				&lt;!--#_
				}
				_#--&gt;
			
				&lt;div class=&quot;newsBody&quot; title=&quot;_#= $htmlEncode(line2.defaultValueRenderer(line2)) =#_&quot; id=&quot;_#= line2Id =#_&quot; &gt; _#= line2 =#_&lt;/div&gt;
			&lt;/div&gt;
		&lt;/div&gt;
&lt;!--#_	
}
else{
_#--&gt;
	&lt;div id=&quot;_#= containerId =#_&quot; data-displaytemplate=&quot;_#= $htmlEncode(dataDisplayTemplateTitle) =#_&quot;&gt;
			&lt;div class=&quot;newsTitle&quot; id=&quot;_#= dataContainerId =#_&quot;&gt;
				&lt;!--#_
				if(!linkURL.isEmpty)
				{
				_#--&gt;
					&lt;a href=&quot;_#= linkURL =#_&quot; title=&quot;_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_&quot; id=&quot;_#= line1LinkId =#_&quot;&gt;
				&lt;!--#_
				}
				_#--&gt;
					&lt;h2 class=&quot;ms-noWrap&quot; id=&quot;_#= line1Id =#_&quot;&gt; _#= line1 =#_&lt;/h2&gt;
				&lt;!--#_
				if(!linkURL.isEmpty)
				{
				_#--&gt;
					&lt;/a&gt;
				&lt;!--#_
				}
				_#--&gt;
			
				_#= shortText =#_
			&lt;/div&gt;
		&lt;/div&gt;
&lt;!--#_	
}
_#--&gt;

After this we can have nice one web part solution with OOTB tools to our problem. You can find the full source from my GitHub (link at the beginning the post).

Change the display value of list column

Every now and then my customers are asking me to hide some list column from different views. Because every time I have to think that what is the best way to fulfill this requirement I decided to write this post that basically tells the different options. There are ways x to hide the column in different list views. And by views here I mean DisplayForm, EditForm and NewForm.

  • With list level setting
  • With JavaScript or actually JQuery here

As you can see I left out the options for doing this with server side code or declaratively during the wsp installation for example. These solution can be used to make the change in existing environment and especially these are working in Office 365. Actually the examples have been developed in my Office 365 test tenant. For these examples I created an OOTB announcement list and added one new column called “Hide Me”.

Change the list level setting

This shouldn’t be a new thing to you but just for reference. You can change the list column visibility from list settings. But this setting will change the visibility in all forms. There is no form level setting available through UI.

  1. Go to list setting from the ribbon
  2. Activate the content type management if necessary
  3. Open the content type that holds the field
  4. Click the field you would like to hide
  5. Select Hidden from column settings

Here’s a video that shows you the steps if needed.

Hide the column with JavaScript

This method is for maybe more advantage users because you need to insert some script to the pages. With this method you can hide the column form any list form separately.

  1. You can find the list form edition option from the ribbon. Open one you want to edit. I use display form here because that’s the most common form one have to edit.

  2. This will open the form (or actually a page). The form is opened in edit mode.
  3. Add a Script Editor web part to main zone.

  4. Click the Edit Snipped link and add the code below to editor.
  5. Remember to change the “Hide Me” text to match your field title.
  6. Click Stop Editing to save the changes.
  7. Your field should now been hidden in display view.

I decided to use JQuery in my script because this way it’s more flexible to search the right HTML element from the page. The code below includes a link to JQuery but you can leave it away if that is already loaded on your environment.

In the page the list columns are actually shown in table format. What we will do here is that we will find the title of our field that we want to hide. Then we will get the closest row and hide it. This will hide both the title and value columns. To get field back simply delete the script editor web part from the form. There is one small draw back when you use this method. For a blink of an eye it’s possible that users are actually seeing the field when they load the form. This is because the scripts in editor web part are run only after the form has been fully loaded.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js" />
<script type="text/javascript" language="javascript">
$(document).ready(function() { $('h3:contains("Hide Me")').closest('tr').hide(); });
</script>

Using PowerShell

Because of the delay there I decided to seek still one option. If you know there is actually SetShowIn setting for field. This setting is available only through object model or you can set it declaratively in field xml settings. Because we already had the environment running and we are using Office 365 those options wasn’t available to us. For me PowerShell is the tool make this kind of coding necessary operations.

You can actually use SharePoint client side code with power shell also. I won’t go through the requirements and basics of that because a link original source for how to do it is a lot easier. Thanks for Chirs O’Brien for posting this tip http://www.sharepointnutsandbolts.com/2013/12/Using-CSOM-in-PowerShell-scripts-with-Office365.html

  1. Make sure you have the SharePoint client dll available on the machine you are running the PowerShell script.
    1. If you don’t have SharePoint server available from where you can get them, you have to download and install SharePoint Server 2013 Client Components SDK.
    2. http://www.microsoft.com/en-us/download/details.aspx?id=35585
    3. The path in my script is showing the place where you can find these dll:s in SharePoint server or after you have installed the SDK
  2. Change the path of the dll files to the script if needed.

  3. You can run this code from basic Windows PowerShell command prompt. You should run the command prompt as administrator.
  4. Navigate in the folder where the script is and run it with the following parameter.
  5. .\ChangeColumnFormVisibility.ps1 -Url “https://tenant.sharepoint.com/sites/spdevsamples/&#8221; -ListName “Events” -FieldName “Hide Me” -ListView “DisplayForm” -ShowInForm:$False
    1. Url = Url of the site where the list is
    2. ListName = Title of your list
    3. FieldName = Title or internal name of your field
    4. ListView = form which view you want to edit. This value has to be DisplayForm or NewForm or EditForm
    5. ShowInForm = Boolean ($true or $false) value that tells should the field be hidden or shown
  6. The script will prompt and ask you for credential during the run.
  7. The details of the changes are shown after the changes are done.

After the script is run you can go and see the changes in your list view.

 

 

 

 

 

 

 

The code is actually quite simple. First we connect to the site. After that we have to get the right list and it’s fields. We have to load the field collection before we can make the necessary changes. After that we can get the right field based the given name. Then we have to check what form value user wants to change and make the right changes and update the field settings.

	# connect/authenticate to SharePoint Online and get ClientContext object..
	$credential = Get-Credential
	$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
	$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($credential.UserName, $credential.Password)
	$clientContext.Credentials = $credentials

	if (!$clientContext.ServerObjectIsNull.Value)
	{
		#This gets Microsoft.SharePoint.Client.List
		$oList = $clientContext.Web.Lists.GetByTitle($ListName);
		#This gets Microsoft.SharePoint.Client.FieldCollection
		$fieldColl = $oList.Fields;

		$clientContext.Load($fieldColl);
		$clientContext.ExecuteQuery();

		$field = $fieldColl.GetByInternalNameOrTitle($FieldName);

		$clientContext.Load($field);
		$clientContext.ExecuteQuery();

		switch ($listView) {
			"DisplayForm"
			{
				$field.SetShowInDisplayForm($ShowInForm);
				$clientContext.ExecuteQuery();

				$message = "Fields '" + $field.Title + "' DisplayForm visibility changed to: " + $ShowInForm
				write-Host $message -ForegroundColor Green
				break
			}
			"NewForm"
			{
				$field.SetShowInNewForm($ShowInForm);
				$clientContext.ExecuteQuery();

				$message = "Fields '" + $field.Title + "' NewForm visibility changed to: " + $ShowInForm
				write-Host $message -ForegroundColor Green
				break
			}
			"EditForm"
			{
				$field.SetShowInEditForm($ShowInForm);
				$clientContext.ExecuteQuery();

				$message = "Fields '" + $field.Title + "' EditForm visibility changed to: " + $ShowInForm
				write-Host $message -ForegroundColor Green
				break
			}
		}
	}

	

You can find the whole script from my GitHub:

GitHub Mikko Koskinen

New-SPConfigurationDatabase – system error 5 (Access is denied.)

This not something very fancy and the solution is actually very clear and something I should have understood right from the error message. But because it took me a while to figure it out and googling with error message didn’t give that much help, maybe this helps someone else also.

I was installing SharePoint 2010 in very typical three tiers environment. SQL Server was installed as it should be based on best practice recommendations. This means that log and data files were also separated to different drivers. SharePoint was also meant to be installed based on least privilege practices. I was using power shell script to make the SharePoint installation but the same error is given to you with wizard also.

So on the stage where Configuration database is created I get the following error
message:

New-SPConfigurationDatabase : CREATE FILE encountered operating system error 5(Access is denied.) while attempting to open or create the physical file ‘R:\Log\Config_log.ldf’. CREATE DATABASE failed. Some file names listed could not be created. Check related errors.

And now what?

I know that my setup account has all the necessary privileges to SQL Server. First I thought that my setup account should have access privileges to Log folder (where all the database log files are created) and I tried that with no help. After some googling, wondering and discussion with my colleague I figured it out.

The SQL server instance is driven with service account. Even though I’m using a setup account to operate in SQL server the actual creation of database is done with service account. I checked the SQL Server Services log on account with Sql Server Configuration Manager and gave this account read/write access to Log –folder.


And that solved the problem and the installation process was over quite quickly.

%d bloggers like this: