Thursday, February 5, 2015

Object Cache Accounts

Many administrators when they first configure SharePoint 2010 and hit a Web Application for the first time are likely to see a recurring event in the event log stating that the object cache has not been configured correctly. The specific error is as follows:

Object Cache: The super user account utilized by the cache is not configured. This can increase the number of cache misses, which causes the page requests to consume unneccesary system resources. 

This is essentially telling you that you have missed a manual configuration step in which you need to run some PowerShell to set two accounts for SharePoint to use to access the object cache:

function Set-WebAppUserPolicy($webApp, $userName, $userDisplayName, $perm) {
    [Microsoft.SharePoint.Administration.SPPolicyCollection]$policies = $webApp.Policies
    [Microsoft.SharePoint.Administration.SPPolicy]$policy = $policies.Add($userName, $userDisplayName)
    [Microsoft.SharePoint.Administration.SPPolicyRole]$policyRole = $webApp.PolicyRoles | where {$_.Name -eq $perm}
    if ($policyRole -ne $null) {
        $policy.PolicyRoleBindings.Add($policyRole)
    }
    $webApp.Update()
}
$webApp = Get-SPWebApplication "http://content"
$portalSuperUserAccount = Get-Credential "localdev\SPSuperUser"
$webApp.Properties["portalsuperuseraccount"] = $portalSuperUserAccount.UserName
Set-WebAppUserPolicy $webApp $portalSuperUserAccount.UserName $portalSuperUserAccount.UserName "Full Control"

$portalSuperReaderAccount = Get-Credential "localdev\SPSuperReader"
$webApp.Properties["portalsuperreaderaccount"] = $portalSuperReaderAccount.UserName
Set-WebAppUserPolicy $webApp $portalSuperReaderAccount.UserName $portalSuperReaderAccount.UserName "Full Read"

Make sure that you do not use the same account for both the super user and super reader. (And of course make sure you change the URL and account names to match your environment).

For more information about these settings see the following TechNet article: http://technet.microsoft.com/en-us/library/ff758656.aspx

Unattended Accounts

* There are some services, specifically the Visio Services Service Application, the Excel Services Service Application, and the PerformancePoint Service Application, that allow us to set an account that we can use for access data sources behind the scenes. These are called unattended access accounts.

* To set these accounts we must create a new target application in the Secure Store Service Application and associate the target application’s ID with the appropriate Service Application.

* The following PowerShell code demonstrates how to do this for the Visio Services Service Application (the Excel Services Service Application is virtually identical and just uses cmdlets specific to Excel rather than Visio; PerformancePoint is a lot simpler):

