Générer un hyperlien (url) absolu à partir de Reporting Services (SSRS)

Il est parfois nécessaire de générer un lien vers un rapport SSRS en utilisant Go to URL plutôt que Go to report:

image

Afin de ne pas coder en dur le protocole (ex. http), le serveur, la collection de sites (ex. /sites/sitecol), le site (ex. /sites/sitecol/siteparent/sitechild) et la librairie de documents (ex. /sites/sitecol/siteparent/sitechild/doclib), nous avons accès aux variables Globals!ReportFolder et Globals!ReportServerUrl.

La variable ReportServerUrl change si on est en design-time (BIDS / SSDT-BI) et une fois dans SharePoint, selon la version de Reporting Services.

Environnement

Valeur

BIDS / SSDT-BI (vide)
SSRS 2008 dans SharePoint Url vers le serveur de rapport.
Ex. http://server/ReportServer
SSRS 2012 http://server/sites/sitecol/siteparent/sitechild/_vti_bin/ReportServer

Le lien vers un rapport SSRS, intégré en mode SharePoint, doit ressembler à ceci:

http://server/sites/sitecol/siteparent/sitechild/_layouts/ReportServer/RSViewerPage.aspx?rv:RelativeReportUrl=/sites/sitecol/siteparent/sitechild/Reports/RPT-1.rdl

Puisque la valeur de la variable change ReportServerUrl, cela complique la vie du développeur de rapports.

Cette fonction VB.Net, qui peut directement être placée dans la section code d’un rapport, peut vous aider:

Public Function GetReportUrl(Optional ByVal sReportName As String = Nothing) As String
  Dim sUseReportFolder    As String
  Dim sUseReportServerUrl  As String
  Dim sSiteUrl            As String
  Dim sRelReportUrl       As String
  Dim sUseReportName      As String

  sUseReportFolder = Iif(String.IsNullOrEmpty(Report.Globals.ReportFolder), "http://server/sites/sitecol/site/doclib", Report.Globals.ReportFolder)
  sUseReportServerUrl = Iif(String.IsNullOrEmpty(Report.Globals.ReportServerUrl), "http://server/sites/sitecol/site/_vti_bin/ReportServer", Report.Globals.ReportServerUrl)
  sUseReportServerUrl = sUseReportServerUrl.Replace("_vti_bin/ReportServer", "")
  
  sSiteUrl = sUseReportFolder.Substring(0, sUseReportFolder.LastIndexOf("/"))
  sRelReportUrl = sUseReportFolder.Substring(sUseReportServerUrl.IndexOf("/", sUseReportServerUrl.IndexOf("//") + 2))
  sUseReportName = Iif(String.IsNullOrEmpty(sReportName), Report.Globals.ReportName, sReportName)
  
  Return String.Format("{0}/_layouts/ReportServer/RSViewerPage.aspx?rv:RelativeReportUrl={1}/{2}", sSiteUrl, sRelReportUrl, sUseReportName) 
End Function

Vous pouvez l’appeler sans paramètre pour créer un lien vers le rapport courant:

=Code.GetReportUrl()

Ou en passant le nom d’un autre rapport:

=Code.GetReportUrl(« Rpt-01.rdl »)

Le code teste si les variables sont vides et si c’est le cas, des valeurs par défaut sont utilisées. Cela permet de tester directement dans BIDS / SSDT-BI.

C’est un problème qui revient souvent.

Quelques notes sur l’authentification par formulaire avec SSRS intégré à SharePoint

Il est possible d’utiliser un mode d’authentification propriétaire dans SharePoint: il suffit de se définir un ASP.Net Membership Provider. Si vous avez aussi besoin de définir des rôles afin de faciliter l’autorisation du contenu pour les différents utilisateurs, vous devrez aussi définir un ASP.Net Role Provider.

En mode Claims (ex. avec SharePoint 2010), vous aurez besoin de modifier plusieurs Web.Config afin d’intégrer votre Membership et Role provider:

  1. Ceux de vos applications Web (ex. SharePoint – 80)
  2. Celui de SharePoint Administration
  3. Celui de Security Token Service sous SharePoint Web Services

