Previously I looked at automating the installation of SharePoint's binaries. I figure if you're going to go to the trouble of automating a glorified file copy, you may as well replace the SharePoint Products Configuration Wizard, even if just to save yourself from database GUIDs.

In this post I am going to do what the configuration wizard does and using a PowerShell script summon up the things every farm needs — a configuration database and the Central Administration web application. See the end of this post for the full script source.

Once SharePoint is installed, you can begin to run SharePoint cmdlets in PowerShell, although since there's no farm yet, there's not much to do. When you add the Microsoft.SharePoint.PowerShell snap in, you'll see the following notice:

PS> Add-PSSnapin Microsoft.SharePoint.PowerShell
The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered.
PS>

Translated, this means PowerShell couldn't connect to the local farm since it doesn't yet exist, but that's okay since we're creating it!

Before we begin, we'll want to determine the values of these items in your environment:

  • Farm account credentials
  • Farm passphrase
  • Database server
  • Configuration database name
  • Central Administration database name
  • Central Administration port
  • Central Administration authentication provider

You'll recognize these as the same items asked by the configuration wizard. Coincidence? Of course not! Let's define these items right away before we do anything fun.

To specify the credentials for the farm account, I'm using my credential hash table. It is overkill for this example but I'm using it because generally a farm creation script would do more than just create the configuration database and Central Administration and I would need credentials for more accounts. You'll see I also define a variable for the domain for the same reason.

$DOMAIN = "CONTOSO"
$accounts = @{}
$accounts.Add("Farm", @{"username" = ($DOMAIN + "\svc-sp-farm"); "password" = "Contoso!"})

