Thursday, February 14, 2019

Configure People Picker to get users from domains


Some Points on User Profiles and People Picker
People Picker and UPS are not related. People Picker is used to select users for authentication and to assign permissions to them.  Profiles are used to store information to enrich the user experience.
A user profile consists of a set of user properties. User Profiles stores users’ information and are used to My Sites, Profile pages, People searching, Organizational charts, Expertise search, Social tagging and Audiences.
The People Picker gets its info directly from AD.  It will get users from the domain that the SharePoint server accounts are in. If Sync is configure then User Profiles are populated from AD, but that's not a requirement
The AD import option does not perform bidirectional synchronization. Changes made to SharePoint user profiles will not be synchronized back to the domain controller
To add additional AD domains they must be in Trust relationship with the domain that SharePoint is using.  Then you can configure it with PowerShell.  This article has the information.  Its for SP2013, but the settings are the same in 2016.
Script to give people picker Search Domain users
There are two ways can give access .  through sts adm and PowerShell way.
Please make sure you are have an application credential key need to generated  in each web front end and that should be unique across each web front end.
Below is the command to generate application credential key through PowerShell
$key = ConvertTo-SecureString "Password1" -AsPlainText -Force
[Microsoft.SharePoint.SPSecurity]::SetApplicationCredentialKey($key)

 Stsadm command
To see the existing settings. Here assume http://teamsites.domain1.com as the web application name.
Stsadm -o getproperty -pn peoplepicker-searchadforests –url  http://teamsites.domain1.com
To set the search domain
STSADM.EXE -o SetProperty -pn PeoplePicker-SearchADForests -pv "Forest:argous,domain1\svc-sp-admin,PWD;Forest:domain2.local,domain2\svc-sp-admin,PWD" -URL http://teamsites.domain1.com

PowerShell script

$wa= Get-SPWebApplication http://teamsites.domain1.com
$wa.PeoplePickerSettings.SearchActiveDirectoryDomains.clear()


$adsearchobj1 = New-Object Microsoft.SharePoint.Administration.SPPeoplePickerSearchActiveDirectoryDomain
$userpassword1 = ConvertTo-SecureString "PWD" -AsPlainText -Force
$adsearchobj1.DomainName = "ARGOUS"
$adsearchobj1.LoginName ="domain1\svc-sp-admin"
$adsearchobj1.IsForest = $true
$adsearchobj1.SetPassword($userpassword1)
$wa.PeoplePickerSettings.SearchActiveDirectoryDomains.Add($adsearchobj1)
$wa.Update()

$adsearchobj = New-Object Microsoft.SharePoint.Administration.SPPeoplePickerSearchActiveDirectoryDomain
$userpassword = ConvertTo-SecureString "PWD" -AsPlainText -Force
$adsearchobj.DomainName = "domain2.local"
$adsearchobj.ShortDomainName ="domain2"
$adsearchobj.IsForest = $true
$adsearchobj.LoginName ="domain2\svc-sp-admin"
$adsearchobj.SetPassword($userpassword)
$wa.PeoplePickerSettings.SearchActiveDirectoryDomains.Add($adsearchobj)
$wa.Update()




Tuesday, May 8, 2018







Script to change Stop Edit caption for SharePoint List quick edit.

user does not care to do stop after updating the record through quick edit. One of the reason they ignore the stop caption, as it looks like just change the edit mode. So it require to change the stop caption to Save Changes and Stop. it can be achieved by below jQuery code. (Found the recursive function not working . need to check on it)

<script type="text/javascript">
$(document).ready(function Dos(event) {
var abc = $("a[class*='ms-heroCommandLink']");
abc.click(function() {
var pqr= $("a[class*='ms-heroCommandLink']");
pqr.text("Save Changes and Stop ");
Dos();
    });

 
});

</script>

Monday, April 23, 2018

calculates free disk spaces in the windows servers and emails based on the parameter read from the configuration file

This VB script calculates free disk spaces in the windows servers and emails to administrator based on the parameter read from the configuration file. The script is designed to send mail  if free space less than  the than the warning level mentioned in the configuration file  This script can be scheduled through Task scheduler to check and notify periodically.

