SPWebConfigModifications

by Brian Krainer Jacobsen 7. July 2013 10:10

Been a long time since the last post - sorry Smile

Verification of SP Web Modifications

These scripts are created to help verifying the deployment of WSP packages which includes SPWebConfigModifications

The first script (SPWebConfigMods.ps1) will create a CSV file with all SPWebModifications which are active on the SharePoint farm, divided per web application

The idea is to:

1. Run SPWebConfigMods.ps1
2. Store the SPWebConfigMods.csv for reference (baseline configuration)
3. Install the WSP package
4. Run SPWebConfigMods.ps1
5. Store the SPWebConfigMods.csv for reference (configuration after WSP package have been installed)
6. Uninstall the WSP package
7. Run SPWebConfigMods.ps1
8. Store the SPWebConfigMods.csv for reference (configuration after WSP package have been uninstalled)
9. Verify that the WSP package did a proper clean up (compare with baseline configuration)


The SPWebConfigModsRemove.ps1 allows the removal of all entries created by a specific Owner


Syntaxes:
---------
SPWebConfigMods.ps1
SPWebConfigModsRemove.ps1 -Owner "OwnerName"

 

SPConfigModifications.zip (2.05 kb)

Tags:

IIS | SharePoint 2010

Upgrading SharePoint 2007/2010 License from Standard to Enterprise in a multi server setup

by Brian Krainer Jacobsen 5. July 2012 09:13

​When upgrading the license key in SharePoint 2010 there are some issues when working in a multi-server implementation, since one of the tasks which will be executed on all servers is the PSCONFIG command (this error is also existing on SharePoint 2007)

This command is not working well when executed on all servers at the same time, since it will update conflicts and conflicting timer jobs (created by one server, deleted by another), and when updating the license the process will kick off the PSCONFIG on all servers. 

The errors I have encountered includes the following:


Errors in the PSCDiagnostics_MM_DD_YYYYY_HH_MM_SS_MS_NUMBER.log
 
Exception: Microsoft.SharePoint.Administration.SPDuplicateObjectException: An object of the type Microsoft.Office.Server.Administration.DiagnosticsService+DiagnosticsServiceTimerJobDefinition named
"DiagnosticsServiceTimerJobDefinition" already exists under the parent Microsoft.SharePoint.Administration.SPTimerService named "SPTimerV4".  Rename your object or delete the existing object.
   at Microsoft.SharePoint.Administration.SPConfigurationDatabase.StoreObject(SPPersistedObject obj, Boolean storeClassIfNecessary, Boolean ensure)
   at Microsoft.SharePoint.Administration.SPConfigurationDatabase.Microsoft.SharePoint.Administration.ISPPersistedStoreProvider.PutObject(SPPersistedObject persistedObject, Boolean ensure)
   at Microsoft.SharePoint.Administration.SPPersistedObject.BaseUpdate()
   at Microsoft.SharePoint.Administration.SPJobDefinition.Update()
   at Microsoft.Office.Server.Administration.DiagnosticsService.CreateTimerJob()
   at Microsoft.Office.Server.Administration.DiagnosticsService.Update()
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.InstallServiceInConfigDB(Boolean provisionTheServiceToo, String serviceRegistryKeyName)
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.InstallServices(Boolean provisionTheServicesToo)
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.Run()
   at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()
 
and
 
Exception: Microsoft.SharePoint.Administration.SPUpdatedConcurrencyException: An update conflict has occurred, and you must re-try this action. The object SearchAdminWebService was updated by DOMAIN\USERNAME, in the
PSCONFIG (PROCESSID) process, on machine SERVERNAME.  View the tracing log for more information about the conflict.
   at Microsoft.SharePoint.Administration.SPConfigurationDatabase.StoreObject(SPPersistedObject obj, Boolean storeClassIfNecessary, Boolean ensure)
   at Microsoft.SharePoint.Administration.SPConfigurationDatabase.Microsoft.SharePoint.Administration.ISPPersistedStoreProvider.PutObject(SPPersistedObject persistedObject, Boolean ensure)
   at Microsoft.SharePoint.Administration.SPPersistedObject.BaseUpdate()
   at Microsoft.SharePoint.Administration.SPIisWebService.Update()
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.InstallServiceInConfigDB(Boolean provisionTheServiceToo, String serviceRegistryKeyName)
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.InstallServices(Boolean provisionTheServicesToo)
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.Run()
   at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()
 
