Upgrading a multi-server SharePoint farm from Standard to Enterprise – lessons learned


While I’ve done a lot of things in the SharePoint world, one thing I had done less than a handful of times was upgrade from a Standard CAL to an Enterprise CAL. Today I had to do it again, and I was fully prepared for an easy copy/paste operation with coffee mug in hand. Boy did I underestimate the power of SharePoint. 🙂

It had been a while since I had last upgraded the SKU of a SharePoint farm, so clearly I was overconfident and deserved a bit of a challenge.

The issue I had was this:

An error occurred while enabling Enterprise features. Refer to the event logs on your server machines for more details.

If you’re still reading this I’m assuming you have the same vague error message. I won’t post all of the log traces here, but suffice to say this issue was pretty well documented on the interwebs.

To make a long story short, I had a multi-server farm with a WFE and an APP server (as well as backend SQL). When I would run the GUI wizard to update the license key, it would take several minutes and would ultimately fail. After scouring through the logs, I was no further along as I was unable to find anything specific that would help me out. I located a TechNet thread that suggested the following:

  1. Stop the Timer Service on all machines in the farm except for 1, in my case I left it running on the APP server.
  2. Add the new product key and hit OK to start the SKU upgrade process in the Central Admin GUI.
  3. Watch the event log of the APP server and wait for an entry with a source of “SharePoint 2010 Products Configuration Wizard” which will inform you that it was Successful.
  4. Start the Timer Service on the next machine in the farm.
  5. Watch the event log and wait again for the successful entry…
  6. Continue with steps 4-5 on all additional servers in the farm.
  7. Once you’ve received all successful entries in your event logs, a minute or so later you should get a successful notification in the GUI for the SKU upgrade.

Hopefully this information will help someone else…

RD

Advertisements

Run all SharePoint Health Analyzer Jobs with PowerShell


Today I had a need to run all health analyzer jobs to make sure everything was good after a clean install of SharePoint 2010. Of course I knew there had to be a quick PowerShell approach to this. I did a quick search and found a few different variations of the same basic code, so I took what I liked and made it into a simple function that I will store in the profile on my SP machines going forward.

The blog that had exactly what I wanted, both in the body and the comments was Matthew McDermott’s blog – here. Matthew has a more structured approach using a foreach loop to iterate through each job in the collection, and then he calls the RunNow() method to start the jobs. Gary LaPointe commented and provided a one-liner, which I’m going to use – although I am putting that one-liner into a function…

By making a simple function, I can just run the function like a cmdlet – so it makes it very easy to run going forward.

Here is the function:

function Start-SPHealthTimerJobs {Get-SPTimerJob | Where-Object {$_.Title -like “*Health Analysis Job*”} | Start-SPTimerJob}

And to run it, I simply type:

Start-SPHealthTimerJobs

Fix SharePoint Quick Launch Links using PowerShell


A lot of times when I’m working on an environment for a client, I come across a situation where I’m in need of a way to quickly update links – usually because people have entered them as an absolute URL (e.g. http://intranet/pages/somepage.aspx) instead of a relative URL (e.g. /pages/somepage.aspx).

Usually when I run across a problem like this, I actually get excited – because these are great opportunities to use our buddy PowerShell! Unfortunately, there aren’t many examples out there of how to use PowerShell to manipulate SharePoint Navigation objects. Hopefully this blog post will be helpful for someone looking to do the same thing I needed to do…

Here’s how it all comes together – and if you don’t want to understand how it works just skip to the end and copy/paste the code :).

Getting the Web Object

The first thing we have to do in order to even begin to work on SharePoint Navigation is to retrieve an SPWeb object. To do this, it’s pretty simple – just run the following code, which will store the Microsoft.SharePoint.SPWeb into the $SPWeb variable:

$SPWeb = Get-SPWeb $Web

Getting the Web.Navigation.QuickLaunch Object

After we’ve retrieved that object, if you use Get-Member to view the Methods and Properties, you’ll quickly notice that the Navigation Property has a QuickLaunch property within it. This is exactly what we want. We can now start to use the ForEach-Object cmdlet to actually show us everything beneath the SPWeb.Navigation.QuickLaunch. Or more specifically, we can use an IF statement to make sure we only grab the appropriate URLs – that is, only ones matching the string we want to replace. Here’s the code snippet:

$SPWeb.Navigation.QuickLaunch | ForEach-Object {
    if($_.Url -match $FindString){
        $linkUrl = $_.Url
        Write-Host "Updating $linkUrl with new URL"
        $_.Url = $_.Url.Replace($FindString,$ReplaceString)
        $_.Update()
    }

Pretty cool, so essentially we just say if the URL matches the string we’re looking for, then go ahead and tell us it’s working on it – then update it, replacing the value of the FindString variable with the value of the ReplaceString variable. Both of these variables are actually mandatory parameters, you’ll see that part at the end… Finally, run the Update() method on each one to actually commit the changes to the server.

All done right? No, we can’t forget about the children!

Fixing the Child links

So far the code we’ve seen will only touch the parent links, but each link also has a Children node. We can simply use the same code as before, except this time we’ll run it against the $_.Children property of each link node.

Here’s how that looks:

$_.Children | ForEach-Object {
        if($_.Url -match $FindString){
            $linkUrl = $_.Url
            Write-Host "Updating $linkUrl with new URL"
            $_.Url = $_.Url.Replace($FindString,$ReplaceString)
            $_.Update()
        }
    }

And now, if we put it all together, you’ll see that we have a nice, clean function to do a quick find and replace of navigation links on the quick launch of a single SharePoint Web. I’ve called the function Repair-SPLeftNavigation, and it has 3 required parameters – Web, FindString and ReplaceString:

function Repair-SPLeftNavigation {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)][System.String]$Web,
[Parameter(Mandatory=$true)][System.String]$FindString,
[Parameter(Mandatory=$true)][System.String]$ReplaceString
)
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$SPWeb = Get-SPWeb $Web
$SPWeb.Navigation.QuickLaunch | ForEach-Object {
    if($_.Url -match $FindString){
        $linkUrl = $_.Url
        Write-Host "Updating $linkUrl with new URL"
        $_.Url = $_.Url.Replace($FindString,$ReplaceString)
        $_.Update()
    }
    $_.Children | ForEach-Object {
        if($_.Url -match $FindString){
            $linkUrl = $_.Url
            Write-Host "Updating $linkUrl with new URL"
            $_.Url = $_.Url.Replace($FindString,$ReplaceString)
            $_.Update()
        }
    }
}
$SPWeb.Dispose()
}#endFunction

To run this bad boy, simply dot-source the function and then call it like a cmdlet – for example:

. .\Repair-SPLeftNavigation.ps1
Repair-SPLeftNavigation -Web http://sp2013 -FindString 'http://sp2010' -ReplaceString 'http://sp2013'

If you needed to run this on multiple site collections or even web applications, you could simply use the native ForEach-Object cmdlet in conjunction with this function to accomplish that goal.

Cheers!
RD

SharePoint Saturday Austin 2013


Today I spoke in front of a great crowd at SharePoint Saturday Austin, which was an all-around blast!

The presentation was about PowerShell (shocker, right?) – but this time had a different vibe as I modified one of my presentations to work in SharePoint 2013 – and I also utilized PowerShell Web Access in Google Chrome for 100% of the technical demonstrations.

Below is a description of the topic itself along with PowerPoint Slides and the PowerShell and XML code that was used in the demo:

The Power is in the Shell, use it wisely!

The topic: The Power is in the Shell, use it wisely!
The story: You may have heard of PowerShell, but do you know what it’s capable of? Gone are the days of long, painful STSADM batch files – we have Windows PowerShell, and it’s here to stay.Learn how you can use Windows PowerShell both to perform simple one-off tasks as well as complex, bulk operations. Leveraging the Object Model gives Administrators and Developers the ability to do in a few lines of code what would’ve taken a lot more work (and probably a Developer or two) in the WSS platform.

In this demo filled session, you’ll see how you can get started with PowerShell, and you will hopefully leave with not only a greater understanding of what PowerShell is – but what it is capable of and how you can start using it to automate tasks in your SharePoint 2010 or 2013 environment.

Here are my slides, and below are the code snippets:

PowerShell code:

Demo 1

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$Template = Get-SPWebTemplate BLANKINTERNETCONTAINER`#0
$Url = "http://sp2013.spsatx.adventureworks.com"
$Site = Get-SPSite $Url
$Site = New-SPSite $Url -OwnerAlias adventureworks\rdennis -Template $Template
$Web = $Site.RootWeb
$web | Get-Member -MemberType property</em></em></em>
$Web.Title = "SharePoint Saturday - Austin, TX"
$Web.Update()
$Web.Dispose()
$Site.Dispose()

Demo 2

function Set-SPWebTitle {
<#
.Synopsis
	Use Set-SPWebTitle to update the Title of a SharePoint Web.
.Description
	This function uses SharePoint Cmdlets and Object Model code to set the title property of a SharePoint Web.
.Example
	C:\PS>Set-SPWebTitle -WebUrl http://<siteUrl> -Title "New Title"
    This example updates the title of a web at http://<siteUrl> to "New Title"
.Notes
	Name: Set-SPWebTitle
	Author: Ryan Dennis
	Last Edit: 2/24/2013
.Link
	http://www.sharepointryan.com
 	http://twitter.com/SharePointRyan
.Inputs
	None
.Outputs
	None
#Requires -Version 2.0
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)][System.String]$WebUrl,
[Parameter(Mandatory=$true)][System.String]$Title
)
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$Web = Get-SPWeb $WebUrl
$Web.Title = $Title
$Web.Update()
$Web.Dispose()
}

Demo 3

function New-SPWebFromXml {
<#
.Synopsis
	Use this PowerShell Script to create lots of sites, very quickly!
.Description
	This advanced function uses Get-Content, ForEach-Object and New-SPWeb 
	cmdlets to bulk create SharePoint webs from an XML file.
.Example
	C:\PS>New-SPWebFromXml -Url http://<siteUrl> -XmlInput c:\Sites.xml
	This example creates sites from an XML located at c:\Sites.xml under a site 
	collection at http://<siteUrl>. 
.Notes
	Name: New-SPWebFromXml
	Author: Ryan Dennis
	Last Edit: 2/24/2013
	Keywords: New-SPWeb, Get-Content, ForEach-Object, New-Timespan, XML
.Link
	http://www.sharepointryan.com
 	http://twitter.com/SharePointRyan
.Inputs
	None
.Outputs
	None
#Requires -Version 2.0
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)][System.String]$Url,
[Parameter(Mandatory=$true)][System.String]$XmlInput
)
Clear-Host

# If SharePoint Snapin isn't loaded - load it #
if ((Get-PSSnapin Microsoft.SharePoint.PowerShell)-eq $null)
{
	Write-Host "Adding SharePoint Snapin"
	Add-PSSnapin Microsoft.SharePoint.PowerShell
}
$i=0
do {

# Read in list of sites from XML file #
[xml]$SitesXml = Get-Content $($XmlInput)
if ($SitesXml -eq $null) { return }

$siteCount = $SitesXml.Sites.Site.Count
Write-Progress -Activity "Provisioning SharePoint Webs from XML" -PercentComplete (($i/$siteCount) * 100) `
-Status "Retrieving XML Data" -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2

Start-SPAssignment -Global

# Loop through each site node to extract data #
$SitesXml.Sites.Site | ForEach-Object {
    $SiteTitle = [string]$_.SiteTitle
	$SiteUrl = [string]$_.SiteUrl
    Write-Progress -Activity "Provisioning SharePoint Webs from XML" -PercentComplete (($i/$siteCount) * 100) `
    -Status "Creating an SPWeb at $($SiteUrl)" -ErrorAction SilentlyContinue
	$i++
	# Site specifics # 
	$WebTemplate = "BLANKINTERNET`#0"
	$LangId = "1033"
	$SiteUrl = $Url+$SiteUrl
	# Create the SPWeb #
	if ($_.create -ne "false")
	{
	$Web = New-SPWeb -Url $SiteUrl -Language $LangId -Template $WebTemplate `
	-Name $SiteTitle
	}
	else
	{
	$Web = Get-SPWeb -Identity $SiteUrl
	}
	# Get publishing site and web objects
	$site = $web.Site
	$pWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
	$pagesLib = $pWeb.PagesList

    # Enable moderation on Pages libraries #
	$pagesLib.EnableModeration = $true;
	$pagesLib.EnableMinorVersions = $true;
	$pagesLib.Update()	

	# Create all Pages using ForEach-Object #
	if ($_.Page -ne $null){
	$pages = $_.Page | ForEach-Object {
	
	# Create page content variables from XML file
	$PageTitle = [string]$_.PageTitle
	$PageUrl = [string]$_.PageUrl
	$PageLayout = [string]$_.PageLayout
	$PageContent = [string]$_.PageContent
	$PageImage = [string]$_.PageImage
	$layout = $pWeb.GetAvailablePageLayouts() | Where-Object {$_.Title -match $PageLayout}
	
    # Create blank page using Add method
	Write-Progress -Activity "Provisioning SharePoint Webs from XML" -PercentComplete (($i/$siteCount) * 100) `
    -Status "Creating $($PageTitle).aspx page" -ErrorAction SilentlyContinue
    $pages = $pWeb.GetPublishingPages($pWeb)
	$page = $pages.Add($PageUrl, $layout)
	$page.Update()
	
    # Update the filename to the one specified in the XML, add HTML content to Page Content zone
    $item = $page.ListItem
	$item["Title"] = $PageTitle;
	$item.Update()
	
   	# Check-in and publish page
    $item.File.CheckIn("")
    $item.File.Publish("")
	$item.File.Approve("")
	$file = $item.File
	# If the page is marked as the Home Page in XML, set it as welcome page #
	if($_.IsHomePage -eq "true"){
	$pWeb.DefaultPage = $file
	}
	$pWeb.Update()
	
	} #end Page Foreach
	
	} # End if block #
	
} # End ForEach-Object loop #
} while ($i -lt $siteCount)
} # End function