#Get the Visio Service App
$svcApp = Get-SPServiceApplication | where {$_.TypeName -like "*Visio*"}
#Get the existing unattended account app ID
$unattendedServiceAccountApplicationID = ($svcApp | Get-SPVisioExternalData).UnattendedServiceAccountApplicationID
#If the account isn't already set then set it
if ([string]::IsNullOrEmpty($unattendedServiceAccountApplicationID)) {
    #Get our credentials
    $unattendedAccount = Get-Credential "localdev\SPUnattended"

    #Set the Target App Name and create the Target App
    $name = "$($svcApp.ID)-VisioUnattendedAccount"
    Write-Host "Creating Secure Store Target Application $name..."
    $secureStoreTargetApp = New-SPSecureStoreTargetApplication -Name $name `
        -FriendlyName "Visio Services Unattended Account Target App" `
        -ApplicationType Group `
        -TimeoutInMinutes 3

    #Set the group claim and admin principals
    $groupClaim = New-SPClaimsPrincipal -Identity "nt authority\authenticated users" -IdentityType WindowsSamAccountName
    $adminPrincipal = New-SPClaimsPrincipal -Identity "$($env:userdomain)\$($env:username)" -IdentityType WindowsSamAccountName

    #Set the account fields
    $usernameField = New-SPSecureStoreApplicationField -Name "User Name" -Type WindowsUserName -Masked:$false
    $passwordField = New-SPSecureStoreApplicationField -Name "Password" -Type WindowsPassword -Masked:$false
    $fields = $usernameField, $passwordField

    #Set the field values
    $secureUserName = ConvertTo-SecureString $unattendedAccount.UserName -AsPlainText -Force
    $securePassword = $unattendedAccount.Password
    $credentialValues = $secureUserName, $securePassword

    #Get the service context
    $subId = [Microsoft.SharePoint.SPSiteSubscriptionIdentifier]::Default
    $context = [Microsoft.SharePoint.SPServiceContext]::GetContext($svcApp.ServiceApplicationProxyGroup, $subId)

    #Check to see if the Secure Store App already exists
    $secureStoreApp = Get-SPSecureStoreApplication -ServiceContext $context -Name $name -ErrorAction SilentlyContinue
    if ($secureStoreApp -eq $null) {
        #Doesn't exist so create.
        Write-Host "Creating Secure Store Application..."
        $secureStoreApp = New-SPSecureStoreApplication -ServiceContext $context `
            -TargetApplication $secureStoreTargetApp `
            -Administrator $adminPrincipal `
            -CredentialsOwnerGroup $groupClaim `
            -Fields $fields
    }
    #Update the field values
    Write-Host "Updating Secure Store Group Credential Mapping..."
    Update-SPSecureStoreGroupCredentialMapping -Identity $secureStoreApp -Values $credentialValues

    #Set the unattended service account application ID
    $svcApp | Set-SPVisioExternalData -UnattendedServiceAccountApplicationID $name
}
When it comes to PerformancePoint we have a lot less work we need to do as the product team was nice enough to make it so that the Set-SPPerformancePointSecureDataValues does all the work of setting up the target application for us (note though that they did screw up how the Service Application is passed into the cmdlet requiring you to pass in the ID of the Service Application rather than the actual Service Application object):

$unattendedAccount = Get-Credential "localdev\SPUnattended"
$secureValues = Get-SPPerformancePointSecureDataValues -ServiceApplication $svcApp.Id
if ($secureValues.DataSourceUnattendedServiceAccount -ne $unattendedServiceAccount.UserName) {
    Write-Host "Setting unattended service account $($unattendedServiceAccount.UserName)..."
    $svcApp.Id | Set-SPPerformancePointSecureDataValues -DataSourceUnattendedServiceAccount $unattendedServiceAccount
}

SharePoint Farm Accounts

* ​In SharePoint 2010 accounts comes in two flavours : Managed accounts and Service accounts.

* Think of the commands as a quick shortcut to get an overview of where certain accounts are used in your farm:

First off, you can get an overview of the existing managed accounts simply by typing

Get-SPManagedAccount

This however does not tell you where an account is used, so lets dig a bit deeper.

First lets see where we should expect accounts to surface. The below list is probably not complete but drop me a comment and I will add any accounts I have missed out:

Managed Service Accounts:

All Service Application Pool Accounts

*Access Service Application
* BCS Service Application
* Excel Services Service Application
* Metadata Service Application
* PerformancePoint Service Application
* Enterprise Search Service Application
* Secure Store Service Application
* Subscription Settings Service Application
* User Profile Service Application
* Visio Services Service Application
* Web Analytics Service Application
* Word Automation Service Application
* Word Viewing Service Application
* PowerPoint Viewing Service Application
* Security Token Service Application

All Content Web Application Pools

Service Instances

* Claims to Windows Token Service
* Document Conversion Launcher Service
* Document Conversion Load Balancer Service
* Microsoft SharePoint Foundation Sandboxed Code Service
* SharePoint Foundation Help Search
* SharePoint Server Search (Enterprise Search)
* Web Analytics Data Processing Service

Service Accounts (should not be managed):

Search Crawl Accounts

* For Foundation Search and Server (Enterprise) Search

Unattended User Accounts

* Excel Services Service Application
* Visio Services Service Application
* PerformancePoint Service Application
(in general, any Secure Store application credentials)

Object Cache Portal Accounts

* Super User Account
* Super Reader Account

User Profile

* Synchronization Service Account (listed incorrectly on the FarmCredentialManagement.aspx page)
* Synchronization Connection Account

Server Search Custom Crawl Rule Accounts

* Any crawl rule that specifies an account other than the default crawl account

<Update>

Get Farm administrators

Find the farm administrators using the following cmdlets

Get-SPWebApplication -IncludeCentralAdministration | ? IsAdministrationWebApplication | Select -Expand Sites | ? ServerRelativeUrl -eq "/" | Get-SPWeb | Select -Expand SiteGroups | ? Name -eq "Farm Administrators" | Select -expand Users

</Update>

Service Application Pool accounts

Using the cmdlet

Get-SPServiceApplicationPool

gives you both service application pool name and process account name.

Service Application accounts

To find out what service application pools are used for a given service application use this command:

Get-SPServiceApplication | select -expand applicationpool -EA 0

Note that the -EA = 0 (-ErrorAction SilentlyContinue) will swallow any exceptions due to the fact that not all service applications are web based (inherits from SPIisWebServiceApplication).

A special case  to be aware of, is the User Profile Synchronization Service Connection. This account is not managed, and can be a bit tricky to find using PowerShell.

First get a hold of the UserProfileConfigManager, then select the connection manager and get the account name:

$configManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager( $(Get-SPServiceContext http://yourSite))
$configManager | select -expand connectionmanager | select AccountUserName

Web Application Pool accounts

Getting to the web application pools are not straight forward, as they do not have cmdlets defined like Service Application Pools. To access existing web application pools we use the Content Service:

[Microsoft.SharePoint.Administration.SPWebService]::ContentService.ApplicationPools | Select Name, Username

 If you want to find out what application pools, and hence accounts, are used by existing web applications this is pretty straight forward:

Get-SPWebApplication | select -expand applicationpool | Select name , username

Service Instance accounts

The command to get these gets a bit longwinded to account for that some are managed and some not:

Get-SPServiceInstance | select -expand service | % { if ( $_.ProcessIdentity -and $_.ProcessIdentity.GetType() -eq "String") { $_.ProcessIdentity } elseif ( $_.ProcessIdentity ) { $_.ProcessIdentity.UserName }}

Services

Using Get-Process does not contain information about what accounts the services are running under. Getting this information would require us to dig a bit deeper.

Fire up PowerShell and type in the following:

Get-WmiObject -Query "select * from win32_service where name LIKE 'SP%v4'" | select name, startname

This should give you output like this:

name                            startname
----                                 ---------
SPAdminV4                LocalSystem
SPTimerV4                 CONTOSO\svcSPFarm
SPTraceV4                  NT AUTHORITY\LocalService
SPUserCodeV4           CONTOSO\svcSPUserCode
SPWriterV4                CONTOSO\svcSPFarm

Other processes ends with "14":

Get-WmiObject -Query "select * from win32_service where name LIKE '%14'" | select name, startname

Object cache accounts

These accounts are used for accessing cached data. Not setting them causes a performance overhead as explained here.

The values are stored in the Web Application properties and can be fetched like this:

Get-SPWebApplication| % {$_.Properties["portalsuperuseraccount"]} 

Get-SPWebApplication| % {$_.Properties["portalsuperreaderaccount"]}

Search crawler account 

Setting this account can be done using Set-SPEnterpriseSearchServiceApplication -DefaultContentAccessAccountName, but querying it is a bit tricky:

New-Object Microsoft.Office.Server.Search.Administration.content $(Get-SPEnterpriseSearchServiceApplication) | Select DefaultGatheringAccount