Errors in the Windows Event Log:
 
The Execute method of job definition Microsoft.SharePoint.Portal.Administration.SkuUpgradeJob (ID SOMEGUID) threw an exception. More information is included below.

Post setup configuration failed when attempting post setup configuration task -cmd services -install -cmd installfeatures


Configuration of SharePoint Products failed.  Configuration must be performed in order for this product to operate properly.  To diagnose the problem, review the extended error information located at DRIVE:\Program Files

\Common Files\Microsoft Shared\Web Server Extensions\14\LOGS\PSCDiagnostics_MM_DD_YYYYY_HH_MM_SS_MS_NUMBER.log, fix the problem, and run this configuration wizard again.
Failed to register SharePoint services.

and
 
An exception of type Microsoft.SharePoint.Administration.SPDeletedConcurrencyException was thrown.  Additional exception information: The object DiagnosticsServiceTimerJobDefinition

Name=DiagnosticsServiceTimerJobDefinition has been deleted by another user since it was last fetched.
Microsoft.SharePoint.Administration.SPDeletedConcurrencyException: The object DiagnosticsServiceTimerJobDefinition Name=DiagnosticsServiceTimerJobDefinition has been deleted by another user since it was last fetched.
   at Microsoft.SharePoint.Administration.SPTimerStore.AddTargetInstance(SPJobDefinition jd, Guid targetInstanceId)
   at Microsoft.SharePoint.Administration.SPTimerStore.AddTargetInstances(SPJobDefinition jd)
   at Microsoft.SharePoint.Administration.SPJobDefinition.Update()
   at Microsoft.Office.Server.Administration.DiagnosticsService.CreateTimerJob()
   at Microsoft.Office.Server.Administration.DiagnosticsService.Update()
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.InstallServiceInConfigDB(Boolean provisionTheServiceToo, String serviceRegistryKeyName)
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.InstallServices(Boolean provisionTheServicesToo)
   at Microsoft.SharePoint.PostSetupConfiguration.ServicesTask.Run()
   at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()

When searching on the internet, the general recommendation is to clear the SharePoint Configuration Cache, but since this is a timing issue, this doesn't fix the problem.

Another approach is to reduce the farm to a single server implementation and reinstall SharePoint on all the servers which aren't part of the farm anymore (example from a 3 server farm):

  • Disconnect the 2 Web Front End servers from the Staging Farm leaving Application server as the only server on the Staging farm
  • Clear the configuration cache on the Application server
  • Perform the Enterprise upgrade on the farm by using the Central Administration site
  • If the upgrade is successful then uninstall SharePoint from the 2 Web Front End servers
  • Reboot the 2 Web Front End servers
  • Install SharePoint on the 2 Web Front End servers using the Enterprise license key
  • Install all of the cumulative updates on the 2 Web Front End servers
  • Connect both Web Front End servers to the farm
  • Perform smoke screen tests
  • Test existing content
  • Test existing functionality
  • Test enterprise functionality


Ref: http://mauiwilliamssharepoint.blogspot.dk/2011/08/sharepoint-2010-upgrade-standard.html

 

I created a workaround for this, so I didn't have to reinstall SharePoint on the servers, this workaround is to create a small application (APP1) which has 3 small tasks:

  • Wait for a configurable amount of time
  • Call a configurable application (APP2) with the arguments received by APP1
  • Redirect Exit Code, Standard Output and Standard Error from APP2 to the caller of the APP1 application


If we have 3 SharePoint servers in a farm (WFE1/CA, WFE2 and APP1), then rename the following files on WFE2 and APP1:

  • DRIVE:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN\PSCONFIG.EXE to PSCONFIGORG.EXE
  • DRIVE:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN\PSCONFIG.EXE.CONFIG to PSCONFIGORG.EXE.CONFIG

Copy the following files:

  • PACKAGE\AppRedirect.exe to DRIVE:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN\PSCONFIG.EXE
  • PACKAGE\AppRedirect.exe.config to DRIVE:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN\PSCONFIG.EXE.CONFIG

Update the new PSCONFIG.EXE.CONFIG on WFE2 with the following information:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="WaitTimeMS" value = "60000"/>
    <add key="StartProgram" value = "PSCONFIGORG.EXE"/>
    <add key="LogFiles" value = "C:\TMP\PSCONFIG"/>
  </appSettings>
