I'm having a problem running a powershell script that creates a new SharePoint site collection.
I have a WCF service hosted in IIS, which has a WCF 3.5 workflow. This workflow executes a Powershell script that creates a new SharePoint site collection. Right now, it fails on the New-SPSite line, but throws no exception or error. The script finishes, but doesn't create the SharePoint site.
I found a cryptic error in a SharePoint log file: Error image
And found no specific answers, but numerous references to impersonation errors. I reviewed each article and thread response I could find, but either it didn’t work or it didn’t apply to my particular issue.
I have an environment where it is working, but I can't create another. I moved to comparing the environments where the solution does and does not work. After comparing almost every aspect of the environments (code being executed in each VM, SharePoint settings, App Pool settings, IIS Settings, and so on), I found out that the only noticeable difference was an entry indicating the type of SharePoint installation in the Server.
By doing some additional research, I found out that authentication on standalone installations might be the root cause of the issue. According to an article I found:
Authentication is a half-baked Kerberos install – If you install the basic install you’ll find your deployment is kerberos, but not really. The SPNs aren’t setup. It feels and behaves a lot like NTLM, but it’s kerberos, but you don’t get all the advantages of kerberos, because without the service principal names, you’re not getting the benefits of what Kerberos would provide for you. Again difficult to troubleshoot or to understand what’s been done. Essentially the product team prefers to see kerberos installs, and with the basic install it doesn’t need to talk to other servers so they can do the install without needing to setup the AD settings around the accounts. It’s a mess, and this is the insight for you if you’re ever trying to figure out what’s gone wrong.
Removing the standalone property from the web.config causes SharePoint to stop working, so I should be able to remove it from somewhere else in SharePoint, but I don't know where.
I tested this script outside the WCF service and works ok, so I think that the problem might be that when the Powershell is running, it doesn't have enough privileges to execute that line. Below you can see the Powershell script, and the portion of code that calls that script. You can see that I'm using impersonation when executing it.
Any help you could provide me would be useful. Thanks a lot.
Daniel
Powershell script
param($SiteName)
$Url = "http://devbox/sites/$SiteName"
$site = Get-SPSite $Url -ErrorAction SilentlyContinue
if ($site -eq $null)
{
$SiteDescription = "Provisioned via workflow - Site $SiteName"
New-SPSite $Url -OwnerAlias "domain\username" -Name $SiteDescription -Template "STS#0" <<< FAILS, BUT RETURNS TRUE WHATSOEVER
return $true
}
else
{
return $false
}
Worfkflow section
using (var imp = System.Security.Principal.WindowsIdentity.GetCurrent().Impersonate())
{
// Set ps1 file path
string powershellCommand;
switch (PathMode)
{
case PathModeTypes.Web:
powershellCommand = HostingEnvironment.ApplicationPhysicalPath + this.PowerShellCommand;
break;
default:
powershellCommand = this.PowerShellCommand;
break;
}
// Add arguments if present
if (IsScript && Arguments != null)
{
powershellCommand += " " + this.Arguments;
}
// Build execution context
baseExecution = base.Execute(executionContext);
var runspaceConfig = RunspaceConfiguration.Create();
if (PSSnapInEnabled)
{
PSSnapInException powerShellException;
var info = runspaceConfig.AddPSSnapIn("Microsoft.SharePoint.Powershell", out powerShellException);
}
using (var runspace = RunspaceFactory.CreateRunspace(runspaceConfig))
{
// Create pipeline
runspace.Open();
var pipeline = runspace.CreatePipeline();
var command = new Command(powershellCommand, this.IsScript);
pipeline.Commands.Add(command);
try
{
// Invoke PowerShell Command
var results = pipeline.Invoke();
this.OutputText = string.Join(Environment.NewLine, results.Select(x => x.ToString()).ToArray());
this.PowerShellSuccessful = !this.OutputText.Equals("False");
}
catch (Exception exception)
{
this.ExceptionMessage = exception.Message;
this.PowerShellSuccessful = false;
}
}
}
return baseExecution;