Key takeaways for #Consultants from #MSIgnite


Over the past two years Microsoft shifted its focus to deliver #CloudFirstMobileFirst Products to enterprise customers. All their product launches and announcements over past two weeks in #Build and #Ignite conferences resonates this strategy.

IMHO being a consultant working primarily on Microsoft technologies, I see this is the right time to evolve from Windows Active directory and start building against Windows Azure Active Directory as most of the advanced functionalities in core Microsoft products such as SharePoint 2016, Office 2016, Office 365, SQL server 2016 etc are targeted at WAAD as the premier identity provider to utilize Azure services such as Azure Storage, Azure service bus etc.

Here are some of the Key announcements and for more details download the videos from the links provided at end of this blog.

Product releases:
Microsoft announced release of several “2016” product lines which will hit General availability within next 12 months.
* SharePoint Server 2016
* Windows Server 2016
* SQL Server 2016
* System Center 2016
* Office 2016
* Windows 10

Azure Announcements:

#AzureStack:
Now Azure Resource Manager is the core component to create and manage all the Azure resources. Azure stack brings this Azure Resource Manager capabilities to on premise for building infrastructures based on Azure code base.
This will help the customers to build stage/test datacenters for UAT scenarios before migrating any workloads to Azure and also to build Azure ready infrastructures for future migration.

#AzureMigration
Azure site recovery evolved in to premier migration tool now supports direct migrations from VMWare to Azure or Hyper-V.

#AzureDNS
To manage DNS records using existing Azure Subscriptions.

#UserDefinedRouting
Enables a number of Virtual Appliance scenarios such as ‘NAT’ing, ‘Application firewall’, ‘Bring your own gateway’, ‘Intrusion protection systems’ etc

#ExpressRoutes
Express routes can now co-exist with Site to Site VPN and express routes is supported for #Office365

#Operations Manager Suite
To monitor any cloud, including your datacenter, Azure, AWS, Windows Server, Linux, VMware, and OpenStack.

References:

http://azure.microsoft.com/blog/2015/05/04/azure-shines-bright-at-ignite
http://azure.microsoft.com/blog/2015/05/05/new-networking-capabilities-for-a-consistent-connected-and-hybrid-cloud/ http://blogs.technet.com/b/server-cloud/archive/2015/05/04/introducing-microsoft-operations-management-suite.aspx

Office 365 Announcements:

#Office365Groups
Group managed at Office365 tenant level to ease the collaboration across every entity in Office 365 including Outlook and emails, Files and SharePoint, Messaging and Skype. All these information and interactions are surfaced in Delve using Office graph provides rich discoverability.

#Office2016
Real time co-authoring available on Office web apps are now extended to Office desktop clients.

#AzureDirectoryConnect
New and improved tool to setup ADFS, Web Proxy, Dir sync from the same interface.

#Unified API
single API endpoint and a single authentication flow for Office 365 Apps and addins.
https://graph.microsoft.com

#RemoteProvision
New community built tool to deploy Sites, Lists, Branding artifacts etc to SharePoint Online and SharePoint 2013 using CSOM and Rest interfaces

#Office365MigrationAPI
New migration API for high speed SharePoint on Prem to SharePoint Online migration utilizing Azure Storage.
Most of the ISV’s already support this.

#NetGenPortals
Integration with #SWAY to enable rich site creation experiences
Video portal integrated with Azure Media Services

#Skype
Easy Skype video meetings, skype broadcast, inetgration with hololens.

https://blogs.office.com/2015/05/04/modern-productivity-office-news-at-ignite
https://msdn.microsoft.com/en-us/office/office365/howto/office-365-unified-api-overview
https://channel9.msdn.com/blogs/OfficeDevPnP/Introduction-to-PnP-site-remote-provisioning-engine
http://en.share-gate.com/blog/what-is-the-office-365-migration-api
http://blog.cdw.com/whats-next-for-office-365-a-first-look-at-nextgen-portals

SharePoint 2016 Announcements

#Extended Boundaries
– Now SharePoint Content DB’s can be extended in TB’s.
– 100,000 site Collections Per Content DB’s
– List Items query threshold well beyond standard 5000 Items
– 10GB file uploads
– Indexing limitations pushed to 500 Million items

