Forefront Protection 2010 for SharePoint–Error “The SharePoint service is running but the Forefront VSAPI Library is not registered”

 

I got this error in the config tool of Forefront Protection 2010 for SharePoint:

“The SharePoint service is running but the Forefront VSAPI Library is not registered”

image

Here is what I did:

1. Stop running service “Microsoft Forefront Server Protection Controller”

2. Stop running service “Microsoft Forefront Server Protection Controller for SharePoint”

3. Go to your installation directory of Forefront Protection 2010 for SharePoint

4. Run from command prompt: “fsccontroller.exe /disable”

5. Run from command prompt: “fsccontroller.exe /enable”

6. Restart SharePoint Services:

    • SharePoint 2010 Administration
    • SharePoint 2010 Timer

7. Start service “Microsoft Forefront Server Protection Controller for SharePoint”

8. Start service “Microsoft Forefront Server Protection Controller”

9. That’s it. (Do a “Refresh” in the Forefront management console application.)

image

How to set the SharePoint 2010 Enterprise Search Service Application “Default Content Access Account” by using PowerShell

If you want to set the SharePoint 2010 Enterprise Search Service Application "Default Content Access Account" by using PowerShell you can use this script:

$searchapp = Get-SPEnterpriseSearchServiceApplication "Search Service Application"
$c= New-Object Microsoft.Office.Server.Search.Administration.Content($searchapp)
$c.SetDefaultGatheringAccount($crawlUser, (ConvertTo-SecureString $crawlPwd -AsPlainText -force))

($crawlUser is – of cause – the login of the account and $crawlPwd is the password in plain text)

How to set the identity of a SharePoint Windows Service, e.g. “SharePoint Server Search”

I have had the problem to set the SharePoint Sevice Account of "SharePoint Server Search" to a special user account during a automatic setup.

In other words: I want to automate this step:

Central Administration -> Security -> Configure Service Accounts

blog-201011030017

There is no PowerShell command as far as I can see.

You can use this script for this job:

  

$farm =(Get-SPFarm)

$farm.get_Services() | ? { $_.typename -ieq "SharePoint Server Search" } | % {

  $searchservice=$_

  $i = $searchservice.get_ProcessIdentity()

  $i.set_CurrentIdentityType(3)

  $i.set_Username($searchUser)

  $i.Update()

  $i.Deploy()

}

Error while trying to connect to a published Service Application in SharePoint 2010: “Unable to connect to the specified address. Verify the URL you entered and contact the service administrator for more details.”

When you receive this error

Unable to connect to the specified address. Verify the URL you entered and contact the service administrator for more details.

…and you have done the exchange of farm certificates than you forgot this step:

$consumingFarmID=<Farm GUID of the consuming farm>

$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 $consumingFarmID

Grant-SPObjectSecurity -Identity $security -Principal $principal -Rights "Full Control"

Get-SPTopologyServiceApplication | Set-SPServiceApplicationSecurity -ObjectSecurity $security

(Technet: http://technet.microsoft.com/en-us/library/ff700211.aspx)

See the first line of the script:

$consumingFarmID=<Farm GUID of the consuming farm>

→ Here you need to execute this PowerShell code snippet and insert the resulting GUID in the script above:

(Get-SPFarm).Id 

How to embedd compressed scripts in other PowerShell scripts

For a current project I want to create a “master script” that contains another compressed PowerShell script. This compressed script contains some informations – server names, network share names – that should be as unreadable as possible for normal users. This script is executed during user logon.

I created two scripts

  1. "compress.ps1"
  2. "execute.ps1"

The first script is used to compress a script. The second one is used to execute the compressed script.

Here is the script for compressing:

 

cls

$c = Get-Content $$ -Encoding UTF8 

$r = [string]::Join("
", $c)

$r2 = [regex]::Match($r, "(.*)(#<--)(.*)", [System.Text.RegularExpressions.RegexOptions]::Singleline)

$ms = New-Object System.IO.MemoryStream
$cs = New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Compress)

$sw = New-Object System.IO.StreamWriter($cs)
$sw.Write($r2.Groups[3])
$sw.Close();

$bytes = $ms.ToArray()
[System.Convert]::ToBase64String($bytes)

exit
#<--

Write-Host "This is a test"
Get-Service A*

The script produces a base64 string that contains everything behind "#<–".

For the script above the output is:

H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/In7j5DdOvlsXbb797app04/ezIsmpf9laZs37Ue/cfJ53m6/zuvLYpqnx9/6jZP/By/6yuMxAAAA

Here is the execution script that contains this base64 string that represents
the compressed script:

cls

$data = [System.Convert]::FromBase64String("H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/In7j5DdOvlsXbb797app04/ezIsmpf9laZs37Ue/cfJ53m6/zuvLYpqnx9/6jZP/By/6yuMxAAAA")

$ms = New-Object System.IO.MemoryStream
$ms.Write($data, 0, $data.Length)
$ms.Seek(0,0) | Out-Null

$cs = New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Decompress)
$sr = New-Object System.IO.StreamReader($cs)
$t = $sr.readtoend()