</configuration>

Ensure that the "LogFiles" directory exists, and the account running the timer service has at least modify permissions to the directory.

Update the new PSCONFIG.EXE.CONFIG on APP1 with the following information:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="WaitTimeMS" value = "120000"/>
    <add key="StartProgram" value = "PSCONFIGORG.EXE"/>
    <add key="LogFiles" value = "C:\TMP\PSCONFIG"/>
  </appSettings>
</configuration>

Ensure that the "LogFiles" directory exists, and the account running the timer service has at least modify permissions to the directory.

The above will ensure that the PSCONFIG is called on WFE1 immidiately, while it's delayed 60 and 120 seconds on WFE2 and APP1.

Update the SharePoint 2010 license key (Enable Enterprise Features in Central Admin)

If the update still fails with the above error descriptions, then increase the WaitTimeMS values (60000 = 60 secs) to e.g. 180000/360000, and retry the license key update.

When the update has succeeded, then rename the PSCONFIGORG.EXE and PSCONFIGORG.EXE.CONFIG back to the original names.

The actual output from the PSCONFIG commands will be located in the LogFiles directory (only for information purposes). 

Disclaimer: Of course you need to test it in your test environment before doing anything in the productions environment (shouldn't be necessary to write this, but...)

 

The application is available (with source) at:

AppRedirect.zip (48.41 kb)

Tags: ,

SharePoint 2010

Publishing SharePoint 2010 through UAG

by Brian Krainer Jacobsen 29. September 2011 23:03

When publishing a SharePoint 2010 site through the Microsoft UAG, and then accessing the site through a mobile device (in this case my Windows Phone 7), I needed to implement the following instructions:

(source: http://technet.microsoft.com/en-us/library/dd903064.aspx)

 

When end users access a SharePoint 2010 site from a mobile device using the Office Mobile client, to allow the device to download documents from a SharePoint site, you must make the following URL set changes:

  • In the Forefront UAG Management console, open the Advanced Trunk Configuration dialog box, and click the URL Set tab.
  • In the URL list, scroll to InternalSite_Rule54, and in the Methods column, add the HEAD method.
  • In the URL list, scroll to SharePoint14AAM_Rule47, and in the Methods column, add the HEAD method.
  • On the Advanced Trunk Configuration dialog box, click OK, and then activate the configuration.

When adding the HEAD methods, remember to press CTRL to ensure that you do not unselect the current methods :o)

 

 

Tags: ,

SharePoint 2010 CSS Reference Chart

by Brian Krainer Jacobsen 28. September 2011 15:24

There is a very nice reference to the CSS styles used in SharePoint 2010 at this location:

Tags:

SharePoint 2010: Configure farm trusts

by Brian Krainer Jacobsen 23. September 2011 21:21

When Service Applications must be published across farms, there must be created a trust between these farms.

The configured trusts can be reviewed in the Central Administration under Security/Manage Trust.

When creating a trust between two farms, there are a set of steps which must be executed:

On the publishing farm the root certificate must be exported on all servers:

$rootCert = (Get-SPCertificateAuthority).RootCertificate
$rootCert.Export("Cert") | Set-Content "DRIVE:\PUBLISHROOT.cer" -Encoding byte

On the subscribing farm both the root and STS (Secure Token Service) certificates must be exported:

$rootCert = (Get-SPCertificateAuthority).RootCertificate
$rootCert.Export("Cert") | Set-Content "DRIVE:\SUBSCRIBEROOT.cer" -Encoding byte

$stsCert = (Get-SPSecurityTokenServiceConfig).LocalLoginProvider.SigningCertificate
$stsCert.Export("Cert") | Set-Content "DRIVE:\SUBSCRIBESTS.cer" -Encoding byte


In the below certificate installations, I have named the certificate with the name of the server from which the certificate originated.

On the publishing farm both the root and STS certificates must be imported (this must be installed from each server in the subscribing farm):

$RootCertName="SUBSCRIBESERVERNAME"
if ((Get-SPTrustedRootAuthority | ?{$_.DisplayName -eq "$RootCertName"}) -eq $null)
{
 Write-Host "Installing Root Certificate: $RootCertName"
 $trustCert = Get-PfxCertificate "DRIVE:\SUBSCRIBEROOT.cer"
 New-SPTrustedRootAuthority "$RootCertName" -Certificate $trustCert | Out-Null
}
else
{
 Write-Host "Root Certificate: $RootCertName is already installed..."
}

$STSCertName="SUBSCRIBESERVERNAME"
if ((Get-SPTrustedServiceTokenIssuer | ?{$_.DisplayName -eq "$STSCertName"}) -eq $null)
{
 Write-Host "Installing STS Certificate: $STSCertName"
 $stsCert = Get-PfxCertificate "DRIVE:\SUBSCRIBESTS.cer"
 New-SPTrustedServiceTokenIssuer "$STSCertName" -Certificate $stsCert | Out-Null
}
else
{
 Write-Host "STS Certificate: $STSCertName is already installed..."
}

On the subscribing farm the root certificate from the publishing farm must be installed (this must be installed from each server in the publishing farm):

$RootCertName="PUBLISHSERVERNAME"
if ((Get-SPTrustedRootAuthority | ?{$_.DisplayName -eq "$RootCertName"}) -eq $null)
{
 Write-Host "Installing Root Certificate: $RootCertName"
 $trustCert = Get-PfxCertificate "DRIVE:\PUBLISHROOT.cer"
 New-SPTrustedRootAuthority "$RootCertName" -Certificate $trustCert | Out-Null
}
else
{
 Write-Host "Root Certificate: $RootCertName is already installed..."
}

After the certificates have been installed, the subscribing farm must be granted permissions to the "Application Discovery and Load Balancer Service Application" on the publishing farm:

# ID of the remote farm: (Get-SPFarm).Id
$FarmID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
 
# Setting permissions for remote farm on topology service application
$security = Get-SPTopologyServiceApplication | Get-SPServiceApplicationSecurity
$claimProvider = (Get-SPClaimProvider System).ClaimProvider
$principal = New-SPClaimsPrincipal -ClaimType "http://schemas.microsoft.com/sharepoint/2009/08/claims/farmid" -ClaimProvider $claimProvider -ClaimValue "$FarmID"
Grant-SPObjectSecurity -Identity $security -Principal $principal -Rights "Full Control"
Get-SPTopologyServiceApplication | Set-SPServiceApplicationSecurity -ObjectSecurity $security

If there are problems, an IISRESET will help :o)