#Installation
– Windows Server 2012 R2, Windows 10, Windows Server 2016
– Role based install to simplify farm architectures
– User Services Role (Web Server)
– Robot services Role (App Server)
– Cache services Role (Distributed Cache)
– Special Services Role (ISV)
– Azure AD based authentication is supported to ease hybrid scenarios
– Zero downtime patching

#Cloud Search Service
– New Cloud Search service to unify SharePoint 2010, SharePoint 2013, SharePoint 2016 and SharePoint Online Indexes
– Delve Support On-Prem
– Cloud Search Service application for SharePoint 2013 editions

#UserProfileService
– Profile Sync uses Dir Sync technology instead of FIM OOB.
– External FIM can be integrated but OOB this is removed from UPS 2016

#HybridExtranet
Publish Intranet sites externally using ADFS and WAAD. No need to implement external identity providers.

#UI
– Responsive NextGen Portals
– Hybrid SP2016/0365 sites enabled via WAAD
– Improved Page load, Document download, document upload performance
– Durable links – Renaming or Moving the documents will not change the links.

SQL Server Announcements:

#Architecture changes
– Support up to 12 TB RAM
– Major changes to SQL engine to support in memory transactions on top of row based transactions to improve the performance
– Support for JSON data format

#Hybrid tables
– Stretched databases – Hybrid databases which extends portion to tables to SQL Azure
– Always Encrypted – data is encrypted by the client drivers, and unencrypted data is never seen by SQL Server

Windows Server Announcements

#Nano Server
– Light weight OS to build highly scalable Micro services and Apps
– Purpose built OS designed to run #Docker based containers and Hyper-V
– #Devops friendly OS. Supports #PowerShellDSC and #Chef

#WindowsServer2016
– Improvements to Hyper-V and Storage capabilities
– First class PowerShell DSC to ease #Devops.

I thank Vlad Catrinescu for building the PowerShell scripts to download #MSIgnite and #Build Videos and links the provided below

#PowerShell to download #Build2015 Videos: http://absolute-sharepoint.com/2015/05/the-ultimate-script-to-download-build-session-videos-and-slides.html

#PowerShell to download #MSIgnite Videos: http://absolute-sharepoint.com/2015/05/the-ultimate-script-to-download-microsoft-ignite-videos-and-slides.html

#Build2015 videos in #channel9: http://channel9.msdn.com/Events/Build/2015

#MsIgnite Videos in #Channel9: http://channel9.msdn.com/Events/Ignite/2015

TEZURE – Cost effective IOT apps using Javascript, Tessel & Azure


TEZURE

Cost effective IOT device using Javascript, Tessel & Azure

  • With the recent advancements to embedded hardware technologies, micro-controller product lines like Tessel, Espruino, RasberryPI etc where able to build compilers to breakdown Programs written in most popular programming languages in to Javascript, Python to Assembly code.

  • With Cloud providers such as Azure, AWS etc allow easy access to Queue and Storage services in a secured way, Industry experts predict that by 2020 the Internet of things (IoT) network will reach ~200 billion connected devices.

  • This blog post explains how to create a IOT device using Javascript, Tessel and Azure.

Tezure-SpyCam Demo

GitHub Site

Internet Of Things (IOT)

The Internet of Things (IoT) is the interconnection of uniquely identifiable embedded computing devices within the existing Internet infrastructure

Every Industry is getting Smarter

  • Smart Logistics
  • Smart Home
  • Smart Industries
  • Smart Healthcare
  • Smart Entertainment

With number of internet connected devices is exploding, there is a need for enabling and controlling services remotely.

Why IOT

  • Enabling services remotely
  • More targeted services
  • Data driven insights
  • Cost efficient

Tezure – SpyCam

  • Mobile controlled Surveillance Camera
    Scenario

Complexities

  • Design & Build
  • C, C++ for Sensors/Devices
  • C#, JAVA for cloud services
  • C#, Java, Obj C for Mobile devices
  • Connectivity (IP & Non IP devices)
  • Security – Identity and Authorization
  • Scalability

Keep it simple

  • Cost efficient
  • End to End solutions using pure Javascript
  • Tessel based devices/sensors
  • X platform mobile apps using Cordova/PhoneGap

  • REST based access to Azure Service bus/Azure Blobs

Hello Tessel!