Si vous avez plusieurs “applications SSRS” accessibles par différents types d’utilisateurs, l’idéal serait de définir des rôles (ex. Analysts, Executives etc.) et de sécuriser les sites SharePoint contenant les rapports SSRS avec ces rôles. La structure de site serait donc:

  1. Site racine (/)
  2. Sous-site pour les analystes (/Analysts) accessible uniquement pour les membres du rôle Analysts
  3. Sous site pour les exécutifs (/Executives) accessible uniquement pour les membres du rôle Executives

La navigation de SharePoint enlève automatiquement les liens vers les sites dont l’utilisateur n’ont pas accès. Par exemple, si un utilisateur n’est n’est ni dans le rôle Analysts ni dans le rôle Executives, la section “Sites and Workspaces” sera vide:

image

Si vos rapports utilisent des sources de données XML (ex. sur un fichier de configuration), vous devrez stocker ces fichiers statiques dans un site SharePoint où l’accès anonyme a été autorisé. La raison est que les sources de données XML supportent uniquement l’authentification Windows ou Anonyme. Il n’est pas possible d’utiliser une identité stockée (ex. compte de service) avec ce type de connexion.

Donc notre site racine permettrait l’accès anonyme et contiendrait une librairie de documents contenant ces fichiers statiques. Les sources de données XML référeraient à ces fichiers en mode anomyme:

  1. L’application Web doit permettre l’accès anonyme:

    image

  2. Le site racine doit permettre l’accès anonyme:

    image

    image

  3. La source de données XML doit être en mode anonyme:

    image

  4. Les utilisateurs doivent s’authentifier pour accéder aux rapports:

    image

    image

    Autrement, ils auront cette erreur:

    image

    Reporting Services does not support anonymous user from a SharePoint site. To view Reporting Services reports, choose a SharePoint site that does not have Anonymous access enabled or sign in on an anonymous site.

Si vous utilisez des sources de données vers des bases de données Analysis Services (SSAS) et que celles-ci utilisent la sécurité de données vous pourrez utiliser cette technique:

  1. Un compte Active Directory devra être créé pour représenter un rôle dans la base de données SSAS (ex. Analysts et Executives).
  2. Une composante (ex. procédure stockée SQL) devra être capable de faire correspondre un utilisateurs formulaire vers un rôle (ex. Analyste1 est dans le rôle Analysts).
  3. Les rapports définissent des connexions directement dans le rapport (et non dans une source de données partagée) afin de pouvoir utiliser une expression qui ajoute EffectiveUserName=Analysts|Executives à la fin. Le rapport appelle la composante en #2 pour obtenir le nom du compte Windows à utiliser dans EffectiveUserName.
  4. L’identité d’un compte de service, administrateur de l’instance SSAS, devra être utilisée pour la connexion. C’est requis afin d’être en mesure d’utiliser EffectiveUserName.

J’en parle avec plus de détails dans mon article intitulé: Authentification par formulaire, SharePoint, SSRS et sécurité des données dans SSAS

SYNTELL a réalisé plusieurs mandats où l’on devait intégrer l’authentification propriétaire du client au sein d’une solution Microsoft BI.

Références

Claims Walkthrough: Creating Forms-Based Authentication for Claims-Based SharePoint 2010 Web Applications Using ASP.NET SQL Membership and Role Providers
https://msdn.microsoft.com/en-us/library/office/gg252020%28v=office.14%29.aspx

Forms Authentication in SharePoint Products and Technologies (Part 2): Membership and Role Provider Samples
https://msdn.microsoft.com/en-us/library/office/bb975135%28v=office.12%29.aspx

XML Connection Type (SSRS)
https://msdn.microsoft.com/fr-ca/library/dd220468.aspx?f=255&MSPPError=-2147217396

Comment faire disparaitre certaines erreurs suite à une installation SharePoint 2013

DCOM 10016

J’ai déjà traité des erreurs DCOM 10016 dans une entrée de blogue Comment faire disparaitre les erreurs DCOM 10016 suite à une installation SharePoint publiée il y a quelques années et suscitant encore beaucoup de traffic. Les erreurs ressemblent à:

The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID {61738644-F196-11D0-9953-00C04FD919C1}
to the user <Nom de l’utilisateur du AppPool> SID <SID du AppPool>.
This security permission can be modified using the Component Services administrative tool.