Tags: , , ,

SharePoint 2010: Setting permissions for cross farm publishing of Managed Metadata

by Brian Krainer Jacobsen 23. September 2011 20:31

When publishing a Managed Metadata service across farms, the remote farm must be granted permissions to the managed metadata service application (there must also be configured a farm trust, but I have documented this in another post):
 
# ID of the remote farm: (Get-SPFarm).Id
$FarmID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
 
# Setting permissions for remote farm on Metadata service application
$ServiceApp = Get-SPServiceApplication | ? {$_.DisplayName -eq "Managed Metadata Services"}
$security = $ServiceApp | Get-SPServiceApplicationSecurity
$claimProvider = (Get-SPClaimProvider System).ClaimProvider
$principal = New-SPClaimsPrincipal -ClaimType "http://schemas.microsoft.com/sharepoint/2009/08/claims/farmid" -ClaimProvider $claimProvider -ClaimValue "$FarmID"
Grant-SPObjectSecurity -Identity $security -Principal $principal -Rights "Full Access to Term Store"
$ServiceApp | Set-SPServiceApplicationSecurity -ObjectSecurity $security
$ServiceApp.Uncache()

 

Tags: , , ,

SharePoint 2010: Subscribing to Managed Metadata Services

by Brian Krainer Jacobsen 23. September 2011 18:32

Subscribing to a published Managed Metadata Services is rather simple:
 
$SAName="Managed Metadata Services"
$LocalProxyName="Connected to: Managed Metadata Services Proxy"
$MetadataProxy = Get-SPMetadataServiceApplicationProxy -Identity "$LocalProxyName"

# (Get-SPTopologyServiceApplication).LoadBalancerUrl.AbsoluteUri
$TopologyUrl = "https://PUBLISHSERVER:32844/Topology/topology.svc"

