Showing posts with label SharePoint 2013. Show all posts
Showing posts with label SharePoint 2013. Show all posts

Monday, November 20, 2017

Deploy JavaScript to a Site Collection or Web in Office 365 or On Premises + Dynamic Navigation Link

Scenario
  • You have some JavaScript you'd like to inject into a page and want the simplest method of deploying it to all pages within a Site Collection or Web.
Issue
  • You can do this via custom master pages, but then you break any future upgrades from Microsoft
  • You can also do this via a Sandbox code solution, SharePoint Framework, or a SharePoint Add-In, but these are all overly complex for this simple task and may not work in some environments due to incorrect environment configurations
Resolution
  • The simplest, fully supported way to do this is via a User Custom Action ScriptLink
  • John Liu has a nice UI tool to simplify registering your code with each site/site collection
Example
  • The following code example injects simple Javascript into each page to add a dynamic link to the left navigation menu (quick launch)
  • I like to put these in Site Assets at the Site Collection root.  If you don't have a Site Assets library, you can create one by opening the site in SharePoint Designer and double clicking the Site Assets link.  You can also do this by enabling any feature that utilizes the Site Assets library.  Otherwise, you can use a different library that everyone can read from.
  • You will need the following 3 files.  These should be saved into the Site Assets library at the site collection root site.
$(document).ready(function(){ 
 //Fixes Chrome Scrolling problem and load of ECMAScript 
 if (typeof(_spBodyOnLoadWrapper) !== 'undefined'){
     _spBodyOnLoadWrapper(); 
     
    console.log('test');
 MenuLastLI = $('#zz14_RootAspMenu li:last');
 MenuLastLI.before('
<li class="static"><a class="static menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" href="http://www.votematrix.com/"><span class="additional-background ms-navedit-flyoutArrow"><span class="menu-item-text">CUSTOM LINK</span></span></a></li>
');
 }; });
  • Click to open John Liu's configuration page (configure-page.aspx)
  • Configure jQuery as Sequence 900 (so it loads first).  Install Site Collection.
  • Configure JSTest.js as Sequence 2000 (Loads after jQuery)
  • That's it.  The link should show on the left nav.

Tuesday, November 15, 2016

SharePoint 2013 - Redirect to View Item Form on New Item Save

Scenario
  • You are saving a new record and want the user to be redirected back to the view item form to review the item.  This will allow the user to start a workflow or perform another action on the ribbon without the need to find the item in the list or library view.
  • Need the solution to use JSOM (client side script) only.  
  • Should work in Office 365, SharePoint Online, and On-Prem.
Issue
  • By default, SharePoint redirects you to the List View you most recently came from.
  • There is no out of the box setting for this.
Resolution
  • We solve this by adding a redirect script to each list view page that does the following:
    • Check if a new item was added by the current user.
    • Check and create a short term cookie to determine if they have already been redirected for this item
    • Redirect the user if they haven't already been
  • First add the following Javascript file to your SiteAssests/js folder.  
    • Create the "js" folder if it's not already there.
    • Replace the ALLCAPS hard coded values with appropriate values.

SiteAssets/js/SP.RedirectOnAddItem.js

var siteUrl = '/sites/SITENAME';

function createCookie(name,value,minutes) {
    if (minutes) {
        var date = new Date();
        date.setTime(date.getTime()+(minutes*60*1000));
        var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

function eraseCookie(name) {
    createCookie(name,"",-1);
}

function RedirectOnAddItem() {
var clientContext = new SP.ClientContext(siteUrl);
var web = clientContext.get_web();
this.currentUser = web.get_currentUser();
clientContext.load(currentUser);
clientContext.executeQueryAsync(
Function.createDelegate(this, onUserQuerySucceeded),
Function.createDelegate(this, onQueryFailed)
);   
}

function onUserQuerySucceeded(sender, args) {
    var email = this.currentUser.get_email();
    var userid = this.currentUser.get_id();
    var loginName = this.currentUser.get_loginName();
    var clientContext = new SP.ClientContext(siteUrl);
var oList = clientContext.get_web().get_lists().getByTitle('LISTORLIBRARYNAME');       
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><Query><OrderBy><FieldRef Name = "ID" Ascending = "FALSE"/></OrderBy><Where><Eq><FieldRef Name="Author" LookupId="True"/><Value Type="User">' + userid  + '</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>');
    this.collListItem = oList.getItems(camlQuery);
       
    clientContext.load(this.collListItem);
       
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onListQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));  
}

function onListQuerySucceeded(sender, args) {
var listItemInfo = '';
var listItemEnumerator = collListItem.getEnumerator();
       
    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
        listItemInfo += '\nID: ' + oListItem.get_id();
        listItemInfo += '\nAuthor: ' + oListItem.get_item("Author").get_lookupValue();
        var diff = Math.abs(Date.now()) - new Date(oListItem.get_item("Created"));
        var minutesPassed = Math.floor((diff/1000)/60);
        listItemInfo += '\nCreated (Minutes Ago): ' + minutesPassed ;
       
        if (oListItem && minutesPassed < 2) {
//alert(listItemInfo.toString());
if (!(readCookie('PANnewID') == oListItem.get_id().toString())){
createCookie('PANnewID', oListItem.get_id().toString(), 2);
window.location = "/sites/SITENAME/Lists/LISTORLIBRARYNAME/DISPLAYFORMNAME.aspx?ID=" + oListItem.get_id();
}
}
    }
}

function onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
  • Finally, add the following code to a Script Editor web part on each List View page where the user would normally be redirected.
<script src="/sites/SITENAME/SiteAssets/js/SP.RedirectOnAddItem.js"></script>
<script type="text/javascript">ExecuteOrDelayUntilScriptLoaded(RedirectOnAddItem, "sp.js");</script>