Architecture
– Tessel is a microcontroller that runs JavaScript.
– It’s NodeJS-compatible and ships with Wifi built in.
– Its easier than ever make physical devices that connect to the web.
– Bridges the gap between Embedded devices and Web development

What Azure Offers

  • Azure Service bus
  • Queues, Topics, relays for messaging
  • Mobile services for push notifications and data tables
  • Azure store blobs
  • Images and Video storage
  • SAS (Shared Access Token) based authentication via REST
  • Supports Async access using NodeJS/Javascript

What PhoneGap Offers

  • PhoneGap is a free and open source framework that allows you to create X-Plat mobile apps using Web technologies
  • Mobile Apps can be created using HTML, Javascript and CSS
  • PhoneGap Build takes the pain out of compiling PhoneGap apps. Get app-store ready apps without the headache of maintaining native SDKs.

Tezure SpyCam – Architecture

Architecture

– Tessel

  • Tessel setup consists of Tessel Microcontroller and Camera module
  • Nodejs packages can be installed inside the tessel devices
  • Current set up consists of tesselPollingService() function which continously checks for new message on Azure queue
  • On new message, Camera module takes a picture and uploads to Azure blob storage
  • ‘Tesselate’ NPM module is used to load the Camera Module functions.
  • ‘Async’ NPM module is used to process the Polling cycles asynchronously