if($MetadataProxy -eq $null)
{
  Write-Host "Subscribing to Service Application: $LocalProxyName"
 
  $SAConnectInfo = Receive-SPServiceApplicationConnectionInfo -FarmUrl "$TopologyUrl" | Where {$_.Name -eq "$SAName"}
  if ($SAConnectInfo -ne $null)
  {
    $ServiceAppProxy = New-SPMetadataServiceApplicationProxy -Name “$LocalProxyName” –URI $SAConnectInfo.Uri
    Add-SPServiceApplicationProxyGroupMember (Get-SPServiceApplicationProxyGroup -default) -Member $ServiceAppProxy | Out-Null
  }
  else
  {
    Write-Host -ForegroundColor Red "ERROR - Service Application is not published - $SAName"
  }
}
else
{
 Write-Host "Already subscribing to Service Application: $LocalProxyName"
}

 

Tags: , , ,

SharePoint 2010: Publishing Managed Metadata Services

by Brian Krainer Jacobsen 23. September 2011 18:01

The publishing of the Managed Metadata Service Application is rather simple:


$SAName = "Managed Metadata Services"
$HubURI = "http://hub.jacobsens.dk/sites/cthub"
$ContentTypeSyndicationEnabled = $true
$SyndicationErrorReportEnabled = $true

Publish-SPServiceApplication (Get-SPMetadataServiceApplication "$SAName")

if (![string]::IsNullOrEmpty($HubURI))
{
  Set-SPMetadataServiceApplication -Identity (Get-SPMetadataServiceApplication "$SAName") -HubURI "$HubURI"
  Set-SPMetadataServiceApplicationProxy -Identity "$SAName Proxy" -ContentTypeSyndicationEnabled:$ContentTypeSyndicationEnabled -Confirm:$false | Out-Null
}

Set-SPMetadataServiceApplication -Identity (Get-SPMetadataServiceApplication "$SAName") -SyndicationErrorReportEnabled:$SyndicationErrorReportEnabled

Tags: , , ,

SharePoint 2010 Search Service Application - Setting default access account password

by Brian Krainer Jacobsen 23. September 2011 17:31

When building my SharePoint 2010 installation and configuration scripts, I ran into a few issues regarding the default crawl account for the Search Service Application, specifically that the search service complained that the password wasn't configured for the default content access count (crawl account).
 
When using the Set-SPEnterpriseSearchServiceApplication cmdlet, some sources shows that you just include the password as a string (but since it's a securestring object, this is obiously wrong), others that the password is added directly with the ConvertTo-SecureString, but it just kept complaining, but the solution I ended up with was actually rather simple, but it works :)
 
$cred = New-Object System.Management.Automation.PSCredential "DOMAIN\USERNAME",(ConvertTo-SecureString "PASSWORD" -AsPlainText -Force)
Set-SPEnterpriseSearchServiceApplication -Identity "Search Service Application" -DefaultContentAccessAccountName $cred.UserName -DefaultContentAccessAccountPassword $cred.Password
 
 

Tags: , , , ,

URL Rewrite non www to www

by Brian Krainer Jacobsen 16. August 2011 08:42

When rewriting the URL in an IIS7(.5) site, you can use the free URLRewrite module from IIS.NET​.

When adding a rule, the following will provide you with an option to redirect all users from a non-www named site to the same site with www infront - e.g.:

http://oltiva.dk -> http://www.oltiva.dk

An example of this is shown here

The problem is if there are sites which shouldn't be redirected, but this is easily solved by adding a few extra conditions:

<rule name="non www to www" enabled="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" matchType="Pattern" pattern="^www\.([.a-zA-Z0-9]+)$" ignoreCase="true" negate="true" />
<add input="{HTTP_HOST}" matchType="Pattern" pattern="^(noredirect1\.oltiva\.dk)$" ignoreCase="true" negate="true" />
<add input="{HTTP_HOST}" matchType="Pattern" pattern="^(noredirect2\.oltiva\.dk)$" ignoreCase="true" negate="true" />
</conditions> <action type="Redirect" url="http://www.{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>

or if you prefer to have the rule written as one statement:

<rule name="non www to www" enabled="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" matchType="Pattern" pattern="^(www\.([.a-zA-Z0-9]+))|(noredirect1\.oltiva\.dk|noredirect2\.oltiva\.dk)$" ignoreCase="true" negate="true" />
</conditions>
<action type="Redirect" url="http://www.{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>

Tags: , ,

IIS