' Code for monitoring windows disk space
'Version History
'Date    version Modified by Details
'06/23/2015 1.0 San Mattel initial version to check DB space
'04/23/2018 1.1 San Mattel Included configuration file to read parameters
'==================================================================
' general constants and variable – NEED TO BE MODIFIED FOR YOUR ENVIRONMENT
'==================================================================
Const MailServerPort = "25" ' SMTP Port used at Mail server (25 is default)
Dim MailServer
Const LOCAL_HARD_DISK = 3
'Only enumerate physical disks (Not Network Drives)
Const HARD_DISK = 3
strVer ="1.1"
strModifyBy =" San Mattel"
strModifyDate = "4/23/18"
'==================================================================
' get current computer name (from system environment variables)
'==================================================================
 Function GetCurrentComputerName
set oWsh = WScript.CreateObject("WScript.Shell")
set oWshSysEnv = oWsh.Environment("PROCESS")
GetCurrentComputerName = oWshSysEnv("COMPUTERNAME")
End Function
'==================================================================
' Send a mail message
'==================================================================
 Sub SendMail(Sender, Recipient, Subject, Message)
Set objMessage = CreateObject("CDO.Message")
objMessage.Subject = Subject
objMessage.From = Sender
objMessage.To = Recipient
objMessage.TextBody = Message

objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2

'Name or IP of Remote SMTP Server
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = MailServer

'Server port (typically 25)
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = MailServerPort

objMessage.Configuration.Fields.Update

objMessage.Send
 End Sub

'==================================================================
' Begin main code
'==================================================================
str = ""
'Get Parameters from Configuration file
'======================================
Dim xmlDom
Dim objNode
dim IsLogging
dim IsMailSending
dim IsEcho
dim WarningPercentage
dim ToMailIds
dim IsWarning
'dim MailServer
'dim IsLogging
Set xmlDom = CreateObject("Microsoft.XMLDOM")
'xmlDom.async = "false"
strdir="FreeSpaceChcker.Config.xml"
If (Not xmlDom.load(strdir)) Then
    wscript.echo "Unable to load file '" & strdir & "'. "
    WScript.Quit(1)
End If
'read from xml configuration file
Set objNode = xmlDom.selectSingleNode("/root/property[@name='IsLogging']")
'if  isEmpty(objNode) Then
' wscript.echo "Unable to read property from file '" & strdir & "'. "
' WScript.Quit(1)
'end if 
' wscript.echo 
IsLogging = objNode.getAttribute("value") 
Set objNode = xmlDom.selectSingleNode("/root/property[@name='IsMailSending']")
IsMailSending = objNode.getAttribute("value") 

Set objNode = xmlDom.selectSingleNode("/root/property[@name='IsEcho']")
IsEcho = objNode.getAttribute("value") 

Set objNode = xmlDom.selectSingleNode("/root/property[@name='MailServer']")
MailServer = objNode.getAttribute("value") 

Set objNode = xmlDom.selectSingleNode("/root/property[@name='WarningPercentage']")
WarningPercentage = objNode.getAttribute("value") 

Set objNode = xmlDom.selectSingleNode("/root/property[@name='ToMailIds']")
ToMailIds = objNode.getAttribute("value") 