Avec SharePoint 2013, il y a de nouveaux GUIDs qui s’affichent dans le Event Viewer. Aussi, il est recommandé par Microsoft d’utiliser un compte de service différent pour le site d’administration (ex. cs-webadmin) que pour les autres applications Web (ex. cs-web). Si Microsoft SQL Server Integration Services est installé, vous pouvez aussi recevoir des erreurs similaires pour le compte de service SQL (ex. cs-sql).

Voici donc la liste complète des GUIDs pour lesquels on doit suivre mon guide précédent, ainsi que les utilisateurs pour lesquels on doit attribuer des droits:

GUID

Component Service

Utilisateur(s)

{61738644-F196-11D0-9953-00C04FD919C1} IIS WAMREG admin Service cs-webadmin, cs-web
{000C101C-0000-0000-C000-000000000046} {000C101C-0000-0000-C000-000000000046} cs-webadmin, cs-web
{83B33982-693D-4824-B42E-7196AE61BB05} Microsoft SQL Server Integration Services 11.0 cs-sql

Erreurs Reporting Services pour les extensions de données

Par exemple, vous avez peut-être ces erreurs dans les journaux SharePoint (ULS) et SSRS:

Exception caught instantiating TERADATA report server extension:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.

Voici un script PowerShell qui désactive les extensions qui ne sont pas utilisées la plupart du temps:

$ssrs = Get-SPRSServiceApplication

$ext = Get-SPRSExtension -Identity $ssrs.Id

$e = $ext | Where-Object {$_.Name -eq « TERADATA » -and $_.ExtensionType -eq « Data »}

Remove-SPRSExtension -Name $e.Name -ExtensionType $e.ExtensionType -Identity $ssrs.Id

$e = $ext | Where-Object {$_.Name -eq « TERADATA » -and $_.ExtensionType -eq « SemanticQuery » }

Remove-SPRSExtension -Name $e.Name -ExtensionType $e.ExtensionType -Identity $ssrs.Id

$e = $ext | Where-Object {$_.Name -eq « TERADATA » -and $_.ExtensionType -eq « ModelGeneration » }

Remove-SPRSExtension -Name $e.Name -ExtensionType $e.ExtensionType -Identity $ssrs.Id

$e = $ext | Where-Object {$_.Name -eq « SQLPDW » -and $_.ExtensionType -eq « Data » }

Remove-SPRSExtension -Name $e.Name -ExtensionType $e.ExtensionType -Identity $ssrs.Id

$e = $ext | Where-Object {$_.Name –eq « SQLPDW » -and $_.ExtensionType -eq « SemanticQuery » }

Remove-SPRSExtension -Name $e.Name -ExtensionType $e.ExtensionType -Identity $ssrs.Id

Erreurs SQL Server 2012 et SSAS 2012

Si vous avez les erreurs suivantes dans votre observateur d’événements, veuillez suivre ce guide pour les faire disparaître.

SQL Server

sqlservr (3472) tentative d’ouvrir le fichier « C:\Windows\system32\LogFiles\Sum\Api.log » pour uniquement un accès en lecture a échoué avec l’erreur système 5 (0 x 00000005): « Accès refusé ». L’opération d’ouverture de fichier échouera avec l’erreur -1032 (0xfffffbf8).

sqlservr (3472) erreur 1032 (0xfffffbf8) s’est produite lors de l’ouverture du fichier journal C:\Windows\system32\LogFiles\Sum\Api.log.

sqlservr (3472) An attempt to open the file « C:\Windows\system32\LogFiles\Sum\Api.log » for read only access failed with system error 5 (0x00000005): « Access is denied. « . The open file operation will fail with error -1032 (0xfffffbf8).

sqlservr (3472) Error -1032 (0xfffffbf8) occurred while opening logfile C:\Windows\system32\LogFiles\Sum\Api.log.

SSAS

msmdsrv (4680) tentative d’ouvrir le fichier « C:\Windows\system32\LogFiles\Sum\Api.chk » pour la lecture / écriture a échoué avec l’erreur système 5 (0 x 00000005): « Accès refusé ». L’opération d’ouverture de fichier échouera avec l’erreur -1032 (0xfffffbf8).

msmdsrv (4680) erreur 1032 (0xfffffbf8) s’est produite lors de l’ouverture du fichier journal C:\Windows\system32\LogFiles\Sum\Api.log.

msmdsrv (4680) An attempt to open the file « C:\Windows\system32\LogFiles\Sum\Api.chk » for read / write access failed with system error 5 (0x00000005): « Access is denied. « . The open file operation will fail with error -1032 (0xfffffbf8).