XML Syntax:

<?xml version="1.0" encoding="utf-8"?>
<Sites>
  <SiteAdmins>
    <User>adventureworks\rdennis</User>
    <User>adventureworks\spfarm</User>
  </SiteAdmins>
  <!-- root site -->
  <Site Create="false">
    <SiteTitle>Home</SiteTitle>
    <SiteUrl>/</SiteUrl>
		<Page IsHomePage="false">
		  <PageTitle>Intranet Governance</PageTitle>
		  <PageUrl>Intranet-Governance.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Terms of Use</PageTitle>
		  <PageUrl>Terms-of-Use.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Privacy Policy</PageTitle>
		  <PageUrl>Privacy-Policy.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Linking Policy</PageTitle>
		  <PageUrl>Linking-Policy.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Legal Disclaimer</PageTitle>
		  <PageUrl>Legal-Disclaimer.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Help Me</PageTitle>
		  <PageUrl>Help-Me.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
  </Site>
  <!-- 2nd level sites -->
  <Site>
    <SiteTitle>My Company</SiteTitle>
    <SiteUrl>/My-Company</SiteUrl>
		<Page IsHomePage="true">
		  <PageTitle>My Company</PageTitle>
		  <PageUrl>My-Company.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Our Culture</PageTitle>
		  <PageUrl>Our-Culture.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>History and Timeline</PageTitle>
		  <PageUrl>History-And-Timeline.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Sustainability</PageTitle>
		  <PageUrl>Sustainability.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>My Community</PageTitle>
		  <PageUrl>My-Community.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
  </Site>
  <Site>
    <SiteTitle>Our Customers</SiteTitle>
    <SiteUrl>/Our-Customers</SiteUrl>
		<Page IsHomePage="true">
		  <PageTitle>Our Customers</PageTitle>
		  <PageUrl>Our-Customers.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Customer Engagement</PageTitle>
		  <PageUrl>Customer-Engagement.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Employee Ambassadors</PageTitle>
		  <PageUrl>Employee-Ambassadors.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
  </Site>
  <Site>
    <SiteTitle>News and Info</SiteTitle>
    <SiteUrl>/News-And-Info</SiteUrl>
		<Page IsHomePage="false">
		  <PageTitle>Utility Performance</PageTitle>
		  <PageUrl>Utility-Performance.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>News Archive</PageTitle>
		  <PageUrl>News-Archive.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Calendar</PageTitle>
		  <PageUrl>Calendar.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Social Media</PageTitle>
		  <PageUrl>Social-Media.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
  </Site>
  <Site>
    <SiteTitle>Task Center</SiteTitle>
    <SiteUrl>/Task-Center</SiteUrl>
		<Page IsHomePage="true">
		  <PageTitle>Task Center</PageTitle>
		  <PageUrl>Task-Center.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Travel</PageTitle>
		  <PageUrl>Travel.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Toolbox</PageTitle>
		  <PageUrl>Toolbox.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Managing Employees</PageTitle>
		  <PageUrl>Managing-Employees.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
  </Site>
  <Site>
    <SiteTitle>Collaboration</SiteTitle>
    <SiteUrl>/Collaboration</SiteUrl>
		<Page IsHomePage="true">
		  <PageTitle>Collaboration</PageTitle>
		  <PageUrl>Collaboration.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Communities</PageTitle>
		  <PageUrl>Communities.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
		<Page IsHomePage="false">
		  <PageTitle>Employee Surveys</PageTitle>
		  <PageUrl>Employee-Surveys.aspx</PageUrl>
		  <PageLayout>Blank Web Part Page</PageLayout></Page>
  </Site>