require('tesselate')(['camera-vc0706'], function (tessel, modules) {
console.log("Executed action 2 : After Camera Load : cycle no : " + count );
async.auto({
listen_messages: function (callback) {
var options = {...

Source Code

– Azure service bus

  • Azure queue receives messages from the Mobile applications and authenticated via SAS token
  • Azure Blob storage receives Images from tessel devices and authenticated via SAS
  • CORS rules can be added to Azure storage to enable X-domain requests

– PhoneGap App

  • Sends a surveillance request message with Device ID and time stamp
  • Polls the Azure Storage to retreive image with DeviceID and time stamp
  • Built with end to end javascript
    Source Code

PreRequisites

Few Gotcha’s

Provision OneDrive and set global administrator for OneDrive accounts in Office365


Recently I was working in a project to migrate all the SharePoint on-premise stuffs to Office365 including file shares. All the users had their on file shares mapped to their home drives on the PC. And the requirement is to move all the home drive data to OneDrive for Business and let the Global administrators to manage them efficiently.

Though Office 365 admin page have functionality to set Global admin for SharePoint sites, for OneDrive sites there is no OOB way to set a Global admin for all the sites. And its very tedious to set this manually for 400+ users.

Below script will help the IT pro’s to

1) Store the Office admin credentials

2) Provision OneDrive Sites for list of users

3) Assign administrator for provisioned OneDrive sites


try
{
  Get-MSOLCredentials
  Create-OneDriveSites
  Assign-Administrator
}

Download the script and change the Variables in “Input Variables” section to suit your environment


#Input Variables Begin
 #Credentials Store Location
 $credFile="C:\scripts\spbreed04cred.xml"
 #Log File location
 $Logfile = "C:\GG\OneDriveProvisionReport.log"
 #O365 Global admin
 $O365AdminAccount = "admin@spbreed04.onmicrosoft.com";
 #O365 Onedrive admin
 $OneDriveAdminAccount = "admin@spbreed04.onmicrosoft.com";
 #O365 Admin site URL
 $webUrl = "https://spbreed04-admin.sharepoint.com"
 #List of OneDrive users (seperated by CSV)
 $OneDriveUsers = "alans@spbreed04.onmicrosoft.com","admin@spbreed04.onmicrosoft.com" 
# Input Variables End

Click here the download the script.

Jumpstart AngularJS app development for O365 & E2E testing using Protractor


BDD (Behaviour Driven Development) and TDD ( Test Driven Development) has become cornerstone for modern Javascript app development but adopting these development strategies to SharePoint/Office 365 is not a trivial task.

I was intrigued to discover #Protractor, an AngularJS testing framework. With client side MVC/MVVM frameworks getting popular among the developers, AngularJS is the premier framework to develop Office365/SharePoint 2013 apps. Integrating TDD methodologies to app development model will help developers to deliver maintainable, flexible and extensible solutions and interfaces.

Below is the RevealJS presentation on how to create AngularJS based SharePoint app and execute end to end testing using #Protractor. I would like to thank Andrew Connell for introducing  RevealJS and AngularJS Apps

http://spbreed.github.io/index.html

This presentation includes training videos and Source code to build SharePoint
1) Expenses AngularApp(SharePoint hosted App)
2) ExpensesAngularApp test (NodeJS project created using VS2013)
1. Expenses AngularApp:
– This is a SharePoint hosted app developed using popular angular framework.
– Utilizes best patterns and practises for angular framework based on HotTowel framework and Learning-Path- Manager-Code-Sample from Andrew Connell.
– Uses ShareCoffee Javascript library to make REST calls to SharePoint
– Available as a nuget package for easy install
2. ExpensesAngularApp test:
– This Project runs on NodeJS and executes End to End testing on Expenses Angular App
– Utilizes Protractor framework to do E2E testing
– Jasmine is used to write test specs
Source code: https://github.com/spbreed/spangularapp

My favorite Nuget Packages for WebAPI /MVC apps


Its been a while since I worked on a hardcore ASP.NET / MVC projects. I was not aware of some of the sleek Nuget packages which are used elsewhere.

When you create MVC/WebAPI project by default VS adds packages.config to maintain a record of all the Nuget packages added to the solution.

You can either add packages directly to this file or via “Manage Nuget packages” or  through PowerShell.

Here are some of my favorite packages.

<?xml version="1.0" encoding="utf-8"?>
<packages>
 <package id="Antlr" version="3.4.1.9004" targetFramework="net451" />
 <package id="bootstrap" version="3.0.0" targetFramework="net451" />
 <package id="DotNetOpenAuth.AspNet" version="4.3.4.13329" targetFramework="net45" />
 <package id="DotNetOpenAuth.Core" version="4.3.4.13329" targetFramework="net45" />
 <package id="DotNetOpenAuth.OAuth.Consumer" version="4.3.4.13329" targetFramework="net45" />
 <package id="DotNetOpenAuth.OAuth.Core" version="4.3.4.13329" targetFramework="net45" />
 <package id="DotNetOpenAuth.OpenId.Core" version="4.3.4.13329" targetFramework="net45" />
 <package id="DotNetOpenAuth.OpenId.RelyingParty" version="4.3.4.13329" targetFramework="net45" />
 <package id="Elmah.Contrib.WebApi" version="1.0.9.0" targetFramework="net45" />
 <package id="elmah.corelibrary" version="1.2.2" targetFramework="net45" />
 <package id="Elmah.MVC" version="2.1.1" targetFramework="net45" />
 <package id="EntityFramework" version="6.1.1" targetFramework="net451" />
 <package id="jQuery" version="1.10.2" targetFramework="net451" />
 <package id="jQuery.UI.Combined" version="1.11.1" targetFramework="net45" />
 <package id="jQuery.Validation" version="1.13.0" targetFramework="net45" />
 <package id="JsonValue" version="0.3.0" targetFramework="net45" />
 <package id="knockoutjs" version="3.2.0" targetFramework="net45" />
 <package id="Microsoft.AspNet.Cors" version="5.2.0" targetFramework="net451" />
 <package id="Microsoft.AspNet.Membership.OpenAuth" version="2.0.1" targetFramework="net451" />
 <package id="Microsoft.AspNet.Mvc" version="5.2.2" targetFramework="net45" />
 <package id="Microsoft.AspNet.Razor" version="3.2.2" targetFramework="net45" />
 <package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net451" />
 <package id="Microsoft.AspNet.WebApi" version="5.2.0" targetFramework="net451" />
 <package id="Microsoft.AspNet.WebApi.Client" version="5.2.2" targetFramework="net45" />
 <package id="Microsoft.AspNet.WebApi.Core" version="5.2.2" targetFramework="net45" />
 <package id="Microsoft.AspNet.WebApi.Cors" version="5.2.0" targetFramework="net451" />
 <package id="Microsoft.AspNet.WebApi.HelpPage" version="5.2.2" targetFramework="net45" />
 <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.2" targetFramework="net45" />
 <package id="Microsoft.AspNet.WebPages" version="3.2.2" targetFramework="net45" />
 <package id="Microsoft.AspNet.WebPages.Data" version="3.2.0" targetFramework="net451" />
 <package id="Microsoft.AspNet.WebPages.WebData" version="3.2.0" targetFramework="net451" />
 <package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
 <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" />
 <package id="Microsoft.Data.Edm" version="5.6.0" targetFramework="net451" />
 <package id="Microsoft.Data.OData" version="5.6.0" targetFramework="net451" />
 <package id="Microsoft.Data.Services.Client" version="5.6.0" targetFramework="net451" />
 <package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.2.0" targetFramework="net45" />
 <package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.0" targetFramework="net45" />
 <package id="Microsoft.Net.Http" version="2.2.28" targetFramework="net45" />
 <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net451" />
 <package id="Microsoft.WindowsAzure.ConfigurationManager" version="2.0.3" targetFramework="net451" />
 <package id="Modernizr" version="2.6.2" targetFramework="net451" />
 <package id="MvcSiteMapProvider.MVC5" version="4.6.15" targetFramework="net45" />
 <package id="MvcSiteMapProvider.MVC5.Core" version="4.6.15" targetFramework="net45" />
 <package id="MvcSiteMapProvider.Web" version="4.6.1" targetFramework="net45" />
 <package id="netfx-Guard" version="1.2.0.0" targetFramework="net45" />
 <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net451" />
 <package id="Ninject" version="3.2.0.0" targetFramework="net45" />
 <package id="Ninject.Extensions.Logging" version="3.2.1.0" targetFramework="net45" />
 <package id="Ninject.Extensions.Logging.Log4net" version="3.2.1.0" targetFramework="net45" />
 <package id="Ninject.Web.Common" version="3.2.3.0" targetFramework="net45" />
 <package id="Ninject.Web.WebApi" version="3.2.2.0" targetFramework="net45" />
 <package id="NotFoundMvc" version="1.2.0" targetFramework="net45" />
 <package id="Pkcs12ProtectedConfigurationProvider" version="1.0.1" targetFramework="net45" />
 <package id="Postal.Mvc5" version="1.0.0" targetFramework="net45" />
 <package id="RazorEngine" version="3.4.1" targetFramework="net45" />
 <package id="Respond" version="1.2.0" targetFramework="net451" />
 <package id="ServiceStack.Text" version="4.0.31" targetFramework="net45" />
 <package id="System.Spatial" version="5.6.0" targetFramework="net451" />
 <package id="WebActivatorEx" version="2.0.1" targetFramework="net45" />
 <package id="WebApi.Core" version="0.3.0" targetFramework="net45" />
 <package id="WebApi.Enhancements" version="0.3.0" targetFramework="net45" />
 <package id="WebGrease" version="1.5.2" targetFramework="net451" />
 <package id="WindowsAzure.Storage" version="3.0.3.0" targetFramework="net451" />
</packages>

 

 

Powershell to change UPN/Sign-in names for Office 365 users


Issue:

In many cases after running the DirSync, Office 365 users are created with user@domain.onmicrosoft.com as Primary UPN.

WAAD_1

Anlaysis:

Internally MS maintains two domains for federated users. One is “user@domain.com” which is the replica of on premise AD and other with “user@domain.onmicrosoft.com” on Azure AD.

It seems if the Dirsync is ran without “E-Mail” attribute on AD, Azure assigns “onmicrosoft.com” as the default domain and primary UPN. Once the initial DirSync is complete, adding “Email” value to AD user object wont help.

WAAD_2

Resolution:

As usual PowerShell comes to rescue. Idea is to use Windows Azure AD Module for Powershell and change the UPN of all the objects with .onmicrosoft UPN.

Steps:

1) Download and Install Azure AD modules from http://technet.microsoft.com/library/jj151815.aspx