Invoke-Expression $t

This executes the following code snipped from the script above:

Write-Host "This is a test"
Get-Service A*

The output is: 

This is a test

Status   Name               DisplayName                           
------   ----               -----------                           
Stopped  AeLookupSvc        Anwendungserfahrung                   
Running  AESTFilters        Andrea ST Filters Service             
Stopped  ALG                Gatewaydienst auf Anwendungsebene     
Stopped  AppIDSvc           Anwendungsidentität                   
Stopped  Appinfo            Anwendungsinformationen               
Running  Apple Mobile De... Apple Mobile Device                   
Stopped  AppMgmt            Anwendungsverwaltung                  
Stopped  aspnet_state       ASP.NET-Zustandsdienst                
Running  AudioEndpointBu... Windows-Audio-Endpunkterstellung      
Running  AudioSrv           Windows-Audio                         
Stopped  AxInstSV           ActiveX-Installer (AxInstSV)          

OCSetup and DISM: Component Names

If you want to install windows features by script you have to use one of the tool OCSETUP oder DISM.

E.g.
start /w ocsetup <component_name>
or
dism /online /enable-feature:<component_name>

BUT: What are the “component names” for the Windows features? First of all: These “component names” are technical names, not the “display names” you will find in Control Panel -> Turn Windows features on or off

You can get a list of the available features if DISM tool is available:

dism /online /get-features

BTW: The component names are case-sensitive!!! – E.g. the component name “NetFx3” (for “Microsoft .Net Framework 3.x”) is not the same as “netfx3”.

But sometimes the technical feature names are very diffrent from the display names. For example: “IIS-LegacySnapIn” is the name for this “IIS 6 Management Console”



Here you’ll find complete lists for the mapping of display name and technical component name

“Passphrase” error while creating a new SharePoint 2010 farm with PowerShell cmdlet “New-SPConfigurationDatabase”

I tried to create a new SharePoint Server 2010 farm by using PowerShell cmdlet “New-SPConfigurationDatabase” in one of the first steps.

I got this error:

New-SPConfigurationDatabase : The passphrase supplied does not meet the minimum complexity requirements. Please select another passphrase that meets all of the following criteria: is at least 8 characters; contains at least three of the following four character groups: English uppercase characters (A through Z); English lowercase characters (a through z); Numerals (0 through 9); Non-alphabetic characters (such as !, $, #, %). Type a passphrase which meets these requirements.

At C:UsersService.SP_InstallDesktopSetupScript.ps1:41 char:28
+ New-SPConfigurationDatabase <<<< -DatabaseName $spconfigdbname -DatabaseServer $dbserver -Passphrase $sppassphrase_sec -FarmCredentials $spfarmcredential
+ CategoryInfo : InvalidArgument: (System.Security.SecureString:SecureString) [New-SPConfigurationDatabase], SPException
+ FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletNewSPConfigurationDatabase

This is my script:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

$sppassphrase=“GOY$sV3SthlkyN%3YTdS&”
$sppassphrase_sec = (ConvertTo-SecureString $sppassphrase -AsPlainText -force)

$spfarmuser=“domainfarmaccount”
$spfarmuserpwd=“P@ssw0rd”

#Securing Settings
$spfarmcredential = new-object -typename System.Management.Automation.PSCredential -argumentlist $spfarmuser, (ConvertTo-SecureString $spfarmuserpwd -AsPlainText -force)

New-SPConfigurationDatabaseDatabaseName “configdb” -DatabaseServer “sqlserver” -Passphrase $sppassphrase_sec -FarmCredentials $spfarmcredential

After debugging I found the following:

When I write the value of variable “$sppassphrase” the the console (with cmdlet write-host) I get:
GOY%3YTdS&
instead of
GOY$sV3SthlkyN%3YTdS&

The problem is: The part “$sV3SthlkyN” will be interpreted as variable name!!!

You have to use escape sequences at least for the “$” character:

$sppassphrase=“GOY`$sV3SthlkyN%3YTdS&”

UPDATE!

Use ‘ instead of ” and you will not have a problem at all!

$sppassphrase=‘GOY$sV3SthlkyN%3YTdS&’

You’ll get what you’ve expected: The correct password string including “$”… (But the solution above also works!)

PowerShell: Cast Object Type

If you load an CSV file with import-csv you will end up with an object of type System.Management.Automation.PSCustomObject. It’s an array.

In such a case I liked to use such an imported file or especially the imported data with the correct object type.

Therefore I created an generic “cast” function in generic PowerShell that can be used for casting with other types.

See the following PowerShell script. The function “Get-CastedObject” takes to parameters:
1) the source array
2) the result object type as string

In the following sample the script creates a CSV file and reads the content of the file during the next run. After loading the data the objects of the array will be “casted” to the correct data type.

Therefore the cast function looks for the “property” object members and tries to assign them to the new created object of the expected result type.

I’m sure there are several opportunities for improvements. Please let me know!

$outfile = C:tempcast-test.csv

Add-Type @’
public class ResultObj
{
public string Test1 = “”;
public string Test2 = “”;
public bool   Test3 = false;
public int    Test4 = 0;
}
‘@

function Get-CastedObject
{
param(
[Parameter(Mandatory
=$true)] [object]$inputObject = $null,
[Parameter(Mandatory
=$true)] [string]$resultType = $null)

if($inputObject -isnot [System.Management.Automation.PSCustomObject] ) {
return $null
}

if($resultType -eq $null ) {
return $null
}

$resultObject = new-object $resultType

$inputObject |gm | ? {$_.MemberType -eq NoteProperty } |% {
Invoke-Expression $(`$resultObject.+$_.Name+ = `$inputObject.+$_.Name )
}

$resultObject
}

$ErrorActionPreference = Continue

if( @(get-childitem $outfile).count -gt 0 )
{
$global:imp = (Import-Csv -Delimiter ; -Path $outfile )
}

$l = @();

$imp | % {$l = $l + (Get-CastedObject $_ ResultObj)  }

$r = New-Object System.Random

for($i=0;$i -lt 10;$i++ ){
$obj = New-Object ResultObj
$obj.Test1 = Test + $l.Count.ToString()
$obj.Test2 = ([System.DateTime]::Now).ToString(HH:mm:ss)
$obj.Test3 = &{if( ($r.NextDouble())-lt 0.5 ) {$true }else {$false } }
$obj.Test4 = [int]$r.Next()
$l = $l + $obj
}

del $outfile -ErrorAction SilentlyContinue
$l |Export-Csv -Delimiter ; -Path $outfile -Encoding utf8 -Force -NoTypeInformation

Please notice my disclaimer in the right sidebar!

Project Server 2010: Error Message “Could not retrieve enterprise global template. Please contact your administrator.”

 

After renaming my SharePoint 2010 from an old to a new URL I could not longer access any project from this server.

The error message looked like this:

“Could not retrieve enterprise global template. Please contact your administrator.”

I could solve the problem by removing the existing Project Server Account connections in the registry:

HKEY_CURRENT_USERSoftwareMicrosoftOffice14.0MS ProjectProfiles<[1..n] project server connections as sub keys>

Before that I copied the URL from the “Path” value under the registry key.

Then I recreated the Project Server Account by using Microsoft Project’s tool.

 

Please notice my disclaimer in the right sidebar!

FileNotFoundException while developing an external SharePoint application

If you develop a SharePoint Application with Visual Studio 2010, e.g. a Console Aplication, you may get an FileNotFoundException.

For example in this code (program.cs):

namespace DemoConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
           SPSite site = new SPSite("http://sharepoint.local");  //<<--- FileNotFoundException
           SPWeb web = site.RootWeb;
           //your code here

        }
    }
}

I’ve maked the line of code where you may receive the exception.

I solved the problem by setting the platform target in the project settings: Go to “project settings”, select “Build” tab, set “Platform target” setting to the architecture of your platform. I always use “x64” there. – After that the exception is gone.