Gino Abraham's Blog

Beginning Azure Machine Learning Nov 14

Free version for Azure ML Studio for Learning

Azure ML Cheat Sheet for Selecting ML Algorithm for your Experiments

Machine Learning Algorithm cheat sheet: Learn how to choose a Machine Learning algorithm.

Custom Role Claim Based Authentication on SharePoint 2013 Mar 21

We had a requirement in a project to authenticate users in a site collection based on Country claim presented by a User.

Below powershell sample is to add a US country claim value to a Visitors group of a site collection to allow any users from US to get authorized to view the site.

$web = Get-SPWeb "https://SpSiteCollectionUrl"
$claim = New-SPClaimsPrincipal -TrustedIdentityTokenIssuer “users” -ClaimValue “US" -ClaimType “
$group = $web.Groups[“GDE Home Visitors“]
$group.AddUser($claim.ToEncodedString(), “”, “US", “”)

Note : for this solution to work you we have used an ADFS solution which pull our calim values from Enterpise directory and sends SAML claim to SharePoint.

Powershell to monitor Server Resource and make html report for a set number of iteration and intreval Mar 21

While building a SharePoint farm for a project, i did load testing with VSTS.
Since my SharePoint farm was in a different domain than that of my Load test controllers, I had to monitor few performance counters to take a well informed decision while tuning the farm capacity.

Below powershell was developed by me to generate a html report for all the different servers at specified intervals.
The output html file will be generated in D Drive. 

#Array which contains the different Server names
$ServerList  = @('server01', 'server02', 'server03','Server04','Server05')

#Array which represents the role of the server
$ServerRole=@('WFE1', 'WFE2', 'Central Admin', 'WorkFlow1','WorkFlow2')

#Number of times this powershell should be executed
$runcount = 15;

$Outputreport = "<HTML><TITLE> Server Health Report </TITLE>
                     <BODY background-color:peachpuff>
                     <font color =""#99000"" face=""Microsoft Tai le"">
                     <H2> Server Health Report </H2></font>
                     <Table border=1 cellpadding=0 cellspacing=0>
                     <TR bgcolor=gray align=center>
                       <TD><B>Server Name</B></TD><TD><B>Server Role</B></TD>
                       <TD><B>Avrg.CPU Utilization</B></TD>
                       <TD><B>Memory Utilization</B></TD>
                       <TD><B>C Drive Utilizatoin</B></TD>

for($i=1; $i -le $runcount;$i++)

    $ArrayCount = 0
    ForEach($computername in $ServerList) 

        $role = $ServerRole[$ArrayCount]
        $ArrayCount = $ArrayCount  + 1
        Write-Host $i $computername $role 

        $AVGProc = Get-WmiObject -computername $computername win32_processor | 
        Measure-Object -property LoadPercentage -Average | Select Average
        $OS = gwmi -Class win32_operatingsystem -computername $computername |
        Select-Object @{Name = "MemoryUsage"; Expression = {“{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }}
        $vol = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'C:'" |
        Select-object @{Name = "C PercentFree"; Expression = {“{0:N2}” -f  (($_.FreeSpace / $_.Capacity)*100) } }
        $result += [PSCustomObject] @{ 
                ServerName = "$computername"
                CPULoad = "$($AVGProc.Average)%"
                MemLoad = "$($OS.MemoryUsage)%"
                CDrive = "$($vol.'C PercentFree')%"

        Foreach($Entry in $result) 
            if(($Entry.CpuLoad) -or ($Entry.memload) -ge "80") 
            $Outputreport += "<TR bgcolor=red>" 
            $Outputreport += "<TR>" 
            $Outputreport += "<TD>$($Entry.Servername)</TD> <TD>$role</TD>  <TD align=center>$($Entry.CPULoad)</TD><TD align=center>$($Entry.MemLoad)</TD><TD align=center>$($Entry.Cdrive)</TD><TD>$i</TD></TR>" 

        $result = $null

$Outputreport += "</Table></BODY></HTML>" 
$time = $(get-date -f MM-dd-yyyy_HH_mm_ss) 
$file = 'D:\' + $time + '.htm'

$Outputreport | out-file $file

Invoke-Expression $file

Powershell to make User Principle Name (UPN) of SharePoint user profile service editable Jan 14

Use the below script to make the UPN updatable.
This was handy incase of Site minder configuration for SharePoint where in there was no profile sync in place and a profile was provisioned as and when the user logs in for the first time.

Without UPN Sp2013 workflows and App will not work, we wrote a module to capture the first time login and updated the UPN with the identity claim under the same user's session.

$siteurl = "http://SPWebAPP:PortNo"
if ((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null )
Add-PsSnapin Microsoft.SharePoint.PowerShell
$site = Get-SPSite -Identity $siteurl -ErrorAction Stop
$ctx = [Microsoft.Office.Server.ServerContext]::GetContext($site)
$upm = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($ctx)
$upcm = New-Object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager($ctx)
foreach($property in $upm.Properties)
if($property.Name -eq "SPS-UserPrincipalName")
Write-Host $property.IsUserEditable
$property.IsUserEditable = $true;
$property.IsVisibleOnEditor = $false;
$property.IsVisibleOnViewer = $false;

Powershell to Migrate users from One Authentication provider to other in SharePoint Jun 10

We recently had a project in which we had to migrate a SharePoint farm from Siteminder-Custom STS authentication to ADFS 3.0

Siteminder - is a SAML Single Sign on Solution used by my customer which will authentication a user against any of the ID provider(Enterprise directory in our case) and will send SAML 2.0 back to the trusted applications. Since SharePoint doesnt understand SAML 2.0, they have used a Custom STS built on to do the transformation for SAML 2.0 to SAML 1.1 and send back the SAML claims to SharePoint.

When ADFS 3.0 was released and promised a very good support for App Model we decided to move away from Custom STS to ADFS 3.0. The ID provider remained same [ ED], Interface to ID provider remained same [ Siteminder R 12.5], just that we knocked off Custom STS and added ADFS 3.0 into the stack. Now ADFS will do the SAML Transformation for us. 

Now coming back to the topic. When we migrated from Custom STS to ADFS, we had to migrate the existing users. As the Identity provider was same, we dont have any changes in the user's actual identity, it just the user name prefix which is changed. [ From "i:05.t|siteminder|testuser1" to "i:0e.t|adfs|testuser1"]

We did the migration in 2 steps.

Step1 : migrated all the spusers by looping through all spuser from the sitecollection.

$url = ""

$userprefix = "i:0e.t|adfs|"
$users = Get-SPUser -web $url –Limit All
# Loop through each of the users in the web app
foreach($user in $users)
$userlogin = $user.UserLogin    
Write-Host $user.UserLogin    
$username = “”
#If the user has old user prefix, it will be modified to new prefix
$a = $userlogin.split('|')        
$username = $userprefix + $a[2]
Write-Host $userlogin " Changed as " $username " Name: " $user.Name " DisplayName :" $user.DisplayName
Move-SPUser –Identity $user –NewAlias $username -Confirm:$false -IgnoreSID

now that the users within the site collection is migrated we should migrate all users in the user profile service DB. if you have more than one site collection, run an outer loop which picks up all site collection and migrate user's within.

Step 2: Migrate users in profile Services DB

#Add SharePoint PowerShell SnapIn if not already added

if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null)
Add-PSSnapin "Microsoft.SharePoint.PowerShell"

#user prefix for the ADFS users
$userprefix = "i:0e.t|adfs|"
$site = new-object Microsoft.SharePoint.SPSite("");  
$ServiceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($site);  
#Get UserProfileManager from the My Site Host Site context
$ProfileManager = new-object  Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext)    
$AllProfiles = $ProfileManager.GetEnumerator()  
$profilCount = $ProfileManager.Count
$LoopCount = 0  
foreach($profile in $AllProfiles)  
$LoopCount = $LoopCount + 1    
$DisplayName = $profile.DisplayName      
$AccountName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value  
    $Farm = Get-SPFarm    
$a = $AccountName.split('|')        
$NewAccountName = $userprefix + $a[2]
write-host $AccountName " has been changed to " $NewAccountName ". Completed " $LoopCount " of $profilCount"
write-host "Finished."

SQl Query to check whether User Principal Name is Blank in SharPoint User Profiles DB Jun 10

User Principal Name /UPN is a property which is mandatory in SharePoint 2013 for Workflows and Provider Hosted Apps to work fine. When you employ a third party profile sync tool or a custom built one, the below SQL query will be quite handy to check whether the User Principal Name property is populated or not. 

SELECT    dbo.UserProfile_Full.UserID, dbo.UserProfile_Full.NTName, dbo.UserProfileValue.PropertyVal
FROM        dbo.UserProfile_Full WITH (NOLOCK) INNER JOIN
                    dbo.UserProfileValue WITH (NOLOCK)  ON dbo.UserProfile_Full.PartitionID = dbo.UserProfileValue.PartitionID AND           dbo.UserProfile_Full.RecordID = dbo.UserProfileValue.RecordID
WHERE     (dbo.UserProfileValue.PropertyID = 5090) AND (dbo.UserProfileValue.PropertyVal IS NULL OR
                    dbo.UserProfileValue.PropertyVal = '') 

Error: feature with ID is not installed in this farm and cannot be added to this scope Jun 09

While working on a SharePoint 2013 development server which is a multi server farm, we will face issues in doing auto deployments from visual studio. There is a workaround for the same posted here.

Accessing internet from Azure VM not working - Solution Below Jan 21

 I built an Azure Virtual network with one VM being a Domain Controller and few other VMs being SharePoint 2013 related Servers. When I logged in to any of my Virtual Machine Windows Servers running on this virtual network, I was unable to open web sites from internet. 

Missing Microsoft external DNS server was the root cause. while creating the virtual network i opted to go with my domain controller rather than the MS public DNS, hence the problem.

You can edit the Virtual Network, under the configure section - select external in the drop-down. An ip address will automatically get set. Save the change and you are done. 

Migrating TFS Project Collection From One TFS Server to other Jan 08

Migrating a TFS Project collection from one TFS environment to other needs to be planned before execution.

As part of the planning,  you should make sure the below points.

1. Make sure the source TFS server and Target TFS server are on same patch level

2. Make sure you are having same sql server version on Source and Target [Higher version at Target is also ok]

Once the above points are verified, follow the below steps.

1. Login to the TFS App sever (in Source), open TFS Admin Console. From the administration console, highlight the name of the collection that you want to delete, and then choose Detach Collection.From the administration console, highlight the name of the collection that you want to delete, and then choose Detach Collection.

Detach a team project collection

2. Login to the SQL server, take a full backup of the backup of the collection database. Once a backup is take you can reattach the collection, using attach collection link in the consol. Reattaching the collection is not mandatory if the source database is not going to be used.

3. Copy the database backup to the target TFS environment's SQL Server and restore the database from backup file.

4. Go to the TFS Admin console in the Target Server and click on attach collection. You will have all your team project in the target environment.

Sharepoint 2013 - Sorry, only tenant administrators can add or give access to this app Jan 07

If you get an error "Sorry, only tenant administrators can add or give access to this app" while adding your app to your site collection, you can add yourself as a local admin on the box not through some group rather user id under the administrator. This is a temporary fix suggested by MS. Hope something will come up or has already come up.Mine is an Aug CU.