msmdsrv (4680) Error -1032 (0xfffffbf8) occurred while opening logfile C:\Windows\system32\LogFiles\Sum\Api.log.

Erreur SharePoint pour SPUsageImportJobDefinition

Si vous avez l’erreur suivante:

The Execute method of job definition Microsoft.SharePoint.Administration.SPUsageImportJobDefinition (ID ef497ec2-0cbf-4458-91ea-db75422fd9da) threw an exception. More information is included below.

Utilisez la soution décrite ici.

Comment lancer un rapport SSRS automatiquement lorsqu’un utilisateur accède à un site SharePoint

Si, comme nous, vous utilisez SharePoint comme dépôt pour vos rapports Reporting Services, vous souhaitez probablement que l’utilisateur accède directement au rapport, et non au site SharePoint.

Vous pouvez tout simplement lui donner l’URL complet vers le rapport, mais cela génère souvent des hyperliens longs.

L’autre approche est d’utiliser un petit script Power Shell:

$web = Get-SPWeb “https://server/sites/client

$folder = $web.RootFolder

$folder.WelcomePage = « FR/Rapports/Rapport1.rdl »

$folder.update()

$web.Dispose()

Ce qui fait que si le client va à l’url https://server/sites/client, il sera automatiquement redirigé à https://server/sites/client/FR/Rapports/Rapport1.rdl.

Merci à mon collègue au support technique pour cette trouvaille.

Utiliser BIDS 2012 pour déployer vers Reporting Services 2008 (R1 ou R2)

Contexte

Si on prend pour acquis que Reporting Services 2008 est la première version acceptable pour le développement d’applications BI, il y a quand même plusieurs options pour le développement de rapports:

BIDS Version

Visual Studio

Description

2008 R1 2008 Installé à partir du DVD de SQL Server 2008.
2008 R2 2008 Installé à partir du DVD de SQL Server 2008 R2.
2012 2010 ou 2012 Installé à partir du DVD de SQL Server 2012. S’enregistre dans VStudio 2010 et / ou 2013.

Au niveau de la du schéma XML des fichiers de rapports (RDL), il y a une différence entre R1 et R2. La version 2012 n’apporte aucun changement de ce côté. Lors du déploiement vers un serveur, il est possible de spécifier R1 ou R2:

image

Au niveau des Dlls de Reporting Services installés dans le répertoire PrivateAssemblies de Visual Studio, le nom de l’assembly change entre les versions 2008 et la version 2012:

Ex. Microsoft.ReportingServices.ProcessingObjectModel.dll

BIDS Version

Assembly Version

File Version

2008 R1 10.0.0.0 10.0.1600.22
2008 R2 10.0.0.0 10.50.2500.0
2012 11.0.0.0 11.0.0.3360.12

Pour ceux qui sont familier avec le développement .NET, c’est la version de l’assembly qui compte lorsque l’on crée une référence vers un Dll. La version du fichier permet au développeur de corriger des problèmes sans forcer la recompilation de tous les programmes utilisant la librairie.

Description de la problématique

Ce qui (finalement) nous amène au sujet de ce blogue. Qu’est-ce qui arrive si l’on est dans la situation suivante:

  1. On utilise BIDS 2012;
  2. On déploie vers Reporting Services 2008 R1 ou R2;
  3. On utilise un Dll en support à nos rapports;
  4. Ce Dll réfère un Dll de Microsoft (ex. ProcessingObjectModel.dll) dans sa version 10 afin de fonctionner avec le serveur lors du déploiement.

Dans cette situation, le rapport déployé fonctionnera car le Dll du serveur aura le bon Assembly Name. Par contre, ni le débogage, ni la prévisualisation dans BIDS ne fonctionneront. L’erreur sera que la version 10.0.0.0 ne peut être trouvée. Effectivement, la version chargée par BIDS est 11.0.0.0.

Si vous changez la référence de votre Dll pour utiliser la version 11, vous aurez le problème inverse! Tout fonctionne localemenet mais pas une fois déployé! Sad smile

Solution: Binding Redirect

Ceux qui ont fait du ASP.Net sont peut-être habitué d’ajouter des Binding Redirect à leur Web.Config afin de rediriger les références à de vielles versions automatiquement à la toute dernière version disponible. Dans ce cas, c’est facile de savoir où l’ajouter (Web.Config de l’application Web).