2) Connect to WAAD  service using Office 365 admin credentials

3) Filter all the users ending with .onmicrosoft.com  as their UPN

4) Change the UPN using Set-MsolUserPrincipalName

5) Generate reports before and after updates

Download the scripts here: Update-msolUpn.ps1 

Powershell:

#
#.SYNOPSIS ./Update-msolUpn.ps1
#PowerShell script to automate this task to change the all Office 365 user accounts with user@domain.onmicrosoft.com. to user@domain.com
#Install Azure AD modules from http://technet.microsoft.com/library/jj151815.aspx before running this.
#

#Get Modules
$env:PSModulePath=$env:PSModulePath+";"+"C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell"
$env:PSModulePath=$env:PSModulePath+";"+"C:\Windows\System32\WindowsPowerShell\v1.0\Modules\"
Import-Module Azure
Import-Module MSOnline

Get-Credential "office365admin@GSI.com" | Export-Clixml C:\GSI\scripts\GSIcred.xml #Store Credentials

#$count = 1 #For Testing the first result

$cred = Import-Clixml C:\GSI\scripts\GSIcred.xml

Connect-MsolService -Credential $cred

Get-MsolUser -All | Select-Object UserPrincipalName, Title, DisplayName, IsLicensed | export-csv –path C:\GSI\scripts\GSI_MSOL_Users_BeforeUpdate.csv