Set objNode=Nothing
Set xmlDom=Nothing
'====================================================================
' Get Disk details from current Server 
'===================================================================
strComputer = GetCurrentComputerName
 Set objWMIService = GetObject("winmgmts:" _
 & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
IsWarning ="FALSE"
Set colDisks = objWMIService.ExecQuery _
 ("Select * from Win32_LogicalDisk Where DriveType = " & HARD_DISK & "")

str = str & "Date :" & Date & " "& Time &" Server: " & strComputer & vbcrlf
 For Each objDisk in colDisks
 str = str & "Disk: "& objDisk.DeviceID & vbTab
 str = str & "Disk Size: "& FormatNumber(objDisk.Size/1073741824,2) &" GB"& vbTab
 'str = str & "Disk Size: "& objDisk.Size & vbTab
 str = str & " Free Disk Space: "& FormatNumber(objDisk.FreeSpace/1073741824,2) &" GB"
  usedSpaceGB = objDisk.Size - objDisk.FreeSpace 
  percentFree = FormatNumber((objDisk.FreeSpace / objDisk.Size) * 100, 2)
 str = str & " Free Percentage: "& percentFree &"% "
 'str = str & " Free Disk Space: "& FormatNumber(CLng(objDisk.FreeSpace / 1024 / 1024),0,,,-1) & " MB" & vbcrlf
 if WarningPercentage>percentFree then
IsWarning ="TRUE"
str = str & "**Need Attention**(Warning % is " & WarningPercentage & " )"
 end if
 str = str &vbcrlf
 Next

Vstr = str & vbcrlf

if ucase(IsLogging) = "TRUE" then ' if logging enabled in configuration file
Set objFSO=CreateObject("Scripting.FileSystemObject")

' How to write file
outFile="FreeSpaceChcker.log"

If (objFSO.FileExists(outFile)) Then
   Set objFile = objFSO.OpenTextFile(outFile,8,True)
Else
  Set objFile = objFSO.CreateTextFile(outFile,False)
End If
objFile.Writeline  Vstr
objFile.Close
end if
if ucase(IsEcho) ="TRUE" then 'if checking from command line
'wscript.echo   Vstr
'msgbox Vstr
end if
'Send the email
if UCase(IsMailSending) = "TRUE" and IsWarning ="TRUE" then ' send mail only if enabled from configuration file and reached warning level
 SendMail  "frommailid@domain.com",ToMailIds, "Drive Space Report: Server Name " & strComputer , str 
end if
++++++++++++++++++++++++++++++++++++++
XML FILE 
<?xml version="1.0"?>
<root>
   <property name="IsLogging" value="TRUE" Descriprion = "True or False for logging to a text file required or not"/>
   <property name="IsMailSending" value="FALSE" Descriprion = "True or False for Mail sending required or not"/>
   <property name="IsEcho" value="TRUE" Descriprion = "True or False value for Console echo required or not"/>
   <property name="ToMailIds" value="emailid@domain.com" Description ="Update value field with comma separated email id" />
   <property name="MailServer" value="mailserver" Descriprion = "Mail Server to use (SMTP)"/>
   <property name="WarningPercentage" value="10" Descriprion = "Warning Percentage for Disk Free Space"/>
</root>

Wednesday, June 28, 2017

SharePoint Large list issue, View does not work even after do data archival to meet the threshold limit for query criteria

SharePoint has resource throttles and limits that govern the amount of data and throughput that can be managed. The List View Threshold is by default, approximately 5000 items, and is set to allow users to work with large lists, but keep good performance.

Index and Filter views , Using folders to organize using document center site are the some of the workaround you can do to keep your queries within the limit.

As a last choice, with Server versions of SharePoint, is to change the limit. But this is not recommended , since a larger limit increases the possibility of affecting the performance for some or all users. 

Archiving the list is the widely using mechanism to over come this issue. However it is noticed that once the issue occur, even after you archive the list and make count of document less than the threshold limit for the query items, it does not work. This is because the old count is still using by the SharePoint process and it does not refresh. As a workaround on this issue, create a new list and move entire data to the list. You can find in the new list, views are started working.






Nintex Support Interaction - move item from a Document library folder to its root folder.


In Nintex workflow , Please let me know how can I move item from a Document library folder to its root folder.

Moving to sub folder , I have used update item and update name as foldername/filename. It works.
But how to move from subfolder to root ? update name with /filename does not work.


Do you have any other way to achieve it?

(JUN 2017)

In it's current state, Nintex Workflow does not have an action that will move or copy an item from a subfolder to the root.  The copy item action copies files to the root of a list/library, but cannot access subfolders.  I'm going to do some additional research tomorrow to see if there are any web services you can call to achieve the desired outcome.  If I can't find anything, I'll check with our senior engineers to see if they have any other thoughts regarding this.  In the meantime, let me know if you have any questions.
----------------------------------------------------------------------------------------------------------------
I want change what I sent yesterday, since we do have an action that can perform this task, although it's probably not the most ideal solution.  You can create a simple workflow that has the "Copy to SharePoint" action and select the location of the root folder.  Publish the workflow like this, then you can navigate to the file you want to move to root, click on the ellipsis (...) then click on the next ellipsis, click on Workflows, and run the workflow you created.  This will move the document from it's current location to the root (or wherever you specify).  Let me know if you have any questions.

By using copy to SharePoint, we can copy the file to root and can delete the original one. But by this approach, we lose all version history details. Is there any way to move file too root by keeping the version history?

Nintex Workflow does not have an action that will automatically do this for you.  However, what you are requesting is possible when using the "Call Web Service" action and utilizing 'author.dll'.  As this type of request will fall under a professional services offering, we can't offer much additional support, however please take a look at this blog post from one of our Technical Evangelists:


Let me know if you have any questions.

Saturday, May 20, 2017

Trigger SharePoint apply filter web part Action by Enter Key

    Trigger SharePoint apply filter web part Action by Enter Key


Apply Filters button that you can use to apply all the filters on the SharePoint page by a text filter or by a choice filter. One after the entry in the text filter, user need to press apply button to apply the changes. Usually customer demand for enter key action once after data input in the text filter.   You may need to include below Javascript/jquery code to achieve this. This can be included in the content editor or script editor web part.

In below example ctl00_ctl42_g_33a1df20_58a6_46b7_9656_ef6f32e42d5b_SPTextSlicerValueTextControl' is the Web part id of the Text filter web part and ctl00_ctl42_g_ec3e3fa8_03e7_4e09_b1f1_9951d415b638 is the ID of the filter web part, which you can fetch from the HTML source using developer tool for IE


<script src="/_layouts/15/STYLES/PNG.SharePoint.Core/js/jquery-1.9.1.min.js" type="text/javascript"></script>

<script language="javascript" type="text/javascript">
$(document).ready(function() {
$('#ctl00_ctl42_g_33a1df20_58a6_46b7_9656_ef6f32e42d5b_SPTextSlicerValueTextControl').keypress(function(event){
        var keycode = (event.keyCode ? event.keyCode : event.which);
        if(keycode == '13'){
           //Your Code that you want to execute or simply call the function RedirectUrl()
        event.preventDefault();
        ctl00_ctl42_g_ec3e3fa8_03e7_4e09_b1f1_9951d415b638_PostBack(event);
        }
    });

})

  
</script>

Screen Shot

Friday, October 14, 2016

Master- Details data handling in SharePoint (Parent Child Relation between Lists)

1            Master- Details data handling in SharePoint - A Background


Master-Detail data presentation is a type of data representation requires the presence of at least two data structures - master and detail. These tables are linked by a one-to-many relationship, i.e., a single row in the first data store can be related to one or more rows in the second data store, but a row in the second table can be related to only one row in the first table. Master and detail tables are also called parent and child tables. SharePoint prospective this relation is from a list item to many items to other list. Here it is explained different options to handle master and details data operations with SharePoint.

2           Master details Data Presentation in SharePoint

There is no out of the box controls available in SharePoint to present these type of data structure however below are some of the techniques to achieve this.  In this article it is assumed customer information stored in Installation List acting as master. Multiple meters for a customer are stored in ‘Meter Detail’ treat as the detail list. One to many relationship established between Installation list and Meter details list using the list column – Installation ID

2.1           Establish parent child relations using Data view web part connection.


Consider Master details are stored – ‘Installations’ list and details are stored in ‘MeterDetails’ and these lists are placed in a SharePoint Page using data view webapart.
In below view, multiple meter details for a customer is displayed by connecting Installation DVWP with Meter details DVWP.  (DVWP – data view web part)

And here is the web part connections established between the data view web parts Customer master and Meter Details.



And Installation ID is the field used here to connect these 2 lists.

Here InStallationID is Lookup column in MeterDetails List, Linked to InstallationID from Installations List as below.


2.2       Display Details in view by modifying display templates for column.


It will be neat and clear look if we include the required details view along with master view itself as below.


It is included in the master view itself by modifying column view display template.
Nintex form repeating section data got stored in a Multiple Line of text column in XML Format. Below is the format it stored. MeterInfo Column contain all meter details populated from Nintex Form.
<?xml version="1.0" encoding="utf-8"?><RepeaterData><Version /><Items><Item><ShowMeter type="System.Boolean">True</ShowMeter><GMAS type="System.String">GMAS</GMAS><ECNo type="System.String">EC1200</ECNo><AccountNo type="System.String">AN2300</AccountNo><MeterCoNo type="System.String">Mtr100</MeterCoNo><ECSerialNo type="System.String">ESSer</ECSerialNo><Rate type="System.Double">2323</Rate><_x0033_73c86b1-3111-490e-a842-34ca757901b4 type="System.String">#Value!</_x0033_73c86b1-3111-490e-a842-34ca757901b4><GasPressure type="System.String">GP111</GasPressure><MeterTypeCodeLKP type="System.String">1</MeterTypeCodeLKP><Index_Type_Old type="System.String">IT100</Index_Type_Old><RUID type="System.String">RU1000</RUID><EndCor type="System.String">EC200</EndCor><US type="System.String">US111</US><Full_GMAS type="System.String">FULL GMAS</Full_GMAS><Orig_Meter type="System.String">OR100</Orig_Meter><f9fb0908-0383-42bd-aa00-6a9280ecf3d0 type="System.String">IT100</f9fb0908-0383-42bd-aa00-6a9280ecf3d0><TerminalServerPort type="System.String">123</TerminalServerPort><MeterTypeCode type="System.String">fdf</MeterTypeCode></Item></Items></RepeaterData>


This XML need to be transformed in a tabular format to display the detail section along with master data.
Below is the script used to achieve this . This script is placed inside a content editor web part/Script Editor webpart,  inside the page.

<script type="text/javascript"
src="https://apps-dev10.piedmontng.com/sites/sitesurvey/SiteAssets/jquery-1.11.3.min.js" ></script> 
 <link rel="stylesheet" type="text/css" href="https://apps-dev10.piedmontng.com/sites/sitesurvey/SiteAssets/metertable.css">
<script type="text/javascript"> 

SPClientTemplates.TemplateManager.RegisterTemplateOverrides({ 
  Templates: { 
           Fields: { 
                'MeterInfo': {  
                    'View': repeatingSectionViewTemplate  
                 } 
           } 
  } 
}); 

function repeatingSectionViewTemplate(ctx) {
   var xml = ctx.CurrentItem["MeterInfo"]; 
  var decodedxml = xml.DecodeXMLNotation();  
   var htm = ""; 
   xmlDoc = $.parseXML( decodedxml ); 
   $xml = $( xmlDoc ); 
   $xml.find("Item").each(function() { 
     htm = htm + "<tr><td>" + $(this).find("MeterCoNo").text() + "</td><td>" + $(this).find("GMAS").text() + "</td><td>" + $(this).find("ECNo").text() + "</td><td>" + $(this).find("Rate").text() + "</td><td>" + +$(this).find("TerminalServerPort").text() +"</td></tr>"; 
   }); 
  return "<table border='1' class ='gridmtable'><tr><th><b>Meter</b></th><th><b>GMAS</b></th><th><b>ECNO</b></th><th><b>Rate</b></th><th><b>Port</b></th></tr>" + htm +"</table>"; 
}; 
 
//Replaces html notation to their equivalent xml escape characters. 
String.prototype.DecodeXMLNotation = function () { 
    var output = this; 
   if ($.trim(output) != "") { 
        output = output.replace(/&apos;/g, "'").replace(/&quot;/g, '"').replace(/&gt;/g, '>').replace(/&lt;/g, '<').replace(/&amp;/g, '&'); 
    } 
    else { 
       output = ""; 
   } 
    return output; 
}; 
 
</script> 

3           Update Master-details Data structure in SharePoint


The best way to modify Master-detail structure is by using Nintex or Infopath form. Here I have used Nintex Form.

3.1           Edit data using Nintex form


Details sections can be placed using repeating table control. This would help to manipulate items inside the detail section at run time.


Here Meter details are placed in repeating section, where run time can add more entries. (Add new Meter link in above figure)

3.2           Store Details in different list using  Nintex workflow


Now details are stored in the Master list  itself in XML format (given in section 2.2). Using a workflow these details can be pushed to MterDetails list , where each meter details can be stored in separate row. This workflow can be triggered over the update of Master record so that details are updated automatically, whenever there is a change. 
Below is the Nintex Workflow used to transfer meter details to a different list.


Steps:

1.    Store the meter info details in XML collection variable in Nintex
2.    Delete all existing records from Meter details
3.    Traverse to each details in XML collection
4.    Query XML and get field values
5.    Insert field values in Meter Details as below
6.    Repeat the operation for all items in collection