Mais quand on exécute le rapport dans BIDS, à quel endroit doit-on ajouter le Binding Redirect? Vous avez répondu DevEnv.config? Ce n’est pas la bonne réponse!

Lorsque l’on utilise le Preview:

image

L’exécutable qui charge nos Dlls et leurs dépendances pour exécuter le rapport est PreviewProcessingService.exe:

image

Tandis que lorsqu’on veut déboguer un rapport:

image

Il s’agit plutôt de l’exécutable RSReportHost.exe

image

La solution au problème est donc d’ajouter ceci:

<dependentAssembly>
<assemblyIdentity name= »Microsoft.ReportingServices.ProcessingObjectModel » publicKeyToken= »89845dcd8080cc91″ culture= »neutral » />
<bindingRedirect oldVersion= »10.0.0.0″ newVersion= »11.0.0.0″ />
</dependentAssembly>

Aux fichiers:

  1. PreviewProcessingService.exe.configimage
  2. RSReportDesigner.configimage

Du répertoire PrivateAssemblies du Visual Studio dans lequel on utilise Report Designer.

Références

<bindingRedirect> Element
http://msdn.microsoft.com/fr-fr/library/eftw1fys(v=vs.110).aspx

SVP, aidez-nous à convaincre Microsoft d’améliorer la plate-forme Reporting Services

Un blogue est souvent une relation à sens unique. Après plus de 20000 hits, le nombre de commentaires est sous la barre des 100. Il reste qu’en 2011, mon blogue obtenait à peine 115 visites par mois et que je dépasse maintenant la barre des 1000 visites / mois.

Aujourd’hui, je sollicite votre aide pour améliorer la plate-forme Reporting Services de Microsoft. Rien de compliqué, juste de voter pour trois éléments sur la plate-forme Microsoft Connect:

  1. Dégradation de performance
  2. Suggestion: limite de l’historique configurable
  3. Suggestion: HTTP POST pour les Go to url

image

En effet, nous avons découvert un problème de dégradation de performance très important avec cette plate-forme. Dès lors que l’on utilise des actions de type “Go to report”:

image

La performance se met à dégrader (rapidement) de click en click. En gros, la plate-forme garde les sessions de toutes les exécutions précédentes actives à chaque fois que l’on clique sur un lien Go to report. Si cela ajoute 0.3 secondes à chaque exécution, éventuellement le coût payé pour maintenir les exécutions précédentes dépasse celui payé pour faire le rendu du rapport courant

La réponse de Microsoft est que cela leur permet d’implanter la fonctionnalité du back, vous savez ce bouton caché dans la barre d’outils de SSRS:

image

C’est très décevant et nous avons utilisé notre statut de partenaire Microsoft afin de demander un correctif à ce sujet. Les gens de Microsoft sont très profesionnels mais il faut d’abord les convaincre que ce n’est pas dans la manière d’utiliser ou configurer le produit. Puis, il faut les aider à reproduire le problème dans leur environnement et suggérer des hypothèses quant à la cause du problème.

Éventuellement, si vous êtes persuasifs et déterminés, le tout sera soumis à l’équipe de développement. Malheureusement, même si le problème est bien réel, cela finira probablement par un célèbre “this behavior is by design”. Plutôt que le correctif (hotfix) souhaité, la meilleure chose qu’on puisse espérer est une suggestion d’amélioration (interne) pour la prochaine version (on parle ici de SQL Server 2016 …).

Microsoft utilise le site Web connect pour recueillir des rapports de bogues ou de suggestions. La priorité des demandes internes et externes est basée sur la popularité de ces demandes. D’où votre implication potentielle.

Deux suggestions d’amélioration ont été soumises à l’équipe interne de Microsoft. Dans la documentation, il y a un lien vers les deux nouvelles entrées de Microsoft Connect que j’ai créées. Plus le vote est élevé, plus les chances sont bonnes pour que notre plate-forme préférée soit améliorée.

Il vous suffit de vous identifier avec un compte Microsoft afin de voter:

image

Faites-le pour vous, faites-le pour nous, mais faites-le! Smile

Et si vous êtes partenaire Microsoft, ou avez accès à du support de leur part, vous pourriez appeler et dire que vous vivez le même problème que celui décrit dans “dégradation de performance”. Vous pouvez mentionner le # de dossier 114031211258040 et éviter de démarrer à partir du début.

