Microsoft didn't provide a PowerShell cmdlet to install publishing design packages, and the
one in the design gallery is just kinda overkill. So I took it upon myself to make a simpler version, albeit it did require calling a couple of "internal" methods from the
Microsoft.SharePoint.Publishing library. Well, here goes have at it (you'll also see some reflection examples for calling internal constructors and methods).
Oh, here's an important note. NOTE: MAKE SURE PUBLISHING INFRASTRUCTURE IS ENABLED FIRST. Otherwise it won't turn on, and you won't be able to access the Master page settings page even if you go directly to
ChangeSiteMasterPage.aspx.
#########################################################################
#
#
Install-PublishingDesignPackage -Site <site url> -Path <package
path>
#
#########################################################################
param(
[Parameter(Mandatory=$true)][string]$Site,
[Parameter(Mandatory=$true)][string]$Path
)
$DesignPackage = [Microsoft.SharePoint.Publishing.DesignPackage]
$DesignPackageInfo = [Microsoft.SharePoint.Publishing.DesignPackageInfo]
$BindingFlags = [System.Reflection.BindingFlags]
function _Using
{
param (
[System.IDisposable]
$inputObject =
$(throw `
"The
parameter -inputObject is required."),
[ScriptBlock] $scriptBlock =
$(throw "The
parameter -scriptBlock is required.")
)
Try {
&$scriptBlock
} Finally
{
if
($inputObject -ne
$null) {
if
($inputObject.psbase
-eq $null)
{
$inputObject.Dispose()
} else
{
$inputObject.psbase.Dispose()
}
}
}
}
function Call-InternalConstructor([System.Type]$Type, [Object]$Parms) {
$ParmTypes
= @()
foreach($parm in $Parms) { $ParmTypes
+= $parm.GetType() }
return $Type.GetConstructor($BindingFlags::NonPublic
-bor $BindingFlags::Instance,`
$null, $ParmTypes, $null).Invoke($Parms)
}
function Call-InternalStaticMethod([System.Type]$Type, [string]$MethodName,
[Object]$Parms) {
$ParmTypes
= @()
foreach($parm in $Parms) { $ParmTypes
+= $parm.GetType() }
return $Type.GetMethod($MethodName,
$BindingFlags::NonPublic
-bor`
$BIndingFlags::Static, $null, $ParmTypes, $null).Invoke($null, $Parms)
}
_using($spsite
= New-Object
Microsoft.SharePoint.SPSite($Site)) {
if ($spsite -ne $null) {
$Path
= [System.Io.Path]::Combine((pwd).path,$Path)
$finfo
= Dir $Path
$pkg
= Get-SPUserSolution
-Site $Site
$finfo.Name
-ErrorAction SilentlyContinue
if
( ($pkg -eq
$null) ) {
try
{
$pkgInfo
= Call-InternalConstructor
$DesignPackageInfo ($finfo.Name)
_Using($fileStream =
New-Object System.IO.FileStream($finfo.FullName,`
[System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)) {
if
($fileStream -ne
$null) {
try {
Call-InternalStaticMethod $DesignPackage
"Install" `
([Microsoft.SharePoint.SPSite]$spsite, `
$pkgInfo, [System.IO.Stream]$fileStream)
$DesignPackage::Apply($spsite,$pkgInfo)
} catch [Exception] {
Write-host -ForegroundColor
Red $_.Exception.ToString()
}
} else
{
Write-Host -ForegroundColor Red Unable
to open
$finfo.FullName
}
}
} catch
[Exception] {
Write-host
-ForegroundColor Red
$_.Exception.ToString()
}
} else
{
Write-Host
-ForegroundColor Red
$finfo.Name
`
is already
in the
solution gallery
of $Site
}
} else
{
Write-Host
-ForegroundColor Red
"Unable to open site: " $Site
}
}