How to Install and Configure SharePoint using Windows Powershell

Summary:

Several sites already explain how to install and configure SharePoint using Windows PowerShell (see "Related Articles"). But anyone wanting to customize their environment or learn PowerShell will benefit from separately installing SharePoint, its application pools, its service applications, etc.

Requirements:

  • Three servers (ours are virtualized) running Windows Server 2008 R2: A database server with SQL Server 2008 R2, a "primary" application server, and secondary application server(s).
  • SPModule extracted to the desktop of each application server. Download SPModule.
  • SharePoint installation folder on the desktop of each application server. Download a trial version of SharePoint.
  • Office Web Apps extracted to the desktop of each application server. Download Office Web Apps. (Sorry, but you'll need an MSDN subscription)
  • Cumulative Updates, saved to the desktop of each application server. Check for the most recent cumulative update. As of this posting the most recent CU is October 2011 (Caution: Test your CUs thoroughly before using in production and only install these if you need a particular fix. I assume if you're following these steps, you're working from scratch in a development environment anyway):
    1. Download SharePoint Foundation 2010 Cumulative update (but don't install it yet).
    2. Download SharePoint Server 2010 Cumulative update (don't install it yet).
  • An alias from the App servers to the database server. Ideally, you'll also change the port SQL is listening on. Our alias is called "SharePoint_alias". Instructions for setting up an alias are here.
  • Hotfixes not included in your Cumulative Updates. Any Hotfixes that were previously part of this process are included in the October Cumulative Update.
  • Finally, you must be logged into both/all application servers as "SP-SETUP" (a domain account that must be a local administrator on all app servers that you plan to install SharePoint onto). Also, "SP-SETUP" (sometimes people name it "SP-ADMIN") must have the following "Login roles" on the DB Server (set these via SQL Management Studio): dbcreator, public, and securityadmin.

Preparation: Set up application server desktops

Having downloaded everything... make sure the desktop of each app server looks like this image:

Preview of desktop prior to install

Must have SharePoint, Office Web Apps, SPModule, and Cumulative Updates downloaded to the desktop

Step-by-step SharePoint Install

Install SharePoint: Run on the main Application Servers

Run this script in Windows Powershell as an administrator, and on all application servers.

# Click "Run" right away, then again at about 25 seconds, then wait about 7.5 min
Start-Transcript
Set-ExecutionPolicy unrestricted -Force # answer Y
$spmodlocation = "C:\Users\SP-SETUP\Desktop\SPModule;"
$env:PSModulePath = $env:PSModulePath + ";$spmodlocation"
Import-Module SPModule.misc
Import-Module SPModule.setup
Install-SharePoint -SetupExePath "C:\Users\SP-SETUP\Desktop\en_sharepoint_server_2010_x64_dvd_518634\setup.exe" -PIDKey "PIDKY-PIDKY-PIDKY-PIDKY-PIDKY"

Create Configuration Database: Run only on the main Application Server

Run this script in Windows Powershell as an administrator.

  # use SP-farm account credentials
  Add-PSSnapin Microsoft.SharePoint.Powershell
  $username = 'DOMAIN\SP-FARM'
  $password = 'Passw0rd!'
  $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
  $cred = New-Object System.Management.Automation.PsCredential $username,$password
  New-SPConfigurationDatabase -DatabaseName "SP2010_Config" -DatabaseServer SharePoint_Alias -AdministrationContentDatabaseName "SP2010_CentralAdmin" -Passphrase (ConvertTo-SecureString "FarmAcctPassw0rd!" -AsPlainText -force) -FarmCredentials $cred
  Install-SPHelpCollection -All
  Initialize-SPResourceSecurity
  Install-SPService
  Install-SPFeature -AllExistingFeatures
  New-SPCentralAdministration -Port 8080 -WindowsAuthProvider "NTLM"
  Install-SPApplicationContent
  # Set-SPDiagnosticConfig -LogLocation "C:\Logs"

Join other servers to the farm: Run on all other Application Servers

Run this script in Windows Powershell as an administrator, and on all other application servers.

  Add-PSSnapin Microsoft.SharePoint.Powershell
  $spmodlocation = "C:\Users\SP-SETUP\Desktop\SPModule;"
  $env:PSModulePath = $env:PSModulePath + ";$spmodlocation"
  Import-Module SPModule.misc
  Import-Module SPModule.setup
  Join-SharePointFarm -DatabaseServer SharePoint_Alias -ConfigurationDatabaseName SP2010_Config
  # Set-SPDiagnosticConfig -LogLocation "C:\Logs"

Create Managed Accounts:

You will need to add these accounts to active directory first. Run this script in Windows Powershell as an administrator.

    $username = 'DOMAIN\SP-MSAP'
    $password = 'Passw0rd!'
    # My Sites application pool account
    # Service application account. The My Sites application pool account must be a domain user account. This account must not be a member of the farm administrators group. The following machine-level permission is configured automatically: This account is a member of WSS_WPG. The following SQL Server and database permissions are configured automatically: This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database.http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-FSS'
    $password = 'Passw0rd!'
    # Foundation 2010 search service account
    # Administrative Account. The SharePoint Foundation 2010 search service account is used as the service account for the SharePoint Foundation 2010 Search service. The SharePoint Foundation 2010 search service account requires the following permission configuration settings: This account must have domain user account permissions. The following machine-level permission is configured automatically: The search service account is a member of WSS_WPG. The following SQL Server and database permissions are conferred by membership in the WSS_CONTENT_APPLICATION_POOLS role in the server farm configuration database: Read access to the server farm configuration database. Read access to the SharePoint_Admin content database. This account is assigned the db_owner role for the SharePoint Foundation 2010 search database.http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-FSCA'
    $password = 'Passw0rd!'
    # Foundation 2010 search content access account
    # The SharePoint Foundation 2010 search content access account is used by the SharePoint Foundation 2010 Search service to crawl content across sites. The SharePoint Foundation 2010 search content access account requires the following permission configuration settings: This account must have domain user account permissions. This account must not be a member of the farm administrators group. The following SQL Server and database permissions are configured automatically: Read access to the server farm configuration database. Read access to the SharePoint_Admin content database. This account is assigned to the db_owner role for the SharePoint Foundation 2010 search database. A full Read policy for the SharePoint Foundation 2010 search content access account is created on all Web applications.http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-AP'
    $password = 'Passw0rd!'
    # Application pool account
    # Service application account. The application pool account is used for application pool identity. The application pool account requires the following permission configuration settings: The following machine-level permission is configured automatically: The application pool account is a member of WSS_WPG. The following SQL Server and database permissions for this account are configured automatically: The application pool accounts for Web applications are assigned to the db_owner role for the content databases. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database.http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-DCA'
    $password = 'Passw0rd!'
    # Web front end application pool account
    # Service application account. The application pool account is used for application pool identity. The application pool account requires the following permission configuration settings: The following machine-level permission is configured automatically: The application pool account is a member of WSS_WPG. The following SQL Server and database permissions for this account are configured automatically: The application pool accounts for Web applications are assigned to the db_owner role for the content databases. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database.http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-WFEAP'
    $password = 'Passw0rd!'
    # Default content access account
    # Service application account. The default content access account is used within a specific service application to crawl content, unless a different authentication method is specified by a crawl rule for a URL or URL pattern. This account requires the following permission configuration settings: The default content access account must be a domain user account and it must have read access to external or secure content sources that you want to crawl by using this account. For SharePoint Server sites that are not part of the server farm, this account must be explicitly granted full read permissions to the Web applications that host the sites. This account must not be a member of the farm administrators group.http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-CA'
    $password = 'Passw0rd!'
    # Content access accounts
    # Service application account. Content access accounts are accounts that are configured to access content by using the Search administration crawl rules feature. This type of account is optional and can be configured when you create a new crawl rule. For example, external content (such as a file share) might require this separate content access account. This account requires the following permission configuration settings: The content access account must have read access to external or secure content sources that this account is configured to access. For SharePoint Server sites that are not part of the server farm, this account must be explicitly granted full read permissions to the Web applications that host the sites. http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-Excel'
    $password = 'Passw0rd!'
    # Excel Services unattended service account
    # Service application account. The Excel Services unattended service account is used by Excel Services to connect to external data sources that require a user name and password that are based on operating systems other than Windows for authentication. If this account is not configured, Excel Services will not attempt to connect to these types of data sources. Although account credentials are used to connect to data sources of operating systems other than Windows, if the account is not a member of the domain, Excel Services cannot access it. This account must be a domain user account.http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-SS'
    $password = 'Passw0rd!'
    # SharePoint Server search service account
    # Service application account. The SharePoint Server 2010 Search service account is used as the service account for the SharePoint Server 2010 Search service. The SharePoint Server Search Service is an NT Service, which is used by all Search Service Applications. For any given server, there is only one instance of this service. The SharePoint Server 2010 search service account requires the following permission configuration setting: The SharePoint Server 2010 search service account is granted access to the propagation location share (or shares) on all search query servers in a farm. The following machine-level permission is configured automatically: The SharePoint Server 2010 search service account is a member of WSS_WPG. The following SQL Server and database permissions are configured automatically: This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database.http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-MMAP'
    $password = 'Passw0rd!'
    # Managed Metadata application pool account
    # Service application account. This is an "other" application pool account. It must be a domain user account. This account must not be a member of the administrators group on any computer in the server farm. The following machine-level permission is configured automatically: This account is a member of WSS_WPG. The following SQL Server and database permissions are configured automatically: This account is assigned to the db_owner role for the content databases. This account is assigned to the db_owner role for search databases associated with the Web application. This account must have read and write access to the associated service application database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database.http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-SSAP'
    $password = 'Passw0rd!'
    # Search Service application pool account
    # Service application account. This is an "other" application pool account. It must be a domain user account. This account must not be a member of the administrators group on any computer in the server farm. The following machine-level permission is configured automatically: This account is a member of WSS_WPG. The following SQL Server and database permissions are configured automatically: This account is assigned to the db_owner role for the content databases. This account is assigned to the db_owner role for search databases associated with the Web application. This account must have read and write access to the associated service application database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database.http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-INAP'
    $password = 'Passw0rd!'
    # Intranet application pool account
    # Service application account. This is an "other" application pool account. It must be a domain user account. This account must not be a member of the administrators group on any computer in the server farm. The following machine-level permission is configured automatically: This account is a member of WSS_WPG. The following SQL Server and database permissions are configured automatically: This account is assigned to the db_owner role for the content databases. This account is assigned to the db_owner role for search databases associated with the Web application. This account must have read and write access to the associated service application database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database. http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-UPSAP'
    $password = 'Passw0rd!'
    # User Profile Service application pool account
    # Service application account. This is an "other" application pool account. It must be a domain user account. This account must not be a member of the administrators group on any computer in the server farm. The following machine-level permission is configured automatically: This account is a member of WSS_WPG. The following SQL Server and database permissions are configured automatically: This account is assigned to the db_owner role for the content databases. This account is assigned to the db_owner role for search databases associated with the Web application. This account must have read and write access to the associated service application database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database. http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-UPS'
    $password = 'Passw0rd!'
    # User Profile Service account
    # Service application account. Made this up. Will NOT find a reference to it here: http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2 It must be a domain user account. This account must not be a member of the administrators group on any computer in the server farm. The following machine-level permission is configured automatically: This account is a member of WSS_WPG. The following SQL Server and database permissions are configured automatically: This account is assigned to the db_owner role for the content databases. This account is assigned to the db_owner role for search databases associated with the Web application. This account must have read and write access to the associated service application database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database.
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-OWAAP'
    $password = 'Passw0rd!'
    # Office Web Apps Application Pool account
    # Service application account. This is an "other" application pool account. It must be a domain user account. This account must not be a member of the administrators group on any computer in the server farm. The following machine-level permission is configured automatically: This account is a member of WSS_WPG. The following SQL Server and database permissions are configured automatically: This account is assigned to the db_owner role for the content databases. This account is assigned to the db_owner role for search databases associated with the Web application. This account must have read and write access to the associated service application database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database. http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred
    $username = 'DOMAIN\SP-DSAP'
    $password = 'Passw0rd!'
    # Default Services Application Pool account
    # Service application account. This is an "other" application pool account. It must be a domain user account. This account must not be a member of the administrators group on any computer in the server farm. The following machine-level permission is configured automatically: This account is a member of WSS_WPG. The following SQL Server and database permissions are configured automatically: This account is assigned to the db_owner role for the content databases. This account is assigned to the db_owner role for search databases associated with the Web application. This account must have read and write access to the associated service application database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the farm configuration database. This account is assigned to the WSS_CONTENT_APPLICATION_POOLS role associated with the SharePoint_Admin content database. http://technet.microsoft.com/en-us/library/cc678863.aspx# Section2
    $password = (ConvertTo-SecureString -String "$password" -AsPlainText -force)
    $cred = New-Object System.Management.Automation.PsCredential $username,$password
    New-SPManagedAccount –Credential $cred

Create Web Applications

We're creating three: one for our web front-end applications, one for MySites, and one for the company intranet.

"SharePoint Front End Web Application" Web Application and Application Pool

New-SPWebApplication -Name "SharePoint Front End Web Application" -Port 81 -URL "http://www.contoso.com" -ApplicationPool "SharePoint Sites Application Pool" -ApplicationPoolAccount "DOMAIN\SP-AP" -DatabaseName "SP2010_ContentDB_Frontend"

"SharePoint Intranet Web Application" Web Application and Application Pool

#STOP: there are a few options below. Review each first. #Note: this one sets up the Intranet web app with classic authentication, no SSL (http) New-SPWebApplication -Name "SharePoint Intranet Web Application" -Port 82 -URL "http://www.contoso.com" -ApplicationPool "SharePoint Intranet Application Pool" -ApplicationPoolAccount "DOMAIN\SP-INAP" -DatabaseName "SP2010_ContentDB_Intranet" #Note: this one sets up the Intranet web app with claims based authentication, but no SSL (http) See http://blogs.technet.com/b/speschka/archive/2009/11/05/configuring-forms-based-authentication-in-sharepoint-2010.aspx $ap = New-SPAuthenticationProvider –UseWindowsIntegratedAuthentication –DisableKerberos
 New-SPWebApplication -Name "SharePoint Intranet Web Application" -Port 82 -HostHeader "servername1" –AuthenticationProvider $ap -URL "http://servername1" -ApplicationPool "SharePoint Intranet Application Pool" –ApplicationPoolAccount (Get-SPManagedAccount "DOMAIN\SP-INAP") -DatabaseName "SP2010_ContentDB_Intranet" #Note: this one sets up the Intranet web app with claims based authentication with SSL (https) See: http://www.sharepointpromag.com/article/sharepoint/power-trip-powershell-bug-and-claims... also... http://blogs.msdn.com/b/sowmyancs/archive/2010/02/12/how-to-enable-ssl-on-a-sharepoint-web-application.aspx...also...http://sharepoint.microsoft.com/blog/Pages/BlogPost.aspx?PageType=4&ListId=%7B72C1C85B-1D2D-4A4A-90DE-CA74A7808184%7D&pID=804 $ap = New-SPAuthenticationProvider –UseWindowsIntegratedAuthentication –DisableKerberos

New-SPWebApplication -Name "SharePoint Intranet Web Application" -Port 445 -HostHeader "servername1" –AuthenticationProvider $ap –SecureSocketsLayer -URL "https://servername1" -ApplicationPool "SharePoint Intranet Application Pool" –ApplicationPoolAccount (Get-SPManagedAccount "DOMAIN\SP-INAP") -DatabaseName "SP2010_ContentDB_Intranet"

"SharePoint My Sites Web Application" Web Application and Application Pool

# http://sharepointgeorge.com/2010/configuring-my-site-sharepoint-2010/
New-SPWebApplication -Name "SharePoint MySites Web Application" -Port 83 -URL "http://www.contoso.com" -ApplicationPool "SharePoint MySites Application Pool" -ApplicationPoolAccount "DOMAIN\SP-MSAP" -DatabaseName "SP2010_ContentDB_MySites"

Get Web Applications

Get-SPWebApplication

Create Application Pools

How many application pools should you create? Which accounts should you assign to the application pools? Check Harbar.net: More on SharePoint Application pools to see what the application pools look like after a default SharePoint install (i.e., one configured with the "Farm Configuration Wizard"). It will help you choose which service accounts to use and what application pools to create. I'm using several pools. In most small or medium environments, they can share one. Run this script in Windows Powershell as an administrator.

# Create "SharePoint Office Web Apps Application Pool" Application Pool

# Does OWA need its own application pool? Should this be the sharepoint owa services pool?
New-SPServiceApplicationPool -Name "SharePoint Office Web Apps Application Pool" -Account "DOMAIN\SP-OWAAP"

# Create "SharePoint Managed Metadata Application Pool" Application Pool

# Suggests a separate app pool: http://thuansoldier.net/?p=812
# Sharepoint George uses the farm account for this
New-SPServiceApplicationPool -Name "SharePoint Managed Metadata Application Pool" -Account "DOMAIN\SP-MMAP"

Create "SharePoint User Profiles Application Pool" Application Pool

# Troubleshoot: http://technet.microsoft.com/en-us/library/gg750257.aspx# farmAcct
New-SPServiceApplicationPool -Name "SharePoint User Profiles Application Pool" -Account "DOMAIN\SP-UPSAP"

# Create "SharePoint Web Services Default Application Pool" Application Pool

# Does OWA need its own application pool? Should this be the sharepoint owa services pool?
New-SPServiceApplicationPool -Name "SharePoint Web Services Default Application Pool" -Account "DOMAIN\SP-DSAP"

# Get Application Pools

Get-SPServiceApplicationPool

Set up Office Web Apps

Related:

Office Web Apps (OWA) allows you to work on Excel, PowerPoint, and Word files in a browser. This requires cache, which is stored inside a special OWA site collection called "Office_Viewing_Service_Cache." A cron job automatically creates it inside each Web Application in your farm. But here's the thing: look for that site collection and you'll see that it shares its content database with every other site collection in the Web Application. That's right: inside any Web Application, Team sites, publishing sites, and OWA will, by default, share the same content database.

As you continue reading, keep in mind that Microsoft discourages letting content databases get larger than 200 GB and that OWA Cache can be very large — up to 100 GB. Also, since it's cache, it doesn't contain anything that can't be lost. So that's potentially 100GB of space on your content database that's being unnecessarily used (and unnecessarily backed up). Given that this potentially eats up half of your allotted space on the content database, it is best to separate out OWA and give it its own content database. That way, you can exclude it from backups and forever ignore it. And as long as we're doing that, we might was well put it in its own, separate managed path. Therefore, the basic steps are to:

  1. Remove all existing managed paths inside each web application (e.g., "/sites")
  2. Add new managed paths (e.g., "/owa/cache")
  3. Install OWA
  4. Turn OWA on (on each server)
  5. Wait 5 minutes for the cron jobs to run and install "Office_Viewing_Service_Cache"
  6. Create new content databases for OWA cache and Link "Office_Viewing_Service_Cache" sites collections to those new content database
  7. Re-create managed paths (e.g. "/sites") (this is done in the next section, after iisrestart and other stuff)

Remove all existing managed paths

The code snippet below removes the "/sites" managed path on each Web Application. If we don't do this, Office Web Apps — once installed — will automatically install site collections there (one on each Web Application). Run these scripts in Windows Powershell as an administrator. (I've separated them because they require user input.)

# Note: read this post about creating managed paths and about how many site collections to have. http://www.mssharepointtips.com/tip.asp?id=1048
# SharePoint Front End Web Application
remove-spmanagedpath "sites" -webapplication "SharePoint Front End Web Application"
# Note: read this post about creating managed paths and about how many site collections to have. http://www.mssharepointtips.com/tip.asp?id=1048
# SharePoint Intranet Web Application
remove-spmanagedpath "sites" -webapplication "SharePoint Intranet Web Application"
# Note: read this post about creating managed paths and about how many site collections to have. http://www.mssharepointtips.com/tip.asp?id=1048
# SharePoint MySites Web Application
remove-spmanagedpath "sites" -webapplication "SharePoint MySites Web Application"

Add new managed paths

Let's give OWA a new path to use: "/owa/cache". Run this script in Windows Powershell as an administrator.

# SharePoint Front End Web Application
New-SPManagedPath "sps" -explicit -webapplication "SharePoint Front End Web Application"
New-SPManagedPath "sps/cache" -webapplication "SharePoint Front End Web Application"
# SharePoint Intranet Web Application
New-SPManagedPath "sps" -explicit -webapplication "SharePoint Intranet Web Application"
New-SPManagedPath "sps/cache" -webapplication "SharePoint Intranet Web Application"
# SharePoint MySites Web Application
New-SPManagedPath "sps" -explicit -webapplication "SharePoint MySites Web Application"
New-SPManagedPath "sps/cache" -webapplication "SharePoint MySites Web Application"

Install OWA: You'll need the PIDKY-PIDKY-PIDKY-PIDKY-PIDKY

Just use the installer on the desktop and when it's done, run the PSConfig script. That is necessary. Repeat both the install and the PSConfig script on every 'application' (not db) server in the farm. Say "Yes" when it asks if you want to make SP better. Cancel when it prompts you to run the farm configuration wizard.

# Install OWA manually by running Setup from your desktop

Turn OWA on

$machinesToActivate = @("app1.contoso.com", "app2.contoso.com")
$serviceInstanceNames = @("Word Viewing Service","PowerPoint Service","Excel Calculation Services")
foreach ($machine in $machinesToActivate) {
foreach ($serviceInstance in $serviceInstanceNames) {
$serviceID = $(Get-SPServiceInstance | where {$_.TypeName -match $serviceInstance} | where {$_.Server -match "SPServer Name="+$machine}).ID
Start-SPServiceInstance -Identity $serviceID
}
}
New-SPWordViewingServiceApplication -Name "SP2010 Word Viewing Service" -ApplicationPool "SharePoint Office Web Apps Application Pool" | New-SPWordViewingServiceApplicationProxy -Name "SP2010 Word Viewing Service Proxy"
New-SPPowerPointServiceApplication -Name "SP2010 PowerPoint Service" -ApplicationPool "SharePoint Office Web Apps Application Pool" | New-SPPowerPointServiceApplicationProxy -Name "SP2010 PowerPoint Service Proxy"  -AddToDefaultGroup
New-SPExcelServiceApplication -Name "SP2010 Excel Calculation Services" -ApplicationPool "SharePoint Office Web Apps Application Pool"
# Run these commands if you get an error trying to open PowerPoint
# Get-SPPowerPointServiceApplicationProxy | Remove-SPPowerPointServiceApplicationProxy -confirm
# Get-SPPowerPointServiceApplication |  New-SPPowerPointServiceApplicationProxy -Name "SP2010 PowerPoint Service Proxy" -AddToDefaultGroup

Wait 5 minutes

During this time, a SharePoint cron job runs. It automatically creates a site collection for Office Web Apps. This site collection is created in the first place that it finds a wildcard managed path (that is, a non-explicit path). Since we deleted all the managed paths in each web application and left only "/owa/cache", the cron job is forced to put its site collection inside that path. (Comment 79 discusses this.) To see when the OWA Site Collection has been created, go to http://www.contoso.com/_admin/SiteCollections.aspx. You will know the cron job has done its thing when you see "/sps/cache/Office_Viewing_Service_Cache" in the list. Click on it. Off to the right you will see it is using the default content database. We'll need to change that in the next step.

Create new content databases for OWA cache

Here's what this script does:

  1. It cycles through each Web Application in your farm
  2. It comes up with a name for the new content database: "SP2010_OWACache_WebApplicationNameWithoutSpaces"
  3. It checks whether a content database by that name already exists
    • if a content database for the cache already exists, it moves the cache to that content database;
    • If one does not exist, it creates a new content database

This script has been changed so that it loops through and makes this change on each Web Application (here's a version that runs only on a URL you specify). Be sure to save this to C:\Scripts (say as "C:\Scripts\OWAConfigCache.ps1") and then run it from Powershell ISE as an administrator. E.g., from the prompt, PS C:\Scripts > .\OWAConfigCache.ps1

  # http://blogs.technet.com/b/wbaer/archive/2010/09/01/the-office-web-applications-cache.aspx
  # http://blogs.msdn.com/b/jjameson/archive/2011/03/03/installing-and-configuring-office-web-apps-on-sharepoint-2010.aspx
  $ErrorActionPreference = "Stop"
  Add-PSSnapin Microsoft.SharePoint.PowerShell -EA 0
  function ConfigureOfficeWebAppsCache(
  [string] $webAppUrl,
  [int] $cacheSizeInGigabytes,
  [int] $expirationPeriodInDays,
  [string] $cacheDatabaseName)
  {
  Write-Host ("Configuring Office Web Apps cache for Web application" `
  + " ($webAppUrl)...")
  Write-Debug "cacheSizeInGigabytes: $cacheSizeInGigabytes"
  Write-Debug "expirationPeriodInDays: $expirationPeriodInDays"
  Write-Debug "cacheDatabaseName: $cacheDatabaseName"
  $cacheSizeInBytes = $cacheSizeInGigabytes * 1024 * 1024 * 1024
  $webApp = Get-SPWebApplication –Identity $webAppUrl -Debug:$false
  $webApp | Set-SPOfficeWebAppsCache `
  -ExpirationPeriodInDays $expirationPeriodInDays `
  -MaxSizeInBytes $cacheSizeInBytes -Debug:$false
  $cacheDatabase = Get-SPContentDatabase $cacheDatabaseName -Debug:$false -EA 0
  if ($cacheDatabase -eq $null)
  {
  $cacheDatabase = New-SPContentDatabase -Name $cacheDatabaseName `
  -WebApplication $webApp -Debug:$false
  }
  Get-SPOfficeWebAppsCache -WebApplication $webapp -Debug:$false |
  Move-SPSite -DestinationDatabase $cacheDatabase -Confirm:$false `
  -Debug:$false
  Write-Host "Restricting the cache database to a single site collection..."
  $database = Get-SPContentDatabase $cacheDatabase
  $database.MaximumSiteCount = 1
  $database.WarningSiteCount = 0
  $database.Update()
  Write-Host -Fore Green ("Successfully configured Office Web Apps cache for" `
  + " Web application ($webAppUrl).")
  }
  function Main(
  [string] $webAppUrl,
  [string] $cacheDatabaseName)
  {
  $cacheSizeInGigabytes = 10
  $expirationPeriodInDays = 14
  ConfigureOfficeWebAppsCache $webAppUrl $cacheSizeInGigabytes $expirationPeriodInDays $cacheDatabaseName
  }
  $SPWebApplications = Get-SPWebApplication
  foreach ($WebAppName in $SPWebApplications) {
  $webAppUrl = $WebAppName.Url
  $wa = $WebAppName.DisplayName
  $wa = [regex]::replace($wa, " ","")
  $wa = [regex]::replace($wa, "-","_")
  $cacheDatabaseName = "SP2010_OWACache_{0}" -f "$wa"
  Main $webAppUrl $cacheDatabaseName
  }

Grant the office web apps service account access to content databases

Set-ExecutionPolicy unrestricted -Force # answer Y
Add-PSSnapin Microsoft.SharePoint.Powershell
$webApp = Get-SPWebApplication "http://www.contoso.com"
$webApp.GrantAccessToProcessIdentity("DOMAIN\SP-OWAAP")
$webApp = Get-SPWebApplication "http://www.contoso.com:8888"
$webApp.GrantAccessToProcessIdentity("DOMAIN\SP-OWAAP")
$webApp = Get-SPWebApplication "http://www.contoso.com:8088"
$webApp.GrantAccessToProcessIdentity("DOMAIN\SP-OWAAP")

# iisreset

iisreset

Install Cumulative Updates and Required Hotfixes

Cumulative Updates

Check for the most recent cumulative update and install whatever version is appropriate. As of this posting the most recent CU is October 2011. Note: "Always install SharePoint Foundation 2010 patches before you install SharePoint Server 2010 patches. " And don't get clever trying to install one right after the other without restarting or running PSConfig. This might ruin your installation. (I just did this. I restarted, but did not run PSConfig, between installing Foundation CU and SharePoint CU. It worked out Ok.) Install Foundation CU. Restart. Rinse and repeat on all other app servers. Run PSConfig. Install SharePoint CU. Restart. Rinse and repeat on all other app servers. Run PSConfig.

  1. Download SharePoint Foundation 2010 Cumulative update (Install this first)
  2. Download SharePoint Server 2010 Cumulative update (Install this second)
# Install Foundation CU.
# Restart.
# Rinse and repeat on all other app servers.
# Run PSConfig.
# Install SharePoint CU.
# Restart.
# Rinse and repeat on all other app servers.
# Run PSConfig.

Hotfixes

Check that required Hotfixes were installed as part of the CU; if not, install them now. Any Hotfixes that were previously part of this process are included in the October Cumulative Update.

Create Managed Paths

At this point, you will probably want to think about your environment and whether it will use managed paths or host-names. Here are two Technet articles to help you (a) plan for host-named site collections (SharePoint Server 2010) and (b) define managed paths(SharePoint Server 2010). Run this script in Windows Powershell as an administrator.

Get managed Paths

Get-SPManagedPath -WebApplication "http://app1.contoso.com/"
Get-SPManagedPath -WebApplication "http://app1.contoso.com:8888"
Get-SPManagedPath -WebApplication "http://app1.contoso.com:8088"

Create Default Managed Paths (Basically, add the "/sites" path that we took out before)

New-SPManagedPath "sps/offices" -explicit -webapplication "SharePoint Front End Web Application"
New-SPManagedPath "sps/offices/myit" -webapplication "SharePoint Front End Web Application"
New-SPManagedPath "sps/departments" -explicit -webapplication "SharePoint Front End Web Application"
New-SPManagedPath "sps/departments/business" -webapplication "SharePoint Front End Web Application"
New-SPManagedPath "sps/offices" -explicit -webapplication "SharePoint Intranet Web Application"
New-SPManagedPath "sps/offices/myit" -webapplication "SharePoint Intranet Web Application"
New-SPManagedPath "sps/departments" -explicit -webapplication "SharePoint Intranet Web Application"
New-SPManagedPath "sps/departments/business" -webapplication "SharePoint Intranet Web Application"
New-SPManagedPath "sps/personal" -webapplication "SharePoint MySites Web Application"

Remove Managed Paths (if necessary)

# remove-spmanagedpath "sps/offices" -webapplication "SharePoint Front End Web Application"
# remove-spmanagedpath "sps/offices" -webapplication "SharePoint Intranet Web Application"
# remove-spmanagedpath "sps/offices" -webapplication "SharePoint MySites Web Application"

Install Service Applications

Create Managed Metadata Service Application

$YourFarmsName = "SP2010"
$appPoolName = "SharePoint Managed Metadata Application Pool"
$dbName = $YourFarmsName + "_ManagedMetadataService"
$MetaDataServiceApp = New-SPMetadataServiceApplication -Name "$YourFarmsName Managed Metadata Service" -ApplicationPool $appPoolName -DatabaseName $dbName
$MetaDataServiceAppProxy = New-SPMetadataServiceApplicationProxy -Name "$YourFarmsName Managed Metadata Service Proxy" -ServiceApplication $MetaDataServiceApp -DefaultProxyGroup

Start Managed Metadata Services

Thanks to Eric Schrader for code:

$mmserviceID = $(Get-SPServiceInstance | where {$_.TypeName -ilike "Managed Metadata Web Service"} | where {$_.Server -match "SPServer Name=app1.contoso.com"}).ID
Start-SPServiceInstance $mmserviceID

Usage and Health

Set-ExecutionPolicy unrestricted -Force # answer Y
Write-Host -ForegroundColor Yellow "Installing Usage and Health Data Collection Service…"
$FarmName = "SP2010"
$dbName = $FarmName + "_UsageandHealthDataCollectionService"
New-SPUsageApplication -Name "$FarmName Usage and Health Data Collection Service" -DatabaseName $dbName
$usageApplicationProxy = Get-SPServiceApplicationProxy | where{$_.Name -eq "$FarmName Usage and Health Data Collection Service"}
$usageApplicationProxy.provision()
if($usageApplicationProxy.Status -eq "Disabled") { $usageApplicationProxy.Status = "Online"; $usageApplicationProxy.Update(); }

Start Search Service Instance

This code is lifted pretty much directly. I recommend installing it line-by-line to address possible errors. One error I get is that write-host $QueryTopo.State returns "Inactive." Update: It returns "Inactive" because it fails: "Another topology activation is in progress. Please wait until it is finished and try again." Simply wait 10 minutes and try that line (line 10) again.

# 1. Setting up some initial variables.
$SSAName = "SP2010 Search Service Application"
$SSAAppPool = "SharePoint Search Service Application Pool"
$SVCAcct = "DOMAIN\SP-SSAP"
$SSI = get-spenterprisesearchserviceinstance -local
$err = $null
# Start Services search services for SSI
Start-SPEnterpriseSearchServiceInstance -Identity $SSI
# 2. Create an Application Pool.
$AppPool = new-SPServiceApplicationPool -name $SSAAppPool -account $SVCAcct
# 3. Create the SearchApplication and set it to a variable
$SearchApp = New-SPEnterpriseSearchServiceApplication -Name $SSAName -applicationpool $AppPool -databasename "SP2010_SearchServiceAdminDB"
# 4. Create search service application proxy
$SSAProxy = new-spenterprisesearchserviceapplicationproxy -name $SSAName" Proxy" -Uri $SearchApp.Uri.AbsoluteURI
# 5. Provision Search Admin Component.
set-SPenterprisesearchadministrationcomponent -searchapplication "$SSAName"  -searchserviceinstance $SSI
# 6. Create a new Crawl Topology.
$CrawlTopo = $SearchApp | New-SPEnterpriseSearchCrawlTopology
# 7. Create a new Crawl Store.
$CrawlStore = $SearchApp | Get-SPEnterpriseSearchCrawlDatabase
# 8. Create a new Crawl Component.
New-SPEnterpriseSearchCrawlComponent -CrawlTopology $CrawlTopo -CrawlDatabase $CrawlStore -SearchServiceInstance $SSI
# 9. Activate the Crawl Topology.
$err = $null
$CrawlTopo | Set-SPEnterpriseSearchCrawlTopology -Active -ErrorVariable err
# should eq "active":
write-host $CrawlTopo.State
# 10. Create a new Query Topology.
$QueryTopo = $SearchApp | New-SPenterpriseSearchQueryTopology -partitions 1
# 11. Create a variable for the Query Partition
$Partition1 = ($QueryTopo | Get-SPEnterpriseSearchIndexPartition)
# 12. Create a Query Component.
New-SPEnterpriseSearchQueryComponent -indexpartition $Partition1 -QueryTopology $QueryTopo -SearchServiceInstance $SSI
# 13. Create a variable for the Property Store DB.
$PropDB = $SearchApp | Get-SPEnterpriseSearchPropertyDatabase
# 14. Set the Query Partition to use the Property Store DB.
$Partition1 | Set-SPEnterpriseSearchIndexPartition -PropertyDatabase $PropDB
$err = $null

Note: If it returns "Inactive" it is because it fails. It fails because "another topology activation is in progress." Solution: Wait 10 minutes before running this last command.

# 15. Activate the Query Topology.
$QueryTopo | Set-SPEnterpriseSearchQueryTopology -Active -ErrorVariable err -ErrorAction SilentlyContinue
# should eq "active"
write-host $QueryTopo.State

Business data

$YourFarmsName = "SP2010"
$appPool = "SharePoint Web Services Default Application Pool"
$dbName = $YourFarmsName + "_BusinessDataConnectivityService"
$BusinessServiceApp = New-SPBusinessDataCatalogServiceApplication -Name "$YourFarmsName Business Data Connectivity Service" -ApplicationPool $appPool -databaseName $dbName
$appserver1 = "servername1"
$bcsserviceID = $(Get-SPServiceInstance | where {$_.TypeName -ilike "Business Data Connectivity Service"} | where {$_.Server -match "SPServer Name=$appserver1"}).ID
Start-SPServiceInstance $bcsserviceID

State Service

Set-ExecutionPolicy unrestricted -Force # answer Y
$FarmName = "SP2010"
$dbName = $FarmName + "_StateService"
New-SPStateServiceDatabase $dbName | New-SPStateServiceApplication -Name "$FarmName State Service Application" | New-SPStateServiceApplicationProxy -Name "$FarmName State Service Application Proxy" -DefaultProxyGroup

Install Site Collections

New SP Site

# Common site collection templates are here: http://technet.microsoft.com/en-us/library/ff678213.aspx
# http://technet.microsoft.com/en-us/library/ff607937.aspx
# Remove-SPSite –Identity "http://sitename" –GradualDelete
# SharePoint cmdlets
# Templates
# Name                 Title                                    LocaleId   Custom
# ----                 -----                                    --------   ------
# GLOBAL# 0             Global template                          1033       False
# STS# 0                Team Site                                1033       False
# STS# 1                Blank Site                               1033       False
# STS# 2                Document Workspace                       1033       False
# MPS# 0                Basic Meeting Workspace                  1033       False
# MPS# 1                Blank Meeting Workspace                  1033       False
# MPS# 2                Decision Meeting Workspace               1033       False
# MPS# 3                Social Meeting Workspace                 1033       False
# MPS# 4                Multipage Meeting Workspace              1033       False
# CENTRALADMIN# 0       Central Admin Site                       1033       False
# WIKI# 0               Wiki Site                                1033       False
# BLOG# 0               Blog                                     1033       False
# SGS# 0                Group Work Site                          1033       False
# TENANTADMIN# 0        Tenant Admin Site                        1033       False
# Languages
# Name                  Title
# ----                  -----
# German                1031
# English               1033
# French                1036
# Spanish               1034
# Contoso Projects Site Collection
Set-ExecutionPolicy unrestricted -Force # answer Y
$SiteCollectionName = "Projects"
$SiteCollectionURL = "http://www.contoso.com/sps/offices/myit/projects"
$ContentDatabase  = "SP2010_ContentDB_Frontend"
$SiteCollectionTemplate = "STS#0"
$SiteCollectionLanguage = 1033
$SiteCollectionDescription = "Information Technology Projects"
$OwnerAlias = "DOMAIN\primaryAdmin"
$OwnerEmail = "primaryAdmin@contoso.com"
$SecondaryOwnerAlias = "DOMAIN\secondaryAdmin"
$SecondaryEmail = "secondaryAdmin@contoso.com"
# Create a new Sharepoint Site Collection
New-SPSite -Name $SiteCollectionName -URL $SiteCollectionURL -ContentDatabase $ContentDatabase -Template $SiteCollectionTemplate -Language $SiteCollectionLanguage -Description $SiteCollectionDescription -OwnerAlias $OwnerAlias -OwnerEmail $OwnerEmail -SecondaryOwnerAlias $SecondaryOwnerAlias -SecondaryEmail $SecondaryEmail
# Contoso Wiki Site Collection
$SiteCollectionName = "Contoso Knowledge Base"
$SiteCollectionURL = "http://www.contoso.com/sps/offices/myit/kbase"
$ContentDatabase  = "SP2010_ContentDB_Frontend"
$SiteCollectionTemplate = "ENTERWIKI#0"
$SiteCollectionLanguage = 1033
$SiteCollectionDescription = "The Information Technology Knowledge Base (Enterprise Wiki)"
$OwnerAlias = "DOMAIN\primaryAdmin"
$OwnerEmail = "primaryAdmin@contoso.com"
$SecondaryOwnerAlias = "DOMAIN\secondaryAdmin"
$SecondaryEmail = "secondaryAdmin@contoso.com"
# Create a new Sharepoint Site Collection
New-SPSite -Name $SiteCollectionName -URL $SiteCollectionURL -ContentDatabase $ContentDatabase -Template $SiteCollectionTemplate -Language $SiteCollectionLanguage -Description $SiteCollectionDescription -OwnerAlias $OwnerAlias -OwnerEmail $OwnerEmail -SecondaryOwnerAlias $SecondaryOwnerAlias -SecondaryEmail $SecondaryEmail
# Contoso Wiki Site Collection
$SiteCollectionName = "Contoso Wiki"
$SiteCollectionURL = "http://www.contoso.com/sps/offices/myit/wiki"
$ContentDatabase  = "SP2010_ContentDB_Frontend"
$SiteCollectionTemplate = "WIKI#0"
$SiteCollectionLanguage = 1033
$SiteCollectionDescription = "The Information Technology Wiki"
$OwnerAlias = "DOMAIN\primaryAdmin"
$OwnerEmail = "primaryAdmin@contoso.com"
$SecondaryOwnerAlias = "DOMAIN\secondaryAdmin"
$SecondaryEmail = "secondaryAdmin@contoso.com"
# Create a new Sharepoint Site Collection
New-SPSite -Name $SiteCollectionName -URL $SiteCollectionURL -ContentDatabase $ContentDatabase -Template $SiteCollectionTemplate -Language $SiteCollectionLanguage -Description $SiteCollectionDescription -OwnerAlias $OwnerAlias -OwnerEmail $OwnerEmail -SecondaryOwnerAlias $SecondaryOwnerAlias -SecondaryEmail $SecondaryEmail
# Contoso Publishing Site
$SiteCollectionName = "Contoso Publishing Site"
$SiteCollectionURL = "http://www.contoso.com/sps/offices/myit"
$ContentDatabase  = "SP2010_ContentDB_Frontend"
$SiteCollectionTemplate = "CMSPUBLISHING#0"
$SiteCollectionLanguage = 1033
$SiteCollectionDescription = "The Information Technology"
$OwnerAlias = "DOMAIN\primaryAdmin"
$OwnerEmail = "primaryAdmin@contoso.com"
$SecondaryOwnerAlias = "DOMAIN\secondaryAdmin"
$SecondaryEmail = "secondaryAdmin@contoso.com"
# Create a new Sharepoint Site Collection
New-SPSite -Name $SiteCollectionName -URL $SiteCollectionURL -ContentDatabase $ContentDatabase -Template $SiteCollectionTemplate -Language $SiteCollectionLanguage -Description $SiteCollectionDescription -OwnerAlias $OwnerAlias -OwnerEmail $OwnerEmail -SecondaryOwnerAlias $SecondaryOwnerAlias -SecondaryEmail $SecondaryEmail
# Contoso Blog Site Collection
$SiteCollectionName = "Contoso Blog"
$SiteCollectionURL = "http://www.contoso.com/sps/offices/myit/blog"
$ContentDatabase  = "SP2010_ContentDB_Frontend"
$SiteCollectionTemplate = "WIKI#0"
$SiteCollectionLanguage = 1033
$SiteCollectionDescription = "The Information Technology Blog"
$OwnerAlias = "DOMAIN\primaryAdmin"
$OwnerEmail = "primaryAdmin@contoso.com"
$SecondaryOwnerAlias = "DOMAIN\secondaryAdmin"
$SecondaryEmail = "secondaryAdmin@contoso.com"
# Create a new Sharepoint Site Collection
New-SPSite -Name $SiteCollectionName -URL $SiteCollectionURL -ContentDatabase $ContentDatabase -Template $SiteCollectionTemplate -Language $SiteCollectionLanguage -Description $SiteCollectionDescription -OwnerAlias $OwnerAlias -OwnerEmail $OwnerEmail -SecondaryOwnerAlias $SecondaryOwnerAlias -SecondaryEmail $SecondaryEmail

Create"My Sites Host" site collection

# MySites Root Site Collection (Required to have at the very root for some reason)
# Read this first: http://social.technet.microsoft.com/Forums/en/sharepointsocialcomputing/thread/60c941da-b552-4739-b389-64c2bb5fcc08
$SiteCollectionName = "My Sites"
$SiteCollectionURL = "http://www.contoso.com:8088/sps"
$ContentDatabase  = "SP2010_ContentDB_MySites"
$SiteCollectionTemplate = "SPSMSITEHOST#0"
$SiteCollectionLanguage = 1033
$SiteCollectionDescription = "SharePoint User Profiles"
$OwnerAlias = "DOMAIN\primaryAdmin"
$OwnerEmail = "primaryAdmin@contoso.com"
$SecondaryOwnerAlias = "DOMAIN\secondaryAdmin"
$SecondaryEmail = "secondaryAdmin@contoso.com"
# Create a new Sharepoint Site Collection
New-SPSite -Name $SiteCollectionName -URL $SiteCollectionURL -ContentDatabase $ContentDatabase -Template $SiteCollectionTemplate -Language $SiteCollectionLanguage -Description $SiteCollectionDescription -OwnerAlias $OwnerAlias -OwnerEmail $OwnerEmail -SecondaryOwnerAlias $SecondaryOwnerAlias -SecondaryEmail $SecondaryEmail
# MySites SPS Site Collection (This is the one people will actually use)
$SiteCollectionName = "My Sites"
$SiteCollectionURL = "http://www.contoso.com:8088/sps"
$ContentDatabase  = "SP2010_ContentDB_MySites"
$SiteCollectionTemplate = "SPSMSITEHOST#0"
$SiteCollectionLanguage = 1033
$SiteCollectionDescription = "SharePoint User Profiles"
$OwnerAlias = "DOMAIN\primaryAdmin"
$OwnerEmail = "primaryAdmin@contoso.com"
$SecondaryOwnerAlias = "DOMAIN\secondaryAdmin"
$SecondaryEmail = "secondaryAdmin@contoso.com"
# Create a new Sharepoint Site Collection
New-SPSite -Name $SiteCollectionName -URL $SiteCollectionURL -ContentDatabase $ContentDatabase -Template $SiteCollectionTemplate -Language $SiteCollectionLanguage -Description $SiteCollectionDescription -OwnerAlias $OwnerAlias -OwnerEmail $OwnerEmail -SecondaryOwnerAlias $SecondaryOwnerAlias -SecondaryEmail $SecondaryEmail

Remove SP Site (So you know how)

# http://technet.microsoft.com/en-us/library/ff607948.aspx
#
# Remove-SPSite –Identity "http://app1.contoso.com/sps/offices/myit/wiki2"

Provision UPS

Several questions: In which application pool should this service application run? A separate "SharePoint User Profile" application pool? Or the "SharePoint Web Services Default"? At least one tutorial uses a separate "SharePoint User Profile" application pool. That same tutorial uses a separate application pool for Managed Metadata. But Microsoft's Technet, Troubleshoot User Profile Synchronization Service start issues, uses the "SharePoint Web Services Default." I chose to use a separate pool.

Helpful Articles about UPS:

So. Onto the procedure...

Add farm account to local administrators group

Yes, add SP-Farm to the local administrators. You will remove it again when the process is complete. Do this with the server manager. No powershell needed.

# Add SP-Farm to local administrators group. This is necessary in order to get the user profiles working. You should remove it when the process is complete.

Restart

# restart

Grant Replicate Directory Changes permission on a domain to the SP-UPS account

# http://technet.microsoft.com/en-us/library/ee721049.aspx# RDCDomain
# Must log into the Active Directory Users and Computers app via an account with admin privileges to mess with domain settings. Needs write access.

Try to install UPS using Powershell

Note: I've been having trouble setting up UPS using Powershell. I'm still trying to figure out what the deal is. Ideally, you would run this script in Windows Powershell ISE as an administrator, remembering to change the variables... and, IDEALLY, this would work. Alas, it does NOT work.

        $DBServer = "SharePoint_Alias"
        $ProfileDBName = "SP2010_ProfileDB"
        $SocialDBName = "SP2010_SocialDB"
        $SyncDBName = "SP2010_SyncDB"
        $FarmAccount = "DOMAIN\SP_Farm"
        $UPSAppName = "SP2010 User Profile Service Application"
        $sb = {
        Add-PSSnapin Microsoft.SharePoint.PowerShell
        $saAppPool = Get-SPServiceApplicationPool "SharePoint User Profiles"
        $upa = New-SPProfileServiceApplication -Name "$UPSAppName" -ApplicationPool $saAppPool -ProfileDBName "$ProfileDBName" -ProfileDBServer $DBServer -SocialDBName "$SocialDBName" -SocialDBServer $dbServer -ProfileSyncDBName "$SyncDBName"  -ProfileSyncDBServer $dbServer -ErrorAction SilentlyContinue -ErrorVariable er
        $proxy = New-SPProfileServiceApplicationProxy -name "SP2010 User Profile Service Application Proxy" -MySiteManagedPath "sps/mysites" -DefaultProxyGroup -ServiceApplication $UPA
        }
        $cred = Get-Credential "$FarmAccount"
        $job = Start-Job -Credential $cred -ScriptBlock $sb | Wait-Job

I'm still testing possible solutions for this and am documenting what I try in another post: How to configure the UPS with Powershell. What I've found is that provisioning UPS with PowerShell does not work due to a bug in SharePoint. When running these Powershell scripts, the provisioning is done as a setup account. But UPS must be provisioned with the Farm account. Therefore, if you try to provision UPS using Powershell, it will seem to work, but it will not have proper permissions to start itself up and will simply say "Starting" or "stopped" when you try. Getting around this requires knowing how to run the Powershell UPS Provisioning script as another user — in this case the farm account user. This page (and the above code) allegedly offers a way to do this, but it hasn't worked for me. Therefore, I recommend creating the UPS manually — that is, through the GUI. This site has a good tutorial: Configuring the User Profile Service in SharePoint 2010. When a solution is found, this page will be updated.

Follow SharePoint George and do this through GUI

# Manual Instructions are here:
# http://sharepointgeorge.com/2010/configuring-the-user-profile-service-in-sharepoint-2010/

Start UPS and UPSS

# -Did this simply by going to System Settings > Manage Services on Server

Enable NetBIOS domain names on UP Service Application:

# "If the NetBIOS name of any domain that you are synchronizing with differs from its fully qualified domain name, you must enable NetBIOS domain names on the User Profile service application. If all NetBIOS names are the same as the domain names, you may skip this procedure."
# http://technet.microsoft.com/en-us/library/ee721049.aspx# WebAppProc
# netbios: contoso
# forest: contoso.com
# Run this script:
$ServiceApps = Get-SPServiceApplication
$UserProfileServiceApp = ""
foreach ($sa in $ServiceApps)
  {if ($sa.DisplayName -eq "SP2010 User Profile Service Application")
    {$UserProfileServiceApp = $sa}
  }
$UserProfileServiceApp.NetBIOSDomainNamesEnabled = 1
$UserProfileServiceApp.Update()

Remove SP-Farm from local administrators:

# Remove SP-Farm from local administrators.
iisreset

This entry was posted in Installation. Bookmark the permalink.

15 Responses to How to Install and Configure SharePoint using Windows Powershell

  1. Wow, this is amazing. Thank you so much for this. Works better than anything else I have tried so far.

  2. Looks like Usage and Health is missing the Var declaration $FarmName = "SP2010"?

  3. Thanks for all the updates, theres a lot changing!

    I noticed you have " in your code snipets now. Is there a way to replace these on your blog? Just wondering.

    I have been looking over the older version of your post and ran into issues at the OWA stage, but looks like there are a lot of updates so I will update my scripts and give it a shot. Running 2 WFE and 2 app servers to a single DB server.

    I also noticed you dont pre-fill the credential username. you can call Get-Credential with the following,
    get-credential -credential Administrator or get-credential -credential DOMAIN\Administrator. That way users dont have to figure out which service account they just put in, as its a little confusing to get 5 authentication prompts that are blank with no prompt.

    I also ran Set-SPDiagnosticConfig -LogLocation "C:\Logs" on each WFE and app server to set my logs to a shorter path.

    Great post. Not too many places have this (a lot of it was old beta 2 stuff and confusing).

    Looking forward to getting UPS and Search configured through PS also.

  4. For the OWA wildcard managed path, after you delete sites, can you create OWA wildcard, cache explicit under that, then recreate Sites wilcard before configuring OWA? Not sure what you mean by "1st wildcard manged path it finds". My OWA failed to configure Word and PowerPoint, but Excel succeeded. I was wondering if my developers could create sites wildcard again and configure OWA again another time.

    • Prior to configuring OWA, two managed paths exist: "/" (explicit) and "/sites" (wildcard). I advocate removing "/sites" before configuring OWA. If you do not, a cron job will run when the OWA is configured and it will install an OWA site collection under that path, leaving you with "/sites/Office_Viewing_Service_Cache". I don't like that. So I remove "/sites" and create a new managed path ("/owa/cache"). Having only "/" and "owa/cache" seems to force the cron job to create the OWA site collection under that new, isolated, managed path. It looks nicer and is easily ignored.

      By the way, notice it does not install the site collection on the explicit path at the root ("/"). That is what I meant by my comment, "1st wildcard managed path." Still, it's only a hypothesis based on observation. My guess (and it is only that) is that the cron job actively looks for the "/sites" path first. Then, if it doesn't find it, it looks for another "wildcard" managed path. I don't think it will install the site collection under any "explicit" path. I have not tried leaving only explicit paths and seeing where the cron job puts the site collection. My guess is that it won't create it or it will create it at the root ("/"), neither of which is desirable.

      Now, as you know, the managed path is one thing and the content database is another. And the more important thing is to isolate the OWA site collection's content database. The script that does this can be found under "Configure Office Web Apps Cache database," which was lifted from this blog . But I may decide to replace it with this Technet code or with this similar code.

      As for the services failing... that happened to me once (but not regularly) and I simply manually turned them on.

  5. You can also do write-output "Please enter SP Farm account" etc. There is also write-host, and you can do cool things like write-host -fore green "This text is green", but the text will only be placed on the screen (not pipable to another command, just something to keep in mind if you try to manipulate the text)

  6. In Usage and Health, $Usage.provision(), should that be $usageApplicationProxy.provision()?

    When this ran, for some reason $usageApplicationProxy was null, but I re-ran it and I was getting back the service app proxy

  7. Start Managed Meta Data Services-

    #Start the Managed Meta Data Web Service
    $mmdservice = Get-SPServiceInstance | Where-Object { $_.TypeName -ilike "Managed Metadata Web Service"}
    start-spserviceInstance $mmdservice.ID

    • Thanks, Eric. As there's one per server, I went with:
      $appserver1 = "servername1"
      $mmserviceID = $(Get-SPServiceInstance | where {$_.TypeName -ilike "Managed Metadata Web Service"} | where {$_.Server -match "SPServer Name=$appserver1"}).ID
      Start-SPServiceInstance $mmserviceID

  8. Do your app servers have a UPGRADE REQUIRED status on the mange services page in Central Admin?

    My wfe's dont have it for some reason...