Merci d’avance et si vous êtes de bonne humeur, laissez un commentaire pour que je sache que vous avez voté après avoir lu cette entrée de blogue,

Au plaisir,

Frédérick

Virtualisation, plate-forme BI de Microsoft et économie d’énergie

Introduction

Les utilisateurs n’aiment pas attendre. Les entreprises comme Amazon et Google prennent cela très au sérieux, tel qu’indiqué dans cet article:

Surprising as all this may be, the implications of this impatience are even more shocking. Amazon‘s calculated that a page load slowdown of just one second could cost it $1.6 billion in sales each year. Google has calculated that by slowing its search results by just four tenths of a second they could lose 8 million searches per day–meaning they’d serve up many millions fewer online adverts.

On est d’accord sur le fait qu’un rapport BI est plus complexe à générer qu’une page listant les produits électroniques en solde. Mais les utilisateurs vont quand même exiger des performances acceptables, autrement ils n’utiliseront pas l’application.

C’est pourquoi vous devez faire passer les performances avant les économies d’énergie sur vos serveurs desservant la solution BI.

Plusieurs CPU modernes supportent des fonctions d’économie d’énergie afin de diminuer la consommation d’énergie quand les serveurs ne sont pas trop occupés. Cependant, cette mécanique ne réagit pas assez vite et fait en sorte que la peformance de l’application BI sera médiocre … sauf lors de pointes d’utilisation (charge).

The theory is in “Balanced” mode the CPU will run at a lower clock speed when it is under low workload, and bring more resources online when there is more to do. As great as it sounds, this won’t always be your best option. If your workload is incredibly bursty (quick moments of intense work), your SQL query speeds will take a hit, as by the time Windows has decided it needs more resources the work may already be done.

Symptômes

Si vous ne contrôlez que les paramètres du système d’exploitation “Guest” (machine virtuelle), voici les symptômes qui peuvent indiquer que l’hôte utilise des fonctions de gestion d’énergie:

  1. Si vous utilisez un outil de Benchmark, comme NovaBench, les résultats varient beaucoup d’un test à l’autre.
  2. Si vous demandez un rapport, les temps sont mauvais. Si vous demandez X rapports où X est le nombre de vCPU, les temps individuels sont meilleurs …

Recommandation

Il peut y avoir trois niveaux de configuration:

  1. BIOS
  2. Hypervisor
  3. OS

La recommandation est de soit désactiver la gestion de l’énergie dans le BIOS, soit l’activer en laissant le contrôle à l’OS (OS Controlled). Dans ce dernier cas, il faut s’assurer que l’hypervisor et / ou l’OS guest utilise High Performance.

Par défaut, VMWare ESX/ESXi utilise High Performance par défaut.

Par défaut, Windows Server 2008 R2 est à Balanced Performance, ce qui n’est pas désirable dans un environnement BI de Microsoft.

Références

Does CPU power management affect server performance?
http://serverfault.com/questions/94212/does-cpu-power-management-affect-server-performance

Consider CPU Power Optimization Versus Performance When Virtualizing
http://workinghardinit.wordpress.com/2011/06/20/consider-cpu-power-optimization-versus-performance-when-virtualizing/

Follow Up on Power Options for Performance When Virtualizing
http://workinghardinit.wordpress.com/2011/07/01/follow-up-on-power-options-for-performance-when-virtualizing/

Best Practices in Power Management
http://en.community.dell.com/techcenter/power-cooling/w/wiki/best-practices-in-power-management.aspx

(VMWare) Using CPU Power Management Policies
http://pubs.vmware.com/vsphere-4-esx-vcenter/index.jsp#managing_cpu_resources/c_managing_cpu_power_efficiency.html

Degraded overall performance on Windows Server 2008 R2
http://support.microsoft.com/kb/2207548/en-us

SQL Server on Power-Saving CPUs? Not So Fast.
http://www.brentozar.com/archive/2010/10/sql-server-on-powersaving-cpus-not-so-fast/

Why Microsoft Windows Server 2012 produces slow and inconsistent SQL query speeds
http://www.masterofmalt.com/software-development/blog/why-microsoft-windows-server-2012-produces-slow-and-inconsistent-sql-query-speeds/