Tuesday, July 19, 2016

Restricted Edit Event Receiver - SharePoint 2013

Scenario
  • You need to restrict edits to a document library based on the current value of a field.
  • Full trust farm solution for SharePoint 2013 scoped to Web.
Solution
  • I created a configurable event receiver that will restrict edits (metadata and content) based on the value in one of the document's metadata columns.
  • Additional feature: Delay implementation of the restriction for a number of seconds from Created Date to allow for additional automated processes to update new documents.
  • Additional feature: Exclude a document from the restriction based on a regular expression using its  filename.
  • Additional feature: Automatically populate the Title field (or other text field) based on another choice or text field.
  • Open-Source code is available here:  RestrictedSave ZIP
    • Feel free to modify and use this code.  You may not resell it or a modified version of it as part of a packaged solution without my permission.
  • Disclaimer:  This will only prevent edits that trigger the item updating event receiver.  Some programmatic and 3rd party API calls made using bulk edit operations, workflow actions, or other event receivers may bypass the event receiver.  In addition, this code is not hardened for high security scenarios and is only meant as a first line defense against unwanted typical user edits.
Installation
  • Download the RestrictedSave WSP file and deploy to your farm.
  • Enable the Restricted Save feature on your sub-site.
    • Feature Description:
      Configured via the RestrictedSave list. If this site does not have one, a RestrictedSave list will be added. Document libraries named in the RestrictedSave list will not save a file if the user is unauthorized and the assigned column contains a certain value. If no required permission is specified, then the field can only be edited if the restricted column's value is changed. Multiple document libraries, columns, or values may be configured but must exist in this subsite. Optional New File Delay and Regular Expression Exclusion may be configured as well. Will also set the document title and/or filename based on a choice field by using the 'Title Choice Field' columns.
  • Configure the RestrictedSave list that was added to the site according to your needs.
Example

  • A standard configuration of the RestrictedSave list to restrict edits on a document library named "RestrictDeleteTest" when the "LOBType" column is set to "Choice 1".

  • The resultant error displayed on a document's edit properties form in the "RestrictDeleteTest" library when a filename modification is attempted.


  • Error Message in clear text
UNABLE TO SAVE! -- When column "LOBType" is set to "Choice 1" the item is locked and cannot be updated. -- Please work from a new copy or change the column value.





RestrictedSave List Configurable Fields
  • Instructions are provided in-line on the form.
  • Add one line for each restriction.  All lines will be parsed for each document edited in the sub-site.

--------------------------------------------------------------------------------------


And again in text format for search-engines, visually impaired, and copy/paste:

Document Library Name *


Column Name


Column Value


Required Permission To Edit

   

New Item Delay Seconds


Title Exclusion Regex


Title Choice Field Name


Title Choice Target

   

Thursday, July 7, 2016

Hacking the Datasheet View / Quick Edit in SharePoint 2013 to display in an IFrame

Scenario
  • I created a document library list view in datasheet (quick edit) mode for display in a custom popup dialog in a SharePoint 2013 Visual Studio project "application page".
    • This grid was used to make last minute changes to metadata values of selected items before continuing an existing process in a larger solution.
  • I needed to display the list view using an IFrame pointing to a URL filtering the values by IDs.
  • This was a large list exceeding the list view threshold
  • I needed to hide all chrome, navigation, ribbon, and other elements surrounding the list view web part.
  • I needed to call a JavaScript function outside the list view page from a button on the list view page.
  • Note that I couldn't figure out how to convert the application page into a web part page which is why the list view web part is included via an IFrame rather than embedded directly into the page, however the same issues would apply except without the need for a hidden button or the chrome trimming.
  • An alternative to using the list view web part in datasheet mode would be to use a datagrid control and manage the CRUD programatically, but this would be harder to maintain if the SharePoint schema changed down the line and would require much more coding to implement correctly.
Issues
  • In Datasheet view the last record edited (or possibly the only record) will only save if you select another record (which you can't even do if there's only one record). This was an issue for 2 reasons:
    • There was a custom button in the app that when clicked would continue the process without saving the record that was just edited.
    • The stop editing functionality which would normally be used to save the last record resulted in a list view threshold error dialog due to a bug in the datagrid / Quick Edit mode when in a folder or using filter parameters and using the "Stop editing this list" link because it forwards to a standard view without the filter or folder.
Resolution
  • Implementing the IFrame: A bug in Visual Studio .Net 4.5 framework IFrame web control requires the control to be instantiated manually in the code behind rather than automatically in the designer code file
protected global::System.Web.UI.HtmlControls.HtmlGenericControl iframe1;
  • The IFrame was added to the application page like so:
 <iframe name="iframe1" id="iframe1" ClientIDMode="Static" runat="server" height="400" width="400" seamless" />
  • The IFrame was instantiated dynamically using server side code that set the filter parameters in the query string like so (itemids are in a semicolon delimited format):
iframe1.Attributes["Src"] = "/sites/SiteName/LibraryName/Forms/DatasheetViewName.aspx?IsDlg=1&FilterName=ID&FilterMultiValue=" + itemids;
  • I hid a button (id = btnCopy style:display = none) on the application page which ran the application code and added the following JavaScript function to the application page so that it could be called from the list view page from within the IFrame.  Note the timed delay here as I'll explain this later.
<script type="text/javascript">
    function triggerBtnCopyClick() {
        setTimeout(function () { document.getElementById('btnCopy').click(); }, 1200);   
    }
    
    ....  existing code used by the application page that handled the btnCopy click event.
