PowerShell: Creating a SharePoint solution package (WSP file) with CAS

I need to add some code access security information to a SharePoint solution package manifest file. Given the assembly file we can retrieve the required assembly info, and with some xml magic in PowerShell create some result xml. It is not actually the exact code I use in my solution, but it shows the job...

# function: GetAssemblyInfo
#
Arguments: $assemblyFile - path to assembly file to determine information from
#
Returns: Hashtable with the following keys: PublicKeyBlob, Name, Version
function global:GetAssemblyInfo
{
    param
    (
       
$assemblyFile = $(Throw'Missing: assemblyFile')
    )
   
   
if (!(Test-Path -Path $assemblyFile))
    {
        Throw
"Assembly file '$assemblyFile' does not exist"
    }
   
   
# Secutil returns:
   #Line 0: Microsoft (R) .NET Framework SecUtil 2.0.50727.42
   #Line 1: Copyright (c) Microsoft Corporation.  All rights reserved.
   #Line 2:
   #Line 3: Public Key =
   #Line 4: 0x00240000048000009400000006020000002400005253413100040000010001003BBC200DC39F9419851471C4AF65A91540C5904D72694CDE6DF63427FAD8D180630538338E557D90BA4F18A2EF6F44F3A53A5C7CFE625F4954D53B4FF9CF700226FDF13F04731EDED323B1821BA38C5F310231007E7AF862F497174A127BD42C0FA4FAFF1154910B48E177E090888A7745145ED4F4F7BB75D28D6616961A71E3
   #Line 5: Name =
   #Line 6: Macaw.Mast.Wss3.Templates.Presentation.WebAppUI
   #Line 7: Version =
   #Line 8: 1.0.0.0
   #Line 9: Success
   $secutilExe = 'C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\SecUtil.exe'

   
$resultLines = (& $secutilExe -hex -s $assemblyFile)
   
if ($resultLines[9]-ne 'Success')
    {
        Throw
"secutil.exe can't determine assembly information from assembly file '$assemblyFile', secutil.exe command failed"
    }
    @{
'PublicKeyBlob' = $resultLines[4];'Name' = $resultLines[6];'Version' = $resultLines[8] }
}

$assemblyFile = 'C:\Inetpub\wwwroot\wss\VirtualDirectories\1000\bin\Macaw.Mast.Wss3.Templates.Presentation.WebAppUI.dll'
$result = GetAssemblyInfo -assemblyFile $assemblyFile
$result

This will result in the following output:

We can now create out code access security information (in this case in a SharePoint solution package manifest.xml file with code similar to the following code:

$assemblyInfo = GetAssemblyInfo -assemblyFile $assemblyFile
$policyItem = @"
<PolicyItem>
    <PermissionSet class="NamedPermissionSet" version="1" Description="Macaw Solution Factory generated permissionSet" Name="$($assemblyInfo.Name)-PermissionSet">
        <IPermission class="WebPermission" version="1">
            <ConnectAccess>
                <URI uri="`$OriginHost`$" />
            </ConnectAccess>
        </IPermission>
        <IPermission class="SmtpPermission" version="1" Access="Connect" />
        <IPermission class="SharePointPermission" version="1" ObjectModel="True" />
        <IPermission class="PrintingPermission" version="1" Level="DefaultPrinting" />
        <IPermission class="FileIOPermission" version="1" Read="`$AppDir`$" Write="`$AppDir`$" Append="`$AppDir`$" PathDiscovery="`$AppDir`$" />
        <IPermission class="EnvironmentPermission" version="1" Read="TEMP;TMP;USERNAME;OS;COMPUTERNAME" />
        <IPermission class="SqlClientPermission" version="1" Unrestricted="true" />
        <IPermission class="SecurityPermission" version="1" Flags="Assertion, Execution, ControlThread, ControlPrincipal, RemotingConfiguration" />
        <IPermission class="DnsPermission" version="1" Unrestricted="true" />
        <IPermission class="WebPartPermission" version="1" Connections="True" />
        <IPermission class="AspNetHostingPermission" version="1" Level="Medium" />
        <IPermission class="IsolatedStorageFilePermission" version="1" Allowed="AssemblyIsolationByUser" UserQuota="9223372036854775807" />
    </PermissionSet>
<Assemblies>
	<Assembly Name="$($assemblyInfo.Name)" Version="$($assemblyInfo.Version)" PublicKeyBlob="$($assemblyInfo.PublicKeyBlob)" />
</Assemblies>
</PolicyItem>
"@

$xmltext = @"
<?xml version="1.0" encoding="utf-8"?>
<Solution DeploymentServerType="WebFrontEnd" SolutionId="2244989E-9DA9-4a5d-9767-0D8F387181B7" ResetWebServer="true">
    <CodeAccessSecurity>
    </CodeAccessSecurity>
</Solution>
"@

[xml]$xmlDoc = $xmltext
$xmlDoc.SelectSingleNode('/Solution/CodeAccessSecurity').set_InnerXml($policyItem)
$xmlDoc.get_InnerXml()

 

This will results in the following output:

In the production of a real SharePoint solution package a lot more is happening, but this showcases some of the PowerShell power you can use to get the job done.

1 Comment

Comments have been disabled for this content.