30 novembre 2015

SHAREPOINT 2013 : Installation sous Windows Server 2012 R2

Lors de l'installation de SharePoint 2013 sous WS2012R2, vous pouvez rencontrez des soucis dans la phase d'installation des prérequis:
"The tool was unable to install Application Server Role, Web Server (IIS) Role"
 
Cette erreur survient avec ou sans l'utilisation de l'AutoSPInstaller.
Après quelques recherches, il s'avère que ce problème est plutôt fréquent. Un article a même été mis à disposition par Microsoft:
https://support.microsoft.com/en-us/kb/2765260
 
La première erreur peut survenir du faire que vous ne possèdez pas le fichier "ServerManagerCmd.exe" sur le serveur. Il ne s'agit que d'une copie de l'exécutable "ServerManager.exe".
Pour se faire, vous pouvez lancer la commande PowerShell suivante:

Import-Module ServerManager
Copy-Item -Path "$($ENV:SystemRoot)\System32\ServerManager.exe" -Destination "$($ENV:SystemRoot)\System32\ServerManagerCmd.exe" -Force


Si le problème persiste, vous pourrez activez manuellement les fonctionnalités nécessaires "Application Server" et "Web Server" via PowerShell:

Add-WindowsFeature NET-WCF-HTTP-Activation45,NET-WCF-TCP-Activation45,NET-WCF-Pipe-Activation45
Add-WindowsFeature Net-Framework-Features,Web-Server,Web-WebServer, `
 Web-Common-Http,Web-Static-Content,Web-Default-Doc,Web-Dir-Browsing, `
    Web-Http-Errors,Web-App-Dev,Web-Asp-Net,Web-Net-Ext,Web-ISAPI-Ext, `
    Web-ISAPI-Filter,Web-Health,Web-Http-Logging,Web-Log-Libraries,Web-Request-Monitor, `
    Web-Http-Tracing,Web-Security,Web-Basic-Auth,Web-Windows-Auth,Web-Filtering, `
    Web-Digest-Auth,Web-Performance,Web-Stat-Compression,Web-Dyn-Compression, `
    Web-Mgmt-Tools,Web-Mgmt-Console,Web-Mgmt-Compat,Web-Metabase,Application-Server, `
    AS-Web-Support,AS-TCP-Port-Sharing,AS-WAS-Support, AS-HTTP-Activation, `
    AS-TCP-Activation,AS-Named-Pipes,AS-Net-Framework,WAS,WAS-Process-Model, `
    WAS-NET-Environment,WAS-Config-APIs,Web-Lgcy-Scripting,Windows-Identity-Foundation, `
    Server-Media-Foundation,Xps-Viewer

Il sera ensuite nécessaire de redémarrer le serveur et le tour est joué.

26 novembre 2015

SHAREPOINT : Repackager un WSP manuellement

Le développement dans SHAREPOINT s'articule autour du déploiement de WSP:
  • Conception de solutions plus ou moins complexes de type ferme ou Sandbox (WebParts, modèles de sites, timer jobs, types de contenus, pages applicatives métiers),
  • Enregistrement de sites en tant que modèle (fonctionnalité offerte nativement par SharePoint qui se déploie en tant que Sandbox).
 
Dans chacun de ces cas, il peut-être demandé de réaliser des modifications sur des WSP en production alors que les sources ne sont plus disponibles (si si, cela arrive...).
Si la modification est minime (pas de DLL à modifier), plutôt que de faire du retro engeneering, il peut-être avantageux de simplement modifier un fichier dans le WSP.
 
Pour se faire, il faut tout d'abord comprendre l'architecture qu'un WSP. Il ne s'agit ni plus ni moins qu'un fichier CAB (ou archive) renommé en WSP. Il est donc possible d'extraire le contenu d'un WSP dans un répertoire après l'avoir renommé en CAB ou RAR puis l'avoir décompressé.
 
Vous accédez donc à présent à l'ensemble des fonctionnalités comprises dans votre WSP et vous pouvez réaliser les modifications apportées. Mais comment reconcevoir le package une fois modifiée? Ce qui ont travaillé avec des archives CAB connaissent l'outil "MAKECAB" mais il est facile de se retrouver avec un package incorrect.
 
Pour se faire, SharePoint intégre une méthode qui peut être appelée via le PowerShell pour SharePoint (il faudra être positionné sur un serveur SharePoint):
 
$destWSPfilename = "C:\TEMP\Repackage\MonNomdeWSP.wsp"
$sourceSolutionDir = [System.IO.DirectoryInfo]"C:\TEMP\Repackage\MonArchiveExtraite"
 
$a = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$ctor = $a.GetType("Microsoft.SharePoint.Utilities.Cab.CabinetInfo").GetConstructors("Instance, NonPublic")[0]
$cabInf = $ctor.Invoke($destWSPfilename);
$mi = $cabInf.GetType().GetMethods("NonPublic, Instance, DeclaredOnly")
$mi2 = $null
foreach( $m in $mi ) {
    if( $m.Name -eq "CompressDirectory" -and $m.GetParameters().Length -eq 4 ) {
        $mi2 = $m;
        break;
    };
}
$mi2.Invoke($cabInf, @( $sourceSolutionDir.FullName, $true, -1,$null ));
 
Il faudra donc uniquement modifier les 2 variables $destWSPFileName (correspondant à l'emplacement de regénrération de votre WSP) et $sourceSolutionDir (correspondant à votre répertoire contenant les fichiers extraits du WSP).
 
Et le tour est joué, vous obtenez un magnifique WSP prêt à être déployé!