Foreach ($account in $accounts.keys) {
	$accounts.$account.Add(`
	"Credential", `
	(New-Object System.Management.Automation.PsCredential $accounts.$account.username, `
	(ConvertTo-SecureString -String $accounts.$account.password -AsPlainText -Force)))
}

In this case our farm account is CONTOSO\svc-sp-farm, with the complex-password-policy-compliant password "Contoso!"

While we're making SecureStrings, we may as well generate our farm's passphrase. What is the passphrase, and why do we need it? In previous versions of SharePoint, all an administrator needed to join a server to the farm was the knowledge of where the configuration database was and the necessary permissions. If you think about the sort of permissions a database administrator has on a database server, you can see how easy it is to add another server, intentionally or not. My assumption is the passphrase exists to prevent unauthorized or accidental server additions. Treat the passphrase like any shared password — provide it only to people who have a valid reason for adding a server, and don't post it on the Internet.

We need to supply the passphrase as a SecureString to prevent unauthorized persons from seeing the original text. Specifying the passphrase in our script is not a security best practice and I've accepted the risks in this case for the same reasons as the farm account password.

Our passphrase is "SharePoint2010!"

$config_Passphrase = "SharePoint2010!"
$s_config_Passphrase = (ConvertTo-SecureString -String $config_passphrase -AsPlainText -force)

With our SecureStrings out of the way, let's now define the database information, starting with the SQL Server name:

$server_DB = "A-BLOGFARM"

SQL Aliases. Use them. Without question. They will save your life and the lives of 13 of your family members. See Zach's post for more information about why you should create a SQL Alias. Also, check out Zach's other post about creating a SQL Alias with PowerShell if you're into that sort of thing (which you are since you're here reading about configuring your farm with PowerShell).

Now we can provide names for the configuration and Central Administration content databases. This is the most important step for those of you who don't want databases with GUIDs. For those of you with OCD, it also allows you to start a database naming convention about which you can later get all smug. I like the convention: FarmName_DatabaseType_Application_Extra, where:

  • FarmName is unique to the farm and usually identifies to which farm the database belongs as an easy reference. This is especially handy when two or more farms share a SQL Server instance. Not only do you know which database is for which farm, but all the database names for a farm sort together in most lists.
  • DatabaseType describes the role of the database in the farm. In SharePoint 2010 I suggest three possibilities: Configuration, Content, and Service. In MOSS you would have also seen SSP.
  • Application is the name of the service or web application. For example, Search, ManagedMetadata, or State for services and Extranet, Accounting, or JoesCustomApp for content databases. The Configuration database doesn't have an "application" so you can skip this.
  • Extra allows any extra information. Databases for Search and the User Profile Service Application are good candidates for needing this extra field. Web applications with multiple content databases could use it too. If you don't need it, then don't use it. With temporary databases, I like to throw a _TEMPJWYYYYMMDD at the end so when I'm lazy and forget to delete them I (or someone else) can figure out (or ask me) at a later time if the database is still needed.

So following my convention, we arrive at the following database names:

$db_Config = "SP2010_Configuration"
$db_CentralAdmin = "SP2010_Content_CentralAdministration"

And finally the Central Administration Options — port and authentication provider:

$ca_port = 11111
$ca_AuthProvider = "NTLM"

My suggestion for the port is to pick something above port 1023 so you don't conflict with an assigned port (warning: large XML). I chose NTLM for this demo because it's simpler and doesn't require any additional setup as with Kerberos.

Now we have all the information needed to create the farm. So let's do it.

The farm is created with the New-SPConfigurationDatabase PowerShell cmdlet. We'll specify the database name, database server, Central Administration content database name, our SecureString passphrase, and the PSCredential object for the farm account:

New-SPConfigurationDatabase `
-DatabaseName $db_Config `
-DatabaseServer $server_DB `
-AdministrationContentDatabaseName $db_CentralAdmin `
-Passphrase  $s_config_Passphrase `
-FarmCredentials $accounts.farm.credential

This creates the configuration and Central Administration databases, i.e., the farm. Though note that we haven't yet created the Central Administration site, so all we can do is issue further PowerShell cmdlets. We should now be able to use Get-SPFarm to validate that the farm exists:

PS> Get-SPFarm

Name                                                    Status
----                                                    ------
SP2010_Configuration                                    Online

PS>

We can use this as a way to test success within the script and only proceed if the farm was created. If an SPFarm object wasn't returned, then there is likely some serious problem (New-SPConfigurationDatabase likely threw an exception). But going one step further, the SPFarm class has the Status property (inherited from SPPersistedObject) which should return "Online" (see above) if our farm is running:

$farm = Get-SPFarm
if (!$farm -or $farm.Status -ne "Online") {
	Write-Output "Farm was not created or is not running"
	exit
}

The next bunch of steps are more or less the same steps you see the configuration wizard perform, starting with creating Central Administration with the New-SPCentralAdministration cmdlet. We need to provide the port and authentication provider:

New-SPCentralAdministration `
-Port $ca_Port `
-WindowsAuthProvider $ca_AuthProvider

Next, Install-SPHelpCollection installs all help collections from 14 hive\HCCAB\<LCID>:

Install-SPHelpCollection -All

Initialize-SPResourceSecurity initializes security on all files, folders, and registry keys. This means it sets the permissions on all the installed bits to make sure they are properly secured:

Initialize-SPResourceSecurity

Install-SPService installs all services, service instances, and service proxies specified in the registry on the local server computer:

Install-SPService

Install-SPFeature scans for any unregistered features and registers them in the farm. Once it's done, it will dump out a (long) list of features in the farm:

Install-SPFeature -AllExistingFeatures

Install-SPApplicationContent copies shared application data to existing Web application folders:

Install-SPApplicationContent

And with that, you have a farm! Obvously this farm serves no purpose and there are no web applications (other than CA) or services. At this point Central Administration should load, and you can begin configuring components of the farm either there or in PowerShell.

Script source

############################################################
# ConfigFarm.ps1
# Configures a SharePoint 2010 farm with:
#   Configuration Database
#   Central Administation web application and site
#
# Jason Warren (jwarren@habaneros.com)
#
############################################################

# Service accounts
$DOMAIN = "CONTOSO"
$accounts = @{}
$accounts.Add("Farm", @{"username" = ($DOMAIN + "\svc-sp-farm"); "password" = "Contoso!"})

Foreach ($account in $accounts.keys) {
	$accounts.$account.Add(`
	"Credential", `
	(New-Object System.Management.Automation.PsCredential $accounts.$account.username, `
	(ConvertTo-SecureString -String $accounts.$account.password -AsPlainText -Force)))
}

# Farm configuration

$config_Passphrase = "SharePoint2010!"
$s_config_Passphrase = (ConvertTo-SecureString -String $config_passphrase -AsPlainText -force)

$server_DB = "A-BLOGFARM"
$db_Config = "SP2010_Configuration"
$db_CentralAdmin = "SP2010_Content_CentralAdministration"

$ca_port = 11111
$ca_AuthProvider = "NTLM"

########################################
# Create the farm

Add-PSSnapin Microsoft.SharePoint.PowerShell

Write-Output "Creating the configuration database $db_Config"
New-SPConfigurationDatabase `
-DatabaseName $db_Config `
-DatabaseServer $server_DB `
-AdministrationContentDatabaseName $db_CentralAdmin `
-Passphrase  $s_config_Passphrase `
-FarmCredentials $accounts.farm.credential

# Check to make sure the farm exists and is running. if not, end the script
$farm = Get-SPFarm
if (!$farm -or $farm.Status -ne "Online") {
	Write-Output "Farm was not created or is not running"
	exit
}

Write-Output "Create the Central Administration site on port $ca_Port"
New-SPCentralAdministration `
-Port $ca_Port `
-WindowsAuthProvider $ca_AuthProvider


# Perform the config wizard tasks

Write-Output "Install Help Collections"
Install-SPHelpCollection -All 

Write-Output "Initialize security"
Initialize-SPResourceSecurity 

Write-Output "Install services"
Install-SPService 

Write-Output "Register features"
Install-SPFeature -AllExistingFeatures 

Write-Output "Install Application Content"
Install-SPApplicationContent

References

  • Automating the SharePoint 2010 installation
  • The Credential Hash Table
  • Creating a SQL alias for SharePoint
  • Create a SQL Alias with a PowerShell Script
  • New-SPConfigurationDatabase
  • SPFarm Class
  • Get-SPFarm
  • New-SPCentralAdministration
  • Install-SPHelpCollection
  • Initialize-SPResourceSecurity
  • Install-SPService
  • Install-SPFeature
  • Install-SPApplicationContent
    • Share

      Related Posts

      Deconstructing ECM: How to get started

      How can you get started with your SharePoint ECM project? Our clients commonly feel somewhat overwhelmed or mystified just thinking about an enterprise collaboration management (ECM) initiative. For many, ECM is one of those topics that feels like it’s all or nothing, and it can seem like there’s no obvious place to start.

      In this post, I share a process for approaching ECM projects that focuses on three key areas: understanding ECM itself, using the content life cycle, and then planning an approach to ECM.