</script>
  • I added a script editor web part to the Datasheet List View page and configured it to remove the chrome elements still remaining after IsDlg=1 did its work.  Note that your class names may be different based on the WPQ number (find using your browser's developer tools).
    <style>
    #s4-ribbonrow{display: none;}
    #Hero-WPQ2{display: none;}
    #CSRListViewControlDivWPQ2{display:none;}
    </style>
    • Finally, I added the button and code to call the parent page's triggerBtnCopyClick code.  You will need to find the GUID of your list view web part (webpartid) and plug it into the code.
      This is the part that involved hacking the datasheet view by finding the function calls the "Stop editing this list" button used to save the final changes and reusing them in my own code.  The downside to this is that the grid needs to be refreshed afterwards and takes a second to finish processing so I added a 1200ms delay into the triggerBtnCopyClick function above that processes the code after the save.
    <input type="button" id="SaveEdits" value="Save and Process" onclick="var gridInitInfo = g_SPGridInitInfo[('{WebPartID GUID HERE}')]; var ganttControl = window[gridInitInfo.controllerId]; var ganttControl = window[gridInitInfo.controllerId]; ganttControl.TryDispose(function(dlgReturnValue) {window.location.reload(false);}); this.style.display = 'none'; window.parent.triggerBtnCopyClick(); return false" />



    Thursday, April 9, 2015

    SharePoint Migration and Administration Notification Tool

    Scenario
    • You are performing an administrative change at the SharePoint site level or for all sub-sites starting at a particular location
      • Examples
        • Migration
        • Retention, Archival or Deletion
        • Redesign
        • User Acceptance Testing (UAT)
        • Upgrade
        • Restructure
        • Merge
    • You need to convey the administrative status to all users on the site
      • Likely as part of your SharePoint administrative communications plan
      Issue
      • There is no simple or easy out of the box way to accomplish this
      • We don't want to manually replicate notifications on each sub-site, modify the master pages, or configure content roll-ups on each site
      Solution
      • I developed the SharePoint Migration Notification Tool specifically for this purpose
        • Download SharePointMigrationNotification.wsp for deployment at the Site Collection level on a SharePoint on-premises farm
        • Add and Install the WSP file you downloaded
        • Enable the site collection feature named "Migration Notification" on each site collection
        • Add a list to the root site for each site collection.  Select the "Migration Notification URLs" list template (found under Blank & Custom list types)
          • You can name this whatever you like, but you should only have 1 of these lists at the site collection root because the tool uses the first one it finds
      • Here are some examples of the default notifications you can configure
        • You can also add your own custom notification messages

      • Here is the list configured at the Site Collection root level that defines your notifications
        • The new/edit item forms describe what should be entered in each field

      • Notification Tool Feature List
        • Site Collection Deployed full trust solution (Currently designed for SharePoint 2010+)
        • Client object model exclusively used for notification processing in order to support future releases on the SharePoint 2013 app model and Office 365 environments
        • Drop down selection of common notification scenarios
        • Migration notification list definition
          • Must be added to the root site collection
        • Configurable notification text with wiki-like syntax for inserting hyperlinks or a date from the Migration Notification List
          • More Info URL
          • New URL
          • Migration Date
        • SharePoint client object model property bag caching to reduce server load and increase performance
        • Supports the standard notification color selections
        • Include all sub-sites (notification can be overridden at the child site level)
        • New / test site URL replacement including the full path to the current page/form
        • Notification disable flag
        • Automatic population of the title field from the New Site URL wiki when sent to a ".../NewForm.aspx?source=..."  page (Using "New URL Set Title" syntax)
        • Permission based notification visibility (security trimming)
        • Notification dismissal option (cookie based)
          • 1 day dismissal duration
        • Automatically delete sites from the migration notification list by selecting Auto Delete or Auto Recycle in the Old Site Status field
          • This capability is enabled through a separate Site Collection feature and requires the user to have permissions to delete the site
          • This feature is especially useful for retention policies that require you to post a notice of deletion before deleting the site.
          • If you use Auto Delete instead of Auto Recycle, you should backup the site first if there is any possibility of needing a restore
      • Contact me for SharePoint Farm Upgrade or Migration services, to request a customized version of this solution, or to provide SharePoint Solution Architecture services
      Releases
      • Release 1.3.2.0 (2013 only): 11/7/2015
        • Fixed a bug when removing an existing Migration Notification List and adding another with a different name.
      • Release 1.3.1.0: 7/6/2015
        • SharePoint 2013 list view fix
        • 3 digit year date format fix (115 fixed to be 2015)
      • Release 1.3.0.0: 5/29/2015
        • SharePoint 2013 version created
      • Release 1.3.0.0: 5/27/2015
        • New Features
          • Auto Delete Old Site feature added
            • New feature activates migration notification list event receiver keying off a new field type "Old Site Status"
          • Refactored to use ScriptLink and _layouts JavaScript code file to enable browser based code caching
      • Release 1.2.1.0: 5/15/2015
        • Bug Fixes
          • Redirect URL now works when browsing folders within a list/library
            • These links now redirect to the Document Library root folder
        • New Features
          • Notification dismissal option (cookie based)
            • 1 day dismissal duration
      • Release 1.2.0.0: 5/13/2015
        • Bug Fixes
          • URLs with spaces and special characters now work correctly
            • You will need to make sure to unencode the URLs when entering them in the list.  The title field description now reflects this requirement.
          • Redirect URLs with special characters will now be encoded correctly
        • Added Features
          • Permission based notification visibility (security trimming)
      Backlog
      • Develop an Office 365 app version
      • Add parameter for dismissal duration length

      Tuesday, March 10, 2015

      CRM and xRM vs SharePoint: Business Solution Architecture

      Scenario
      • You are tasked with developing an enterprise application or business process solution using a stable platform tool
      • You have MS SharePoint / Office 365 and MS Dynamics CRM options available and need to decide which to use
      SharePoint / Office 365 and Microsoft Dynamics CRM and xRM Comparison
      • SharePoint and Office 365 is a(n)
        • Customizable and flexible business solution platform
          • Content-centric
        • Content/document management and versioning system (CMS/DMS)
        • Enterprise search engine
        • Workflow system (WWF/Azure Workflow)
        • Alert engine
        • Extension for MS Office client apps and MS OfficeWeb Apps (OWA)
        • Web site development and web content management tool (WCM)
        • Publishing tool
        • Personalizable web interface
        • Social platform
        • Cloud capable, multi-tenant framework
        • MS Access web database platform
        • MS Project platform
        • MS Team Foundation Studio site platform
        • MS Dynamics CRM document repository
      • Dynamics CRM (xRM) is a(n)
        • Customizable CRM line of business system
          • For Sales and Marketing departments
        • Entity management platform
          • Ex: Accounts, contacts, orders, cases and opportunities
          • May be configured for case management solutions such as health and human services, benefits administration, legal cases, grant management, etc.
        • Query tool
        • Workflow engine (WWF)
        • Analytics tool
        • Extension for MS Outlook, Excel, and Word
        • Custom business solution platform
          • Email and conversation-centric applications
            • Customer service, tech support, employee relations, outreach, campaigning, contracts, etc.
      Summary

      MS Dynamics CRM is designed as a customer relationship management system and the platform has native relational design at its heart.  It can be adapted to many conversational and relationship based business processes.  The primary problem with CRM, is that it lacks the popularity of SharePoint and Office 365 due to reduced feature set and increased cost and is therefore less likely to be available as a platform to most business developers and end users.  This makes finding third party solutions, developers, community forums, and experienced users difficult or costly.  Dynamics CRM as a line of business app has many competing products that make the base feature set less important when choosing a solutions platform.  These include those from MS partners built directly on SharePoint such as BPA Solutions CRM, SP CRM Template, and SP Marketplace CRM.

      The capabilities of SharePoint and Office 365 currently outweigh those of Dynamics CRM for general purpose custom business solutions.  This is especially true when business solutions incorporate enterprise search, documents and content management, publishing and approval, personalization, collaboration, or public web content.   SharePoint with a typical set of third party add-ins provides the best long term, affordable, and flexible solution architecture.  Microsoft has embraced SharePoint as an application platform within most of its divisions, Dynamics being the outlier.  SharePoint/Office 365 is also the fastest growing product within Microsoft due to its rapid adoption globally.  Finally, SharePoint has many more third party solution providers and COTS line of business systems than Dynamics CRM.

      For highly relational and performance based web applications it is better to develop a user interface in SharePoint (app model or web parts) with a SQL DBA developed backend or MS Access Web Database rather than develop a solution using the Dynamics CRM drag drop interface or native SharePoint lists/libraries.  This will remain the case until Dynamics CRM catches up to SharePoint/Office 365 in functionality, SharePoint integrates a better relational/back end framework, or another company develops a better web application platform.


      Microsoft Corporate Strategy and Product Roadmap Commentary

      Ideal Objective: SharePoint = Microsoft's Web Operating System

      SharePoint must be the single web based application platform for all Microsoft's business solutions.  MS Dynamics CRM has not been ported to the SharePoint platform for the main reason that customizable relational models are not embraced within SharePoint.  Every attempt by the SharePoint product team to incorporate true relational database (RDBMS) integrity, performance, and design into the product have met with limited success.  External lists and lookups are feature deprived and difficult to configure. Access web databases are siloed from other SharePoint features and sites.  Native lookup fields lack basic features and have limited relational support. Database synchronization to or from lists is non-existent.  Many third party vendors have stepped up to fill these gaps, but that leaves Microsoft without the capabilities for internal development utilizing these missing features.  For now, we are stuck in that period where the Dynamics CRM platform is not yet obsolete, but SharePoint (without third party add-ins) is not ready for the port.

      If Microsoft is to succeed in its primary focus towards enterprise software, then these product teams need to work together to bolster SharePoint's feature set as a solutions development platform and then port the Dynamics business solutions onto the improved platform.  This would allow the Dynamics teams to contribute to the design of the SharePoint platform while also removing the CRM team's burden of having to re-invent the wheel regarding the existing and continually improving SharePoint feature set.  Examples of these shared functionality opportunities include: workflow engine, search engine, forms engine, list engine, authorization, authentication, UI, admin consoles, deployment methods, device support, mobile applications, OneDrive for Business synchronization, web services, application object model, BI, content management, metadata, analytics services, patches, upgrades, and MS Office integration.  Microsoft has taken the first steps with incorporating the MS Access team into SharePoint forms and Access web database design, but the SharePoint team also needs the real world requirements and feedback from the Dynamics teams to ensure the future success of both products.

      Nearly 10 years ago, at the last SharePoint Conference he keynoted, I asked Bill Gates if SharePoint would get true relational design functionality.  His answer was that they were working on some of these features (which turned out to be External Lists and Lookup RI) but he still insisted on using SQL RDBMS for highly relational solutions.  This answer was inadequate and shortsighted.  It is now time for Microsoft to step up and take advantage of the monumental opportunity to combine relational design into the worlds most prevalent and feature rich Web OS, SharePoint (aka Office 365).

      Sources and Other Resources

      MS Ignite 2015 Update
      While attending MS Ignite 2015, I used the opportunity to talk with product leads and managers on both Dynamics CRM and SharePoint/Office 365 to find out how this is going down within Microsoft.  Both teams admit that there is very little collaboration between the Dynamics and SharePoint teams and there is a lack of direction from the executive level.  This issue flows from the Microsoft organizational structure and requires executive action or an internal grass roots effort to remediate.  If Microsoft wants to establish itself as the king of business solutions, then we need these teams (Dynamics, SharePoint/Office 365, and MS Access) to combine their platforms and stop wasting time reinventing the wheel.

      One prime example of waste was brought up in the CRM line of business development session.  Since the CRM team does not collaborate with the SharePoint team, they are developing their own separate enterprise search engine rather than utilizing the highly efficient FAST search engine the SharePoint/Office 365 team bought for $1.2 Billion.

      Tuesday, August 5, 2014

      AutoSpInstaller Notes

      Scenario
      • Using AutoSpInstaller to run a multi-server farm install.
      Issues
      • When provisiong the User Profile Service the second window pops up and immediately closes, then the main window eventually hits a Timed Out error
        • This was caused by the Farm account being unable to run PowerShell commands on the app server despite being configured correctly as local admin and having the log on locally permission
          • When running any command  as the farm account, the following error is displayed: "The term 'Get-ChildItem' is not recognized as the name of a cmdlet, function, script, ...."
            • 'Get-ChildItem' here could be any PowerShell command
        • This anomaly only occurred on the app server in the farm and only with the farm account, but unfortunately, the User Profile Service must be configured as the farm account.
        • The solution ended up being that the PSModulePath environment variable had been removed for the farm account.  We re-added and it ran fine.

      Wednesday, May 21, 2014

      SharePoint 2013 Virtual Development Environment Installation Guide - Part 1

      SharePoint 2010 dev server deployment guide can be found here

      Scenario
      Prerequisites
        • Your workstation must be running a 64bit processor with Hardware Virtualization enabled
        • You must have enough memory (6 GB), disk space (60 GB), and processor power (2 cores) to run the VM and hold all snapshots.  Disk space will need to grow as you add content.
          • I highly recommend running this VM from a solid state drive (SSD) for optimum performance.  Disk speed is the greatest limiter for performance and if your RAM is limited, then the SSD swap file will help compensate.
        • You must have access to and appropriate licensing for above products
          • ex: MSDN Subscription
        • You must have time (about 8 hours) to install everything.
          • Hints:
            • Look for "Wait" for good break points
            • Snapshots can be used to create other virtual machines or to test minimally installed environments
            • Hyper-V, VirtualBox and VMWare specific settings will be called out
      How To
      • Download the Software Listed Above - Wait
      • Enable Windows 8 Hyper-V, install VMWare, or install VirtualBox and the Extension Pack
      • Hyper-V: Enable a Shared/NAT virtual switch
        • ICS can only be set up from one network card at a time in Windows 8 so if you have a laptop and switch between WiFi and Ethernet you will need to change the ICS if you need the VM to access the internet
      • Create a new virtual machine named "sp2013"
        • Hyper-V: Generation 2 option
        • 6144 GB RAM (not dynamic)
        • Network: Use a Shared/NAT connection
        • 125GB dynamically expanding boot hard disk
          • You will likely use 45GB of this without any content
        • Increase the processors: 2-8 range
        • Mount the Windows Server 2012 R2 ISO
        • VirtualBox: Enable RDP support
      • Start the sp2013 virtual machine and boot from DVD
        • Hyper-V: Hold down a key to boot to DVD
          • Don't wait till the prompt to "Press a Key" or you will get this error: "Boot Failed. EFI SCSI Device."
      • The Windows Server 2012 R2 installer should begin
        • Select Windows Server 2012 Standard (Server with a GUI)
        • Select Custom (new install)
        • Short Wait
      • Set a new administrator password
        • pass@word1
      • Install VM guest tools (none for Hyper-V)
        • VirtualBox: VirtualBox Guest Additions
          • Auto Reboot
        • VMWare: VMWare Tools
      • Configure Server Manager: Local Server properties
        • Rename the server to sp2013 (Both the name and the computer description)
          • Note: If you forget this step, you will have a randomly named server.
            I have included instructions for aliasing and configuring a randomly named server
          • Restart later (so we can shut down instead)
        • Enable Remote Desktop
        • Disable IE Enhanced Security Configuration
      • Shut down and take a Snapshot named "Windows Install" then boot the machine
      • Server Manager Dashboard: Add Roles
        • Server Roles
          • Active Directory Domain Services
            • Add features and Include management tools
          • Application Server
          • DNS Server
            • Add features and Include management tools
            • Ignore Static IP warning
          • Web Server (IIS)
            • Add features and Include management tools
        • Features
          • ASP.NET 4.5 (under .NET Framework 4.5)
          • Telnet Client
            • SMTP connectivity troubleshooting tool
          • User Interfaces and Infrastructure
            • Desktop Experience
              • Also adds Ink and Handwriting Services
        • Application Server / Role Services
          • Web Server (IIS) Support
            • Add features and Include management tools
        • Allow auto-restarts then Install
        • Short Wait
        • Click "Promote this server to a domain controller"
          • Select "Add a new forest"
          • Root domain name: sp.local
          • Next
          • Forest and Domain functional level: Windows Server 2012 R2
          • Password: pass@word1
          • Continue pressing Next until Install
            • Short Wait for NetBIOS domain name to be recognized and for Prerequisite check
            • Ignore the 3 warnings
          • Install
          • Short Wait
          • Accept reboot prompt
          • Log back in as Administrator
      • Server Manager Dashboard: Add Roles
        • Features
          • ASP.NET 3.5 Features
          • Before installing specify the following alternate path
            • D:\sources\sxs  (where D: is the Windows Server DVD drive)
      • Verify Internet connectivity by opening Internet Explorer and browse to Bing
      • Disable SmartScreen Notifications from the Action Center
      • Windows Update: Turn on auto updates
        • Install Updates and Wait
        • Reboot when prompted
        • Some errors in windows update may occur as they are installed and the server is rebooted. Here are some solutions:
          • Several updates fail and require reboots
            • Open System Configuration (msconfig)
            • Check Selective startup
              • Uncheck Load Startup items
            • OK
            • Restart when prompted
          • Hyper-V: Security Update for Windows Server 2012 R2 (KB2920189) Failed 800F0922
            • Only occurs on Gen 2 Hyper-V with Secure Boot
            • Temporarily disable Secure Boot in the VM settings while installing the update
      • Open Active Directory Administrative Center (Pin to desktop and Start menu)
        • Administrator account
          • Account / Password Options: Password never expires
          • Organization / Email: administrator@sp.local
        • Create a user in the Users OU
          • Full Name: User
          • User SamAccount: sp\user
          • pass: same as Administrator password
          • Account / Password Options: Password never expires
          • Organization / Email: user@sp.local
        • Add User to the Users group
        • Create a user in the Managed Service Accounts OU
          • Full Name: spservice
          • User SamAccount: sp\spservice
          • pass: same as Administrator password
          • Account / Password Options: Password never expires
      • Open Group Policy Management console
        • sp.local / Domains / sp.local / Domain Controllers / Default Domain Controllers Policy
        • Right click and Edit
          • Policies / Windows Settings / Security Settings / Local Policies / User Rights Assignment
          • Edit Allow log on locally
            • Add the Users group
      • Stop and Disable the following Services
        • DFS Namespace
        • DFS Replication
      • Shut down, snapshot "DC and IIS", and start virtual machine
      • Mount the SQL Server ISO to the VM DVD drive
      • Start SQL Server Setup 
        • Install Stand-alone
        • Use MS Updates
        • Ignore DC and Firewall warnings
        • All Features with Defaults
        • Continue
        • Server Configuration / Service Accounts
          • Use the same account for all SQL Server services
            • specify the sp\spservice account and password created above
        • Continue
        • Analysis Services Configuration
          • Account Provisioning
            • Add Current User
        • Reporting Services Configuration
          • Install only for both
        • Distributed Replay Controller
          • Add Current User
        • Continue then Wait
      • Shut down, snapshot "SQL Server", and start virtual machine
      • Open SQL Server Configuration Manager
        • SQL Server Network Configuration
          • Protocols for MSSQLSERVER
            • Enable Named Pipes
      • Restart the SQL Server (MSSQLSERVER) service
      • If your server is randomly named - not sp2013
        • DNS Manager
          • Forward Lookup Zones
            • sp.local
              • Add a new alias
                • Name: sp2013
                • FQDN: Browse to splocal\servername
                  • servername will be a randomly generated value
      • Mount the SharePoint Server 2013 iso
      • Start the Prerequisites installer
        • Run D:\Splash.hta (open with MS HTML Application Host)
        • Short Wait
        • Finish to restart
      • Start the SharePoint Install
        • Enter your Enterprise license key
        • Wait
        • Run the Configuration Wizard
        • Create a new server farm
        • Configuration Database
          • Server: sp2013
          • Name: SharePoint_Config
          • Username: sp\spservice
          • Password: same as above
        • Farm Security Settings
          • Passphrase: same as admin password above
        • Central Admin Web App
          • Port: 8000
          • Auth: NTLM
        • Wait
        • Finish
      • IE will open to the central administration website.
        • Join the experience program (or don't)
        • Start the wizard and configure as follows
      • Central Admin Initial Farm Configuration Wizard steps
        • Use existing managed account: sp\spservice
        • All items should be checked except for Lotus Notes
        • Next
        • Wait
        • Create Root Site Collection
          • Title: SP2013
          • URL: /
          • Experience version: 2013
          • Template: Collaboration \ Team Site
          • OK
            • If you encounter a  error, skip to the next step (AAM config) then delete the running timer job, restart IIS, and re-run the wizard from Central Admin
          • Finish
        • Open central admin (http://sp2013:8000) and add the following Alternate Access Mapping (AAM) internal URLs
      • Set the browser home page to http://sp2013
      • Configure Search from Central Admin
        • Central Admin \ Manage service applications \ Search Service Application (first one)
          • Content Sources
            • Local SharePoint Sites
              • Incremental every 30 minutes (or other value here based on needs)
                • Recommend disabling incremental crawls for performance
              • Note: Continuous crawls will require more resources on VM startup
            • Start a full Crawl
      • Open http://sp2013 in IE
        • Add sp\administrator to the sp2013 Members group
        • Add sp\user to the sp2013 Visitors group
        • Validate that the following workset
          • Any workflow
          • Search scopes
          • My Sites and User Profile
      • Performance Tuning
        • Run the following PowerShell scripts (in SharePoint 2013 Management Shell)
          • Set-SPEnterpriseSearchService -PerformanceLevel Reduced
        • Disable the following system services unless/until needed
          • SQL Server Analysis Services (MSSQLSERVER)
            • From Automatic to Disabled
          • SQL Server Reporting Services (MSSQLSERVER)
            • From Automatic to Disabled
          • Optional (if you do not need SharePoint search and want to reduce memory footprint)
            • Remove the incremental crawl scheduled earlier
        • More tips from Andrew Schwenker
      • Shut down, snapshot "SharePoint Configured", and restart
      Optional Configurations

      Monday, March 10, 2014

      SharePoint Farm Infrastructure Architecture Recommendations

      Following are some recommendations for a typical SharePoint Development environment topology:

      In addition to the corporate Test/Stage and Prod farms, I recommend a standalone Dev VM for each of your MSDN subscriptions/developers.  Development VMs contain a standalone single server farm as well as all development tools.  Any content only solutions (OOB site collection or web scoped) should be configured directly in Production in a new site collection.  Custom development (Visual Studio) is completed on the development VMs, released to Stage, tested, and then released to Prod.  Each Dev VM should be semi-isolated from the corporate network (separate subnet and domain).  Dev VMs should be disposable, distributable, and standardized as in my article here: SharePoint 2010 Development Farm VM

      In this way every new developer would only need to copy the VM to their workstation and would be up and running after connecting to Source Control.  They would also have full control of their VM so IT admin requests would be minimized.  Simply recopying the template VM would fix any issues.

      The development VM operating system drive should be a solid-state drive.  Optionally, an external BLOB storage and search index partition may be stored on a low cost drive (requires a little more configuration).  Workstations must support hardware virtualization.

      The Test/Stage servers may need to be used for debugging and development of integration issues.  Alternatively, a standalone Dev farm on the corporate network can be set aside for this purpose.

      In each case, a process for synchronizing Production site collections back onto the Test/Stage and Dev VMs should be maintained.  Usually this includes site collection backups being made available as needed.  However care must be taken to ensure information security policies are maintained.  This can include scrubbing/redacting content, disabling alerts and emails (this may be done through network isolation), and populating sample data.

      Tuesday, May 28, 2013

      Every SharePoint Team Site should have a OneNote notebook

      Update:  Office 365 and SharePoint now include a OneNote notebook in every Team Site.  Thank you Microsoft for listening!

      In my experience, any "Team Site" should have a document library containing a OneNote team notebook.  My premise is that since a team site is typically created for collaboration, a team notebook is likely the best tool for those needs.  Team sites gutted and used as the base for a custom solution would no longer count towards this premise.  I would also consider Evernote or similar notebook tools as decent alternatives, albeit not as fully featured or integrated.

      Windows 8/10 Tip 
      Make the desktop version of OneNote the default (Not the Metro version) to get the most features

      OneNote 2016 and Office 365 new features

      OneNote Notebook features
      • Continuous Save. No Save Button
      • Automatic track changes / version history
      • Automatic synchronization and offline editing
        • Sync Now (Shift+F9) is an option to refresh quicker when collaborating
      • Simultaneous editing (changes highlighted)
      • Windows-Shift-N desktop shortcut or right click via the control panel
        • Also the Windows-N new side note and Windows-S screen clipping shortcuts
        • Other than Copy/Paste, these should be your most commonly used keyboard shortcuts
      • 1-4 click left/top/right navigation (can go deeper at the section level)
      • Recent notebooks are easily accessible via the Notebook Pane
        • Notebooks are available on the Notebooks Pane on the left nav every time you open OneNote until you remove (Close) the notebook
        • Notebooks can be renamed uniquely to that machine and user
          • Notebook contents however are synchronized across machines and users
        • OneDrive/OneNote.Com/SharePoint/O365 will also maintain a separate list of your recently used notebooks across machines
      • Audio (and video) recording with note taking time stamps
        • Notes taken at any time during the recording can replay the recording at the appropriate time
      • Mobile device support
      • Embedded documents
      • Screen clip tool (Windows-S or Insert screen clip from note page)
      • Embedded links (Linked Web Notes)
        • If researching using a browser, notes taken in OneNote will automatically embed the related URL
        • Copying, pasting, and screenshots will also include the current address from the browser
        • Also works when viewing other OneNote notebooks, PowerPoint, or Word documents
      • Drawing/tablet support (Ink to Text, Ink to Math)
      • Math (Trig/Calculus support )
      • Linked meeting notes from Outlook invitation for quickly accessing meeting notes for scheduled meetings
      • Free form layouts, markups, and drawings
        • Text, drawings, images, etc. can be inserted anywhere on the note page
        • Use to markup a screenshot or document print
      • Dock to desktop and full screen features
        • Docks to side of screen displacing the desktop so that you can take notes while demoing or working
        • Full screen mode removes the notebook navigation and menu items
      • Save to SharePoint or OneNote Online (OneDrive)
        • Notebook sections and pages are saved as folders and files within the document library, so don't be surprised if you see this in explorer view
      • Print to OneNote
        • Quickly markup or take notes on any document source
        • OneNote installs a virtual printer driver on your machine
      • Web based versions of OneNote
      • Share pages and notebooks via Email or Hyperlink (to facilitate notebook adoption)
      • MindMapping Source (Not really specific to OneNote but a nice use)
        • MindMaps are just graphical bulleted lists.  Make the bulleted list in OneNote and then copy the list to your favorite MindMapping tool.  This way you can collaborate with others who don't know or own the MM tool and you can look cool demoing the info.  Note that my whole blog could be converted into a giant mind map. :)
      Additional Features with OneTastic
      • Macros
        • Macroland: prebuilt macros
      • OneCalendar
        • See your notes by date in a calendar
      • Image utilities
        • Crop/rotate images and select OCR'd text
      • Custom styles
        • Like MS Word styles
      • Favorites and pin desktop shortcuts
      When not to use OneNote
      • Final published or printable document
      • Blogging
        • Use Windows Live Writer instead (send to blog is supported but not as good)
        • Drafts in OneNote are ok
      • Heavily formatted content or page oriented layout
        • This is better done in Publisher or Word
        • When copy/pasting or sending to MS Word, bullets may need to be reset and other formatting corrected
          • Highlight the bulleted list and then double click the bullet icon to fix the lists in MS Word
      • Diagramming or presentations
        • Use Visio or PowerPoint
        • Quick hand drawings or draft object drawings are ok
      • Spreadsheets
        • Use SharePoint lists or Excel and embed a link in OneNote
      • Dynamic/sortable/filterable lists, data, or documents
        • Use SharePoint

      Tuesday, November 30, 2010

      SharePoint 2007, 2010, and 2013 Cascading Lookup Column Comparison

      Scenario
      • You have multiple SharePoint lists that are related
        • Parent/Child or other relationship
      • You want to allow the user to define the relationship via a Lookup Column Dropdown (Combobox) or Multiselect Interface
      • Or you need filtered lookups or some other additional lookup functionality
      Issue
      • The out of the box SharePoint Lookup Field columns are severely limited
        • They really only work for relatively small lists of uniquely named items that don't change often
        • SharePoint 2010 natively supports related lists, but do not have all the features below
      • We need one or more of these advanced features
        1. Cascading Updates (and possibly deletes)
          • Maintain Referential Integrity
          • Updates made in one list are reflected in the lookups.
        2. Keyboard filtering from the dropdown and multiselect interfaces
          • Autocomplete, find as you type
        3. Cascading drop-down filters
          • One or more dropdowns to filter the final dropdown
          • Ex: State, County, City
        4. Lookup filters (likely based on a List View)
          • Ex: Only show my Cities, or only show Active Items in the lookup
        5. Datasheet view editing (Excel, Access), InfoPath, and Office DIP support
          • In most cases this is unavailable.  The workaround is to create a view without the lookup fields for use with Office integration and ensure the lookup fields are not required or have a default value.
        6. AJAX
          • We don't want to postback when applying realtime filtering
          • We may not want to preload all the values for very large lists
        7. May be used in a Calculated Column
          • Ideally the text field and ID field would both be accessible
        8. Supports multiple display fields from the lookup list
          • ex: First and Last Name concatenation in the dropdown
          • Workaround would be to use a calculated field within the lookup list
        9. Link to add an item to the lookup list from the lookup column interface
        10. Cross site support
          • By default the list must be in the same subsite as the lookup column
        11. Cross site-collection support and content type hub support
          • Workaround would be to synchronize lookup lists accross site collections using a workflow, content deployment job, or a custom timer job.
        12. Two-way relationships
          • Items within a lookup list will keep track of where they have been referenced.
          • Ex: Orders are linked to a customer via the order form.  On the customer form, you can see the linked orders.
          • SharePointBoost's LookupBoost or Sparqube's Lookup Tracker can be installed to provide this information via a separate relationships page.
        13. Matches the SharePoint look and feel
          • Ex: Inherits themes/styles for drop down
        14. Can be created as a site column
          • Sometimes only implemented as a list column.
        15. Conversion tool 
          1. Converts lookup columns to custom lookup
          2. Converts custom lookup back to a regular lookup
        16. Allow filtering from a multiselect
          • Ex: Filter lookup of Cities when multiple States are selected
        17. Set the lookup column's default value
        18. Referential Integrity (2010 new feature)
          • Cascade or disable updates/deletes when the item is used in lookups elsewhere
          • Not available on a multi-select
        19. Projected Columns (2010 new feature)
          • Lists with the lookup column will expose other columns from the lookup list.
          • Ex: Order list with a Customer lookup column could also include Customer Phone and Customer Email in the Order list view based on the selected Customer
      Resolution
      • The following third-party products are available to meet your needs.  This analysis was done based on the marketing material available on their websites and any personal experience I have with them.   ? - denotes unknown feature
        • SharePoint 2010 Lookup Column (Out of the box - not third party)
          • Features: 1 (includes recycle bin), 2, 5?, 10, 13, 14, (17 via code), 18, 19
        • Sparqube SharePoint Lookup Column (SharePoint 2010+)
          • Features (provided by vendor): 1, 2, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
          • Note: There are 2 column types to choose from.  Each has advantages and disadvantages.  All features above may not be available depending upon which control you use.
          • (12) Sparqube Lookup Tracker provides this as a separate (included) feature
        • KWizCom SharePoint Cascading Lookup Plus
          • Features: 1?, 2, 3, 4, 6, 7, 8, 9, 10, 12*, 14, 15.1, 17?, 18?, 19?
          • Review Notes
            • Runtime issues will occur if you are still referencing AJAX 1.x
            • Single-select, single-value items appear in a grid format with a header
            • Display form grid uses a hyperlink icon rather than text
            • Dropdown skins do not match SharePoint but are customizable
          • *(12) Same list 2-way relationships are not supported
        • SharePointBoost Cascaded Lookup
          • Features: 1, 2, 3, 4, 5 (except multiselect), 8*, 9, 10, 12*, 13, 14, 15, 17*, 18, 19
          • *(12) Lookup Boost: Provides feature 12 via a separate relationship page
          • Review Notes
            • Installed properly
            • Worked as advertised
            • Issue with saving a sub-site as a template after implementing a root level site column and content type.  Workaround provided by SharePointBoost
          • *(8) - Doesn't support hyphenated values in the drop-down for SP 2010.
          •  *(17) - Only supports defaulting to first item in a view and does not support the standard Default property, so this is difficult to set from code.  Does not support defaults on a multi-select.
        • Azu Lookup Plus 2013
          • I haven't evaluated this yet.  Please refer to the website.
        • Infowise
          • Features: 3, 4, 9+, 10, 12 (with bi-directional bundle), 13, 14, 15, 17?, 18?, 19?
          • (9+) Enhanced support for inline simple text additions and for task creation
        • Bamboo Lookup Selector
          • Features: 2, 3, 6, 10, 11, 17?, 18?, 19?
        • SharePointBoost Cross-Site Lookup
          • Features: 2, 10, 15, 17?, 18?, 19?
          • Lookup Boost: Provides feature 12 via a separate relationship page
        • SharePoint Tool Basket
          • Features: 2, 6, 17?, 18?, 19?
          • Open Source
        • SharePoint Cascaded Lookup Dropdowns
          • Features: 3, 6 (client-side only), 17?, 18?, 19?
          • Not a column.  Must be applied to each form.
          • Open Source
        • CodePlex Filtered Lookup
          • Features: 4, 10, 17?, 18?, 19?
          • Open Source