AutoSPInstaller enhancements

Dec 8, 2010 at 12:27 PM

Hey Brian.

I have made some enhancements to your script, that i thought i would share with you and the others.

I made 3 thing:

  1. Added a check to see if the script is suppose to create User Profile services - and if not - don't create a manage account for that
  2. Added a provision statement to the WSS usage application creation - right now, when your script is finished, the WSS Usage Application Proxy isn't actually started (so there no gathering going on), so added code to actually start a provision on the object - that starts the proxy
  3. Added the functionality to create the Web Analytics application (using the allready existing keys in the setinput file - ??)

Did some other minor stuff, but thats more just specific thins for our environment.

So, heres the stuff:

1) It's just an IF statement around the block that creates the Managed account - but shown here for completion:

if ($CreateUserProfileApp -eq "1")
{
	$ManagedAccountMySite = Get-SPManagedAccount | Where-Object {$_.UserName -eq $MySiteAppPoolAcct}
	if ($ManagedAccountMySite -eq $NULL) 
	{ 
		Write-Host -ForegroundColor White "- Registering managed account" $MySiteAppPoolAcct
		New-SPManagedAccount -Credential $Cred_MySiteAppPoolAcct | Out-Null 
	}
	else {Write-Host -ForegroundColor White "- Managed account $MySiteAppPoolAcct already exists, continuing."}
}

Like to keep the environment "clean" no need to create an account not used.

2) Found this around the net when I realized that the WSS Usage application proxy wasn't started. So i made the function look like this:

#Region Create WSS Usage Application
function CreateWSSUsageApp
{
	try
	{
		$GetSPUsageApplication = Get-SPUsageApplication
		if ($GetSPUsageApplication -eq $Null)
		{
			Write-Host -ForegroundColor White "- Creating WSS Usage Application..."
			New-SPUsageApplication -Name $WSSUsageApplication -DatabaseServer $DBServer -DatabaseName $WSSUsageDB | Out-Null
			Write-Host -ForegroundColor White "- Done Creating WSS Usage Application."
			Write-Host -ForegroundColor White "- Fixing Provisioning not done."
			$UP = Get-SPServiceApplicationProxy | where {$_.DisplayName -eq $WSSUsageApplication} 
			$UP.Provision()
		}
		else {Write-Host -ForegroundColor White "- WSS Usage Application exists, continuing..."}
	}
	catch
	{
		Write-Output $_
	}
}
if ($CreateWSSUsageApp -eq "1") {CreateWSSUsageApp}

#EndRegion

3) This was the biggest part - found on technet and adapted to your script. The xml keys for this already exists (??) so just uses the existing keys.

#Region Create WebAnalyticsService

function CreateWebAnalyticsApp
{
	try
	{
		$GetWebAnalyticsServiceApplication = Get-SPWebAnalyticsServiceApplication $WebAnalyticsService -ea SilentlyContinue
		if ($GetWebAnalyticsServiceApplication -eq $null)
		{
			$StagerSubscription = "<StagingDatabases><StagingDatabase ServerName='$DBServer' DatabaseName='$WebAnalyticsStagingDB'/></StagingDatabases>"
			$WarehouseSubscription = "<ReportingDatabases><ReportingDatabase ServerName='$DBServer' DatabaseName='$WebAnalyticsReportingDB'/></ReportingDatabases>" 

		      	## Managed Account
		      	$ManagedAccountGen = Get-SPManagedAccount | Where-Object {$_.UserName -eq $AppPoolAcct}
		      	if ($ManagedAccountGen -eq $NULL) { throw "- Managed Account $AppPoolAcct not found" }      
			    ## App Pool
				Write-Host -ForegroundColor White "- Getting Hosted Services Application Pool, creating if necessary..."
		    	$ApplicationPool = Get-SPServiceApplicationPool "SharePoint Hosted Services" -ea SilentlyContinue
		    	if($ApplicationPool -eq $null)
			  	{ 
		            $ApplicationPool = New-SPServiceApplicationPool "SharePoint Hosted Services" -account $ManagedAccountGen
		            if (-not $?) { throw "Failed to create an application pool" }
		      	}	 
				
			 write-host -ForegroundColor White "- Creating Web Analytics Service Application"
		     $ServiceApplication = New-SPWebAnalyticsServiceApplication -Name $WebAnalyticsService -ReportingDataRetention 20 -SamplingRate 100 -ListOfReportingDatabases $WarehouseSubscription -ListOfStagingDatabases $StagerSubscription -ApplicationPool $ApplicationPool 

		     #Create Web Analytics Service Application Proxy
			write-host -ForegroundColor White "- Creating Web Analytics Service Application Proxy"
			$NewWebAnalyticsServiceApplicationProxy = New-SPWebAnalyticsServiceApplicationProxy  -Name $WebAnalyticsService -ServiceApplication $ServiceApplication.Name
		     
		     #Start Analytics service instances
			write-host -ForegroundColor White "- Starting Analytics Service instances ..."
			$AnalyticsDataProcessingInstance = Get-SPServiceInstance | where-object {$_.Name -eq "WebAnalyticsServiceInstance"}
			$AnalyticsWebServiceInstance = Get-SPServiceInstance | where-object {$_.TypeName -eq "Web Analytics Web Service"}
		     
		     $AnalyticsDataProcessingInstance | Start-SPServiceInstance | Out-Null
		     $AnalyticsWebServiceInstance | Start-SPServiceInstance | Out-Null
		}
		else {Write-Host -ForegroundColor White "- Web Analytics Service Application exists, continuing..."}
	}
	catch
	{
		Write-Output $_
	}
	
}
if ($CreateWebAnalytics -eq "1") {CreateWebAnalyticsApp}