</Sites>

Creating an awesome SharePoint development environment on Windows 8


I have been using Windows 8 Professional with Hyper-V for about 2 months now, and I thought I would take a few minutes to post about my setup – as I think it works very well for SharePoint development. I’m not intending to say this is the best setup, but it works well for me and I’m sure there are others who may be wanting a similar setup.

I’ll try to break the post down into chunks, as there are several pieces to this puzzle.

The Laptop

My laptop is an HP EliteBook 8570w, with 32GB RAM and i7 quad-core processors. It is running Windows 8 Professional, and I use Hyper-V for my virtualization. The beauty of this setup is with Windows 8 and Hyper-V, I can actually use things like hibernation – where in the past i would’ve used Windows Server with the Desktop Experience. While it looked like Windows 7 and in reality worked really well, the one thing missing was the ability to hibernate. In addition, there were some things that just didn’t quite work on a Server OS.

Here’s a screenshot of Task Manager, as you can see, there’s a whole bunch of RAM as well as 4 Cores and 8 Logical processors. Pretty sweet eh? 🙂

TaskManager

The Hyper-V Setup

As mentioned above, Hyper-V is my virtualization platform of choice. The VMware folks will probably have plenty of arguments for why I could have used VMware instead, but Hyper-V is free and included with the Windows 8 Professional license. It works fantastically well and I can honestly say I’ve never had an issue with it for what I need it for.

Hyper-V is pretty simple to use, and in my case I’m using it to run a few VMs for different purposes. Here is what I have running currently:

  1. Domain Controller – this is a Windows Server 2012 machine with 1GB of RAM. I’ve got a domain at AdventureWorks.com.
  2. SharePoint 2010 – this is a Windows Server 2008 R2 machine with 10GB of RAM. It is sp2010.adventureworks.com.
  3. SharePoint 2013 – this is a Windows Server 2012 machine with 12GB of RAM. It is sp2013.adventureworks.com
  4. Office Web Apps 2013 – this is a Windows Server 2012 machine with 6GB of RAM. It is owa2013.adventureworks.com

The Networking

The piece that brings all of this together is networking. Since I am running this on a laptop with Windows 8 as my host operating system, it is important that my host have access to the internet. However, it’s also critical that my host can access each of my VMs without issues. Luckily, Hyper-V has a great solution to that problem.

Internal Network

Windows Hyper-V has a Virtual Switch Manager which allows for easy configuration of networking for your virtual machines. In my environment I have what I consider to be a fairly simple setup. I’m sure you can do some pretty complex networking, but I simply didn’t need to.

My requirements were:

  1. My host must be able to access all VMs
  2. My VMs must all be able to access each other
  3. My VMs must all be able to access the web

With those requirements in mind, here’s how my Internal Network is configured:

Host

My host is using 10.0.10.100 as its IP address. Notice I’m using 10.0.10.1 as the DNS IP address, that’s the IP of my Domain Controller – which means I can use name resolution from my DC…

nic1

Domain Controller

My domain controller using 10.0.10.1 as its IP address, with itself as the DNS Server…

nic2

Other VMs

The other VMs all have IP addresses starting at 10.0.10.2 and up, and all of them use 10.0.10.1 (DC) as their DNS server. They are all joined to my AdventureWorks.com domain.

nic3

Hyper-V

Hyper-V networking is very simple for an Internal network, in fact it’s as simple as creating a new Virtual Switch using the type Internal. That’s it:

switchmgrInternal

External Network

The External Network is pretty simple as well, it’s just bound to my physical wireless adapter – which allows all VMs to get a dynamic IP address from my wireless adapter. This allows them to access the internet for browsing, downloads, etc.

switchmgrExternal

Putting it all together

Now that I’ve shown how the networking all works, let’s summarize. Using this setup allows me to run multiple environments with a single domain controller, and since I’m using domain-joined machines with a DNS server, I can setup networking as close as possible to a “real-world” scenario. Additionally, I’ve got adequate system resources to run SharePoint 2013 with Office Web Apps, so I can actually use search with document previews, I can do user profile synchronization with ADDS, etc.

Also, since networking from the host works as well – I can access all of my SharePoint sites from my favorite browser on my Windows 8 host, which includes PowerShell Web Access on my 2013 box. Here’s my 2010 Team site from Google Chrome:

MyTeamSiteFromTheHost