Get-MsolUser -All |
 Where { $_.UserPrincipalName.ToLower().EndsWith("onmicrosoft.com") } |
 ForEach {
 #if($count -eq 1) #For Testing the first result
 # {
 $upnVal = $_.UserPrincipalName.Split("@")[0] + "@GSI.com"
 Write-Host "Changing UPN value from: "$_.UserPrincipalName" to: " $upnVal -ForegroundColor Magenta
 Set-MsolUserPrincipalName -ObjectId $_.ObjectId -NewUserPrincipalName ($upnVal)
 $count++
 # }
 }

Get-MsolUser -All | Select-Object UserPrincipalName, Title, DisplayName, IsLicensed | export-csv –path C:\GSI\scripts\GSI_MSOL_Users_AfterUpdate.csv

 

Powershell to report memory leaks and assembly info on SharePoint 2013/2010 custom solutions.


Issue:

Recently I was involved in a task to troubleshoot performance related issues on a SharePoint farm. On analyzing the farm I found more than 50 WSP’s are deployed. On further analysis some of these solutions had two major performance related issues:

SharePoint Objects are not disposed properly:

Windows SharePoint Services object model contains objects which are not managed by ASP.Net windows garbage collector. Developers must take precautions when using these objects to avoid their long-term retention in memory in the Microsoft .NET Framework.

In scenarios in which you use SharePoint objects extensively—for example, in SharePoint sites that use custom Web Parts—you can cause the following unusual behaviors by not disposing of SharePoint objects when you are finished with them. This results in

  • Frequent recycles of the Windows SharePoint Services application pool, especially during peak usage
  • Application crashes that appear as heap corruption in the debugger
  • High memory use for Microsoft Internet Information Services (IIS) worker processes
  • Poor system and application performance

For more details refer this link

http://msdn.microsoft.com/en-us/library/aa973248(v=office.12).aspx

 Production solutions built in debug mode instead of release mode:

The default build setting during development is “Debug” mode and it is a common mistake to allow this development time setting to find its way onto production servers during deployment.  This can often leads to

  • The compilation of ASP.NET pages takes longer (since some batch optimizations are disabled)
  • Code can execute slower (since some additional debug paths are enabled)
  • Much more memory is used within the application at runtime
  • Improper recycles of App pools etc

More details here: http://weblogs.asp.net/scottgu/Don_1920_t-run-production-ASP.NET-Applications-with-debug_3D001D20_true_1D20_-enabled

Solution:

Though the only known solution is re-build these custom WSP’s using best practices, its important to develop a detailed report on each custom assemblies on GAC and provide a report to fix these issues. So idea is to build a powershell script to

1) Export all the WSP solutions

2) Extract the WSP’s

3) Run SPDispose check on each DLL

4) Identify the assembly is in “Debug” or release mode

5) Export the report to CSV

EXCEL's

 

 

Before running the script install SPDisposeCheck tool from here

http://download.microsoft.com/download/B/4/D/B4D279A0-E159-40BF-A5E8-F49ABDBE95C7/SPDisposeCheck.msi

Download this script here:
Get-SPDisposeReport.ps1

Powershell:

</pre>
<pre>
#
#.SYNOPSIS
#Creates SP Dispose report on all WSP's
#
#.EXAMPLE
#.\Get-SPDisposeReport.ps1
#

Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue

#Variables
$wspdir = "D:\WSP\WSPReport1" #Location to export all WSP's
$exportdir = "$wspdir\Export-$((get-date).toString('yyyyMMdd'))\"
$CSVLocation = "$wspdir\SPDisposeResults.csv"

#create directory
[IO.Directory]::CreateDirectory($wspdir)

