One of the principles that PowerShell offers is the ability to “discover” what commands you need to run to do your tasks. This principle mostly holds up—with on caveat: you have to “Know” the concepts about the task upfront for the commands to make sense. I’m going to both demonstrate what this discovery means at the same time as showing how to create a service application. The idea behind the discovery concept is that you should be able to take the knowledge behind creating 1 specific type of service application and re-use it to create any other type of service application*. Note that Search can be a bit more difficult because of all the flexibility built into 2010—the more flexible the system gets the more detailed setup can be.
First, you need to understand the concept of what is required to create a Service Application (I’m only going to discuss non-federated, so running on the same farm that is using it). In the most simplified form: the following items are required for every service application:
1. The SPServiceApplication: this is the actual definition in the configuration database that will contain information like related databases and settings. Note that this requires providing a web service Application Pool (More on this later).
2. The SPServiceApplicationProxy: This is the “service connection” that is used for Web Applications to “talk” to the Service Application
3. Start at least one SPServiceInstance: This is the actual “process” that will be used to run the Service Application code. This can run on multiple servers to share load and provide high-availability—but only 1 is “required”.
4. Attach the service to a SPServiceApplicationProxyGroup: This is the ‘group’ of service applications that a web application can be set to use. There is a “Default” group that you can add services to that all web apps will be associated with by default.
Each service obviously has it’s own requirements (for example, you need to create databases for the User Profile service), but PowerShell will actually Prompt you for the “required” parameters and will give defaults for as many as it can. Feel free to provide alternates to the defaults.
So, with that, let’s use the four requirements above to create a service app! Metadata Service is a good starting point…
1. Start one or more service instances. Note that these exist regardless of whether they have any service applications to actually run. We also want to wait for this to fully provision before continuing.
$MetadataServiceInstance = (Get-SPServiceInstance |Where{$_.TypeName -eq "Managed Metadata Web Service"}) #Get a pointer to the Service Instance
if($MetadataserviceInstance.Status -eq "Disabled"){ $MetadataserviceInstance | Start-SPServiceInstance } #Start the Service Instance
while(-not ($MetadataServiceInstance.Status -eq "Online")){ #wait for provisioning to finish
write-host -ForegroundColor Yellow "Waiting for Metadata service to provision"; sleep 5;
}
Add-SPServiceApplicationProxyGroupMember -Identity $ProxyGroup -Member $MetaDataServiceAppProxy
2. Get or Create an Application Pool. If you already have one running other services you can get an existing one using the GET command, or create a new one like this.
$ManagedAccount = Get-SPManagedAccount | select -First 1 #Get a managed account. I RECOMMEND YOU CHANGE THIS LINE TO GET THE RIGHT ACCOUNT FOR YOU!
$ApplicationPool = New-SPIisWebServiceApplicationPool "SharePoint Hosted Services" -account $ManagedAccount
*Note: this is NOT a Web Application “app pool”. Do NOT create one of these for a web application –it will NOT work.
3. Create the Service Application
$MetaDataServiceApp = New-SPMetadataServiceApplication -Name "Metadata Service Application" -ApplicationPool $ApplicationPool
4. Create the proxy. I also “attach it to the default proxy group using the -DefaultProxyGroup flag.
$MetaDataServiceAppProxy = New-SPMetadataServiceApplicationProxy -Name "Metadata Service Application Proxy" -ServiceApplication $MetaDataServiceApp –DefaultProxyGroup
That’s it! It’s a little basic, and can’t be part of a larger script that is going to be “re-run” very easily, so here’s a full script with some error handling to wrap the action…
try{
#Managed Account
$ManagedAccount = Get-SPManagedAccount | select -First 1
if ($ManagedAccount -eq $NULL) { throw "No Managed Accounts" }
#App Pool
$ApplicationPool = Get-SPIisWebServiceApplicationPool "SharePoint Hosted Services" -ea SilentlyContinue
if($ApplicationPool -eq $null){
$ApplicationPool = New-SPIisWebServiceApplicationPool "SharePoint Hosted Services" -account $ManagedAccount
if (-not $?) { throw "Failed to create an application pool" }
}
#Create a Taxonomy Service Application
if((Get-SPServiceApplication |?{$_.TypeName -eq "Managed Metadata Service"})-eq $null){
Write-Progress "Creating Taxonomy Service Application" -Status "Please Wait..."
#get the service instance
$MetadataServiceInstance = (Get-SPServiceInstance |?{$_.TypeName -eq "Managed Metadata Web Service"})
if (-not $?) { throw "Failed to find Metadata service instance" }
#Start Service instance
if($MetadataserviceInstance.Status -eq "Disabled"){
$MetadataserviceInstance | Start-SPServiceInstance
if (-not $?) { throw "Failed to start Metadata service instance" }
}
#Wait
while(-not ($MetadataServiceInstance.Status -eq "Online")){ #wait for provisioning
write-host -ForegroundColor Yellow "Waiting for Metadata service to provision"; sleep 5;
}
#Create Service App
$MetaDataServiceApp = New-SPMetadataServiceApplication -Name "Metadata Service Application" -ApplicationPool $ApplicationPool
if (-not $?) { throw "Failed to create Metadata Service Application" }
#create proxy
$MetaDataServiceAppProxy = New-SPMetadataServiceApplicationProxy -Name "Metadata Service Application Proxy" -ServiceApplication $MetaDataServiceApp -DefaultProxyGroup
if (-not $?) { throw "Failed to create Metadata Service Application Proxy" }
}
}
catch
{
Write-Output $_
}