#EndRegion

If someone has any comments or anything to this, please share, so that this great script can become even better.

Hope this is something you can use.

Regards

Jesper

 

Coordinator
Dec 8, 2010 at 5:34 PM

Thanks! I'm very interested in the Web Analytics aspect in particular; in the past I couldn't figure out (or didn't take the time to figure out) how to create databases with standard names. Will give it a try and incorporate if it works...!

Brian

Coordinator
Dec 9, 2010 at 1:30 AM

Hmm well I may leave item #1 out for now - I can't see a reason not to create the User Profile App, and it's easy enough to clear out the unneeded managed account afterwards so not a huge concern at this point.

However your #3 item has to be the fastest external code integration I've ever made... I literally copied and pasted it into the existing script and it just worked - nicely done!

Afterwards I also integrated item #2 to fix the Usage App Proxy - nice.

Both items #2 and #3 will be included in the next check-in and package. I'd like to give you proper credit in the comments - can I have your full name (or Twitter name if you prefer :)) ?

Brian

Dec 9, 2010 at 8:00 AM

Glad to help :-)

Full name: Jesper Nygaard Schiøtt
Email: jesper@schioett.dk

Regarding #1, we don't install User Profile - as you have seen in another discussion, we are having trouble with an access denied when trying to create the user profile app (we are right-clicking -> run as admin)
and the turning of UAC is kinda off limits (I work in Danish Defence IT agency).
So we use the script to do a kind of "Base install" totally automatic - if a "customer" want's the User Profile app, we hand install it (for now - until I find a way of installing it - maybe doing the SQL thing?
or hoping Microsoft creates an update to sharepoint to fix the underlying problem)


I just made another addition to your script.
The problem is when installing on multiserver farms. When installing on the first server, all the selected services is started (Metadata Service Application for instance)
But when we install on the 2nd etc etc, the different services isn't started on that server.
So we end up with only the first server in the farm having for example the Metadata Service App started, and all the additionel servers are only running Central Admin and a couple of other "system" services.

So I created a script-addition that syncronizes the services started on all servers.
It uses a newly created xml key in your setinput.xml file to control if it should do the sync:

<SyncServicesOnServers>1</SyncServicesOnServers>

The script is added after the Create PowerPivot Service Application section:

#Region Syncronizing Services on servers

filter TheType {$_.GetType().ToString()}

function SyncServicesOnServersFunc
{
	if ($FirstServer -eq $false)
	{
		$ser = Get-SPServiceInstance | where {$_.status -eq "Online"} | TheType | Select-Object -Unique

		Write-Host -ForegroundColor White "- Not first server in FARM - Syncronizing the Services started on the servers."
		foreach ($s in $ser)
		{
			$serser = Get-SPServiceInstance | ? {$_.GetType().ToString() -eq $s}
			
			foreach ($t in $serser)
			{
				if ($t.status -ne "Online")
				{
					Write-Host -ForegroundColor Blue " - Starting" $t.Typename "on" $t.server -NoNewline
					$t | Start-SPServiceInstance | Out-Null
					while ($t.Status -ne "Online") 
					{
						Write-Host -ForegroundColor Blue "." -NoNewline
						sleep 1
						$t = Get-SPServiceInstance $t.Id
					}
					Write-Host -BackgroundColor Blue -ForegroundColor White "Started!"
				
				}
				else
				{
					#Write-Host -ForegroundColor DarkGray "  -" $t.typename "is started on" $t.server
				}
			}
			 
		}
	}
}
if ($SyncServicesOnServers -eq "1") {SyncServicesOnServersFunc}
#EndRegion

I don't know if this is by design in your script, but our goal is to create the farm servers (the WEB frontends) to be identical for the purposes we have.
If you (or anybody else :-) have any comments or additions to the above, please share :-)

Regards
Jesper

Coordinator
Jan 14, 2011 at 8:24 PM

Thanks for the script contribution, we are working on v2 at the moment which actually overcomes the issue of multi-server farms in such a way that when you specify "True" to start a service instance in a particular input XML file, it will start it regardless of whether it's already been started on another server, thereby allowing you to 'synchronize' the services simply by making sure your XML files are in sync for your web front-end servers, for example.

BTW I recently came across this diagram from Microsoft that really shed some light on which servers really need to run which services; it turns out the WFE servers can get away with running almost no services, have a look:

http://go.microsoft.com/fwlink/?LinkID=167087

Brian