#Function to export all WSP's
function Export-AllWSPs
{
 Write-Host Exporting solutions to $wspdir
 foreach ($solution in Get-SPSolution)
 {
 $id = $Solution.SolutionID
 $title = $Solution.Name
 $filename = $Solution.SolutionFile.Name
 Write-Host "Exporting $title to ¦\$filename" -nonewline
 try {
 $solution.SolutionFile.SaveAs("$wspdir\$filename")
 Write-Host "– done" -foreground green
 }
 catch
 {
 Write-Host "– error : $_" -foreground red
 }
 }

}

#Function to extract all WSP Packages
function Extract-AllWSPs
{
 #Retrieve the wsp files in this folder and subfolders
 $s = [system.IO.SearchOption]::AllDirectories
 $fileEntries = [IO.Directory]::GetFiles($wspdir,"*.wsp",$s);
 foreach($fullFileName in $fileEntries)
 {
 $fileName = $(Get-Item $fullFileName).Name;
 $dirName = $fileName.Replace(".wsp","");
 $extractPath = $exportdir + $dirName;
 $dir = [IO.Directory]::CreateDirectory($extractPath) 

 #uncab
 Write-Host "Export $fileName started" -ForegroundColor Red
 $destination = $extractPath
 C:\Windows\System32\extrac32.exe $fullFileName /e /Y /L $destination
 }

}

#Function to get Assembly details
function Get-AssemblyCustomProperty
 {
 param
 (
 $assembly,
 $TypeNameLike,
 $Property = $null
 )

 $value = $null
 foreach ($attribute in $assembly.GetCustomAttributes($false))
 {
 if ($attribute.GetType().ToString() -like "*$TypeNameLike*")
 {
 if ($Property -ne $null)
 {
 # Select-Object -ExpandProperty fails if property value is $null
 try {
 $value = $attribute | Select-Object -ExpandProperty $Property
 }
 catch {
 $value = $null
 }
 }
 else
 {
 $value = $attribute
 }
 break;
 }
 }

 $value
 }

#Function to report SP Dispose check results
Function Get-SPDisposeResults()
{

 #Pause for 5 secs to ensure extract is complete
 Start-Sleep -s 5
 $Dir = get-childitem $wspdir -recurse
 $List = $Dir | where {$_.extension -eq ".dll"}
 $List | ForEach-Object {

 [string]$report = & "C:\Program Files (x86)\Microsoft\SharePoint Dispose Check\SPDisposeCheck.exe" $_.fullname
 #remove repetitive strings
 $report = $report -replace "Note: This tool may report errors which are not actually memory leaks, otherwise known as false positives. Further investigation should be done to identify and correct real errors. It is designed to assist developers in making sure their code adheres to best practices for memory allocation when using SharePoint APIs. Please see the following for more information: http://blogs.msdn.com/rogerla/ http://msdn2.microsoft.com/en-us/library/aa973248.aspx http://msdn2.microsoft.com/en-us/library/bb687949.aspx", ""
 $build = "RELEASE";
 try {
 $info = @{}
 $assembly = [Reflection.Assembly]::LoadFile($_.FullName)
 $attr = $assembly.GetCustomAttributes([Diagnostics.DebuggableAttribute], $false)
 $info.IsJITTrackingEnabled = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Diagnostics.DebuggableAttribute' -Property 'IsJITTrackingEnabled'
 #$info.IsJITOptimizerDisabled = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Diagnostics.DebuggableAttribute' -Property 'IsJITOptimizerDisabled'
 #$info.DebuggingFlags = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Diagnostics.DebuggableAttribute' -Property 'DebuggingFlags'
 #Write-Host $_.FullName: +" IsJITTrackingEnabled "+ $info.IsJITTrackingEnabled
 #Write-Host $_.FullName: +" IsJITOptimizerDisabled "+ $info.IsJITOptimizerDisabled
 #Write-Host $_.FullName: +" DebuggingFlags "+ $info.DebuggingFlags

 } catch {
 throw $_
 }

 Write-Host $report

 # Create a hash table with all the data
 $hash = @{
 "Assembly" = $_.name
 "Report" = $report
 "Debug Mode enabled" = $info.IsJITTrackingEnabled

 }
 # Convert the hash to an object and output to the pipeline
 New-Object PSObject -Property $hash
 }
}

#Function calls
Export-AllWSPs
Extract-AllWSPs
Get-SPDisposeResults | Export-Csv -NoTypeInformation -Path $CSVLocation