Newly deployed SharePoint site definitions not found in PowerShell

Tags: SharePoint 2013, PowerShell, SharePoint

This is a new problem for me, something that I have done many times in SharePoint 2010.  I deploy a new site definition to SharePoint (in this case from Visual Studio 2012, although I can’t see it will matters), pop into PowerShell (in my case I use PowerGUI) and try to create a site from the new definition.

However, when in PowerShell, running a script similar to this

$web = Get-SPWeb $SiteURL
$templates = $web.GetAvailableWebTemplates(1033)
$templates | Foreach {
	Write-Host $_.Name
}

You find that your new site definition is not listed in with all the other templates.

Go and look in SharePoint, create a site and bingo, it’s there.  Weird.

The problem is around caching in PowerShell sessions.

Restarting IIS and SQL service didn’t work, so I had a quick Google and found this post.

What a pain…so I quickly (with the help of this article) created a PowerShell cmdlet.

Note: Make sure when you run the x64 version of InstallUtil (with from the VS x64 command line or C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe) otherwise you wont find it when you run

Get-PSSnapin –registered

 

Confused

I’m not entirely sure why I have never come up against this before having done it multiple times, perhaps its an update to PowerGUI and the way it handles sessions or perhaps it’s a change in SharePoint 2013 caching.  I don’t know!

 

Code for the PlugIn

Copied from the link above!.  Don’t forget to add a reference to System.Management.Automation (C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll) and Microsoft.SharePoint

[Cmdlet(VerbsCommon.Reset, "SPContext")]
public class RecycleSPContext : PSCmdlet
{
        
    [DllImport("kernel32.dll")]
    private static extern IntPtr FreeLibrary(IntPtr library);

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetModuleHandle(string lpModuleName);

    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibrary(string lpFileName);
        

    protected override void ProcessRecord()
    {
        Type sprequestmanager = typeof(SPFarm).Assembly.GetType("Microsoft.SharePoint.SPRequestManager", true, true);
        Type spthreadcontext = sprequestmanager.Assembly.GetType("Microsoft.SharePoint.Utilities.SPThreadContext");
        MethodInfo setcontext = spthreadcontext.GetMethod("Set", BindingFlags.Static | BindingFlags.NonPublic);
        Type[] genericArguments = new Type[] { sprequestmanager };
        MethodInfo setcontextgeneric = setcontext.MakeGenericMethod(genericArguments);
        // set the current sprequest manager to null!
        setcontextgeneric.Invoke(null, new object[] { null });

        IntPtr p = GetModuleHandle("OWSSVR.DLL");
        FreeLibrary(p);
        string stsadmPath = SPUtility.GetVersionedGenericSetupPath("ISAPI", 15);
        p = LoadLibrary(stsadmPath + @"\OWSSVR.DLL");
            
        WriteObject("SharePoint context restarted at " + DateTime.Now.ToString());
    }

}

 

And the Installer

[RunInstaller(true)]
public class RecycleSPContextInstaller : PSSnapIn
{
    public override string Description
    {
        get { return "Recycle the SP Context"; }
    }
    public override string Name
    {
        get { return "RecycleSPContext"; }
    }
    public override string Vendor
    {
        get { return "Vendor Name"; }
    }
}




comments powered by Disqus