Pages

Tuesday, August 27, 2013

Content Type Issues in SharePoint 2013



SharePoint 2013 developers are gonna have a hard time while dealing with content types. In previous version of SharePoint, SharePoint allowed existence of content type fields with similar internal names. Hence we were able to deploy the same field multiple times belonging to different content types.

In this new version of SharePoint 2013, it throws an error while deployment stating that ‘A Duplicate field <field_name> already exists’. Thus, in SharePoint 2013, Content Types being site-scoped features do not allow existence of fields with similar internal names.

That being said, we can always take some measures and precautions while creating and deploying our custom content types. I have jot down some steps to do the same as under -


- Make sure the sequence in which various content types are being deployed by looking at its manifest file.

- Include all the field definitions in the first content type and then re-use those field GUIDs in the subsequent content types. This approach would make it easy in terms of implementation

- Refer fields which are available out-of-the-box by SP 2013 (please note that these fields are different from what SP 2010 offered).


This would surely eliminate the duplicate field issue. Following are some of the content types and their respective fields available OOTB in a SharePoint 2013 blank site. The list is very long, hence i have mentioned only a few. You can get the entire list by running the following PowerShell script -

$site = Get-SPSite "http://<your_site_url_goes_here>/"
$web = $site.OpenWeb()
foreach($type in $web.ContentTypes)
{
"----------------------------------------------------------------------------------"
$type.Name
"----------------------------------------------------------------------------------"
foreach($field in $type.Fields)
{
$field | Select InternalName, Type
}
}

Here's an excerpt from the list -

------------------------------------------------------------------------------------
System
------------------------------------------------------------------------------------
ContentType                                   Computed

------------------------------------------------------------------------------------
Common Indicator Columns
------------------------------------------------------------------------------------
ContentType                                   Computed
KpiDescription                                    Note
KpiComments                                       Note
Value                                           Number
Goal                                            Number
Warning                                         Number
FormattedValue                                    Text
FormattedGoal                                     Text
FormattedWarning                                  Text
DetailLink                                         URL
LowerValuesAreBetter                           Boolean
UpdateError                                       Note
LastUpdated                                   DateTime
------------------------------------------------------------------------------------
Fixed Value based Status Indicator
------------------------------------------------------------------------------------
ContentType                                   Computed
KpiDescription                                    Note
KpiComments                                       Note
Value                                           Number
Goal                                            Number
Warning                                         Number
FormattedValue                                    Text
FormattedGoal                                     Text
FormattedWarning                                  Text
DetailLink                                         URL
LowerValuesAreBetter                           Boolean
UpdateError                                       Note
LastUpdated                                   DateTime
------------------------------------------------------------------------------------
SharePoint List based Status Indicator
------------------------------------------------------------------------------------
ContentType                                   Computed
KpiDescription                                    Note
KpiComments                                       Note
Value                                           Number
Goal                                            Number
Warning                                         Number
FormattedValue                                    Text
FormattedGoal                                     Text
FormattedWarning                                  Text
DetailLink                                         URL
LowerValuesAreBetter                           Boolean
UpdateError                                       Note
LastUpdated                                   DateTime
DataSource                                         URL
ViewGuid                                          Text
ValueExpression                                   Note
PercentExpression                              Boolean
AutoUpdate                                     Boolean
------------------------------------------------------------------------------------
Excel based Status Indicator
------------------------------------------------------------------------------------
ContentType                                   Computed
KpiDescription                                    Note
KpiComments                                       Note
Value                                           Number
Goal                                            Number
Warning                                         Number
FormattedValue                                    Text
FormattedGoal                                     Text
FormattedWarning                                  Text
DetailLink                                         URL
LowerValuesAreBetter                           Boolean
UpdateError                                       Note
LastUpdated                                   DateTime
DataSource                                         URL
ValueSheet                                        Text
ValueCell                                         Text
GoalSheet                                         Text
GoalCell                                          Text
WarningSheet                                      Text
WarningCell                                       Text
GoalFromWorkBook                               Boolean
WarningFromWorkBook                            Boolean
AutoUpdate                                     Boolean
------------------------------------------------------------------------------------
SQL Server Analysis Services based Status Indicator
------------------------------------------------------------------------------------
ContentType                                   Computed
KpiDescription                                    Note
KpiComments                                       Note
Value                                           Number
Goal                                            Number
Warning                                         Number
FormattedValue                                    Text
FormattedGoal                                     Text
FormattedWarning                                  Text
DetailLink                                         URL
LowerValuesAreBetter                           Boolean
UpdateError                                       Note
LastUpdated                                   DateTime
DataSource                                         URL
Trend                                           Number
KpiStatus                                       Number
DisplayFolder                                     Text
KPI                                               Text
IncludeHierarchy                               Boolean
AutoUpdate                                     Boolean
------------------------------------------------------------------------------------
Item
------------------------------------------------------------------------------------
ContentType                                   Computed
Title                                             Text
------------------------------------------------------------------------------------
Circulation
------------------------------------------------------------------------------------
ContentType                                   Computed
Title                                             Text
Body                                              Note
DueDate                                       DateTime
Confidential                                   Boolean
AllowEditing                                   Boolean
V4SendTo                                          User
Confirmations                                     Text
V3Comments                                        Note
WhatsNew                                       Boolean
------------------------------------------------------------------------------------
New Word
------------------------------------------------------------------------------------
ContentType                                   Computed
Title                                             Text
IMEDisplay                                        Text
IMEComment1                                       Text
IMEComment2                                       Text
IMEComment3                                       Text
IMEUrl                                             URL
IMEPos                                          Choice
------------------------------------------------------------------------------------
Category
------------------------------------------------------------------------------------
ContentType                                   Computed
Title                                             Text
CategoryDescription                               Text
CategoryImage                                      URL
TopicCount                                     Integer
ReplyCount                                     Integer
LastPostBy                                        User
LastPostDate                                  DateTime
------------------------------------------------------------------------------------
Site Membership
------------------------------------------------------------------------------------
ContentType                                   Computed
Title                                             Text
Member                                            User
MemberStatus                                    Choice
MemberStatusInt                                Integer
------------------------------------------------------------------------------------
Community Member
------------------------------------------------------------------------------------
ContentType                                   Computed
Member                                            User
MemberStatus                                    Choice
MemberStatusInt                                Integer
Title                                             Text
LastActivity                                  DateTime
NumberOfBestResponses                           Number
NumberOfDiscussions                             Number
NumberOfReplies                                 Number
NumberOfRepliesToReachNextLevel                 Number
ReputationScore                                 Number
HideReputation                                 Boolean
------------------------------------------------------------------------------------
WorkflowServiceDefinition
------------------------------------------------------------------------------------
ContentType                                   Computed
Title                                             Text
WSGUID                                            Guid
WSPublishState                                 Integer
WSPublishError                                    Note
WSDisplayName                                     Text
WSDescription                                     Text
FormData                                          Note
------------------------------------------------------------------------------------
InviteUser
------------------------------------------------------------------------------------
ContentType                                   Computed
Title                                             Text
EmailTemplate                                     Note
LoggedUser                                        Text
SentAt                                            Text
InviteUser_Recipients                             Note
CurrentSiteCollection                             Text
------------------------------------------------------------------------------------
Health Analyzer Rule Definition
------------------------------------------------------------------------------------
ContentType                                   Computed
Title                                             Text
HealthRuleScope                                 Choice
HealthRuleService                                 Text
HealthRuleType                                    Text
HealthReportCategory                            Choice
HealthRuleSchedule                              Choice
HealthRuleCheckEnabled                         Boolean
HealthRuleAutoRepairEnabled                    Boolean
HealthRuleVersion                                 Text


Sunday, August 25, 2013

Creating or Modifying Search Topology in SharePoint 2013


The Search service application introduced in SharePoint 2013 is different than that of SharePoint 2010 in more ways than just one.

To start with, SharePoint 2013 uses the web-based interface to change the current status of the topology. It can only be done by using Windows PowerShell. SharePoint Server 2010 also included a web-based option for changing the topology.

The Search Query web service is deprecated in SharePoint 2013. Search in SharePoint 2013 supports FAST Query Language (FQL) syntax and Keyword Query Language (KQL) syntax for custom search solutions. You cannot use SQL syntax in custom search solutions - FullTextSQLQuery was used for this purpose in SharePoint 2010. In SharePoint 2013, this class has been deprecated. It doesn't even support backward compatibility.

Custom search solutions that use SQL syntax with the Query object model and the Query web service that were created in earlier versions of SharePoint Server do not work when you upgrade them to SharePoint 2013. If you submit queries by using these applications, you will receive an error.

There are a lot more features which have been deprecated in SP 2013, thorough details of which you can find here.

The information I am going to share with you will help you configure your search service application to get it up and running for your sites. We will start with changing the default search topology and then move on the Search Service application configuration which I would cover in a different post. Please note that creating a new search topology is not a mandate if the Search is configured properly on your server.


Creating a Search Topology / Changing the Default Search Topology

For demonstrative purposes and making things easy to understand, I'll consider a farm consisting of only server. For multi-server approach, you may refer this link.

- Ensure that no crawls have been started and that the search index is empty on the server that hosts Central Administration.

- Verify that the user account that is performing this procedure is an administrator for the Search service application.

- In Central Administration, in the Application Management section, click Manage Service Applications.

- On the Manage Service Applications page, in the list of service applications, click the Search service application.

- Verify that the search index is empty. On the Search Administration page, under System Status, verify that Searchable items displays "0". Here, if the Searchable items are not zero, discontinue this process and make sure you click on 'Reset Search Index'. Only then move on with the next steps.

- Verify that no crawls have been started. On the Search Administration page, under Crawling, click Content Sources. On the Manage Content Sources page, verify that the Status column for any existing content source displays Idle.

- Start a SharePoint 2013 Management Shell on one of the servers in the farm.

- Specify the new servers you want to add search components to, start a search service instance (ssi) on these servers and create references to the search service instances. In this procedure we have used the example host name "server_name" for the server. At the Windows PowerShell command prompt, type the following command(s):

$host = Get-SPEnterpriseSearchServiceInstance -Identity "server_name"
Start-SPEnterpriseSearchServiceInstance -Identity $host


- Wait until all the search service instances are running. At the Windows PowerShell command prompt, type the following commands until the commands return the state "Online" for the search service instance:

Get-SPEnterpriseSearchServiceInstance -Identity $host

- Create a new search topology and a reference to the new search topology. At the Windows PowerShell command prompt, type the following command(s):

$ssa = Get-SPEnterpriseSearchServiceApplication 
$newTopology = New-SPEnterpriseSearchTopology -SearchApplication $ssa

- Add all the search components to the new search topology. The following Windows PowerShell commands will create the search components of the new topology and assign them to the new server.
In this small enterprise search topology there is one index partition, index partition 0, to cater for a maximum of ten million items. This is indicated with the parameter -IndexPartition in the command New-SPEnterpriseSearchIndexComponent. 

At the Windows PowerShell command prompt, type the following command(s):

New-SPEnterpriseSearchAdminComponent -SearchTopology $newTopology -SearchServiceInstance $host

New-SPEnterpriseSearchCrawlComponent -SearchTopology $newTopology -SearchServiceInstance $host

New-SPEnterpriseSearchContentProcessingComponent -SearchTopology $newTopology -SearchServiceInstance $host

New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchTopology $newTopology -SearchServiceInstance $host

New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $newTopology -SearchServiceInstance $host

New-SPEnterpriseSearchIndexComponent -SearchTopology $newTopology -SearchServiceInstance $host -IndexPartition 0

 - Activate the new search topology. At the Windows PowerShell command prompt, type the following command:

Set-SPEnterpriseSearchTopology -Identity $newTopology

 - Verify that the new search topology is active. At the Windows PowerShell command prompt, type the following command:

Get-SPEnterpriseSearchTopology -SearchApplication $ssa

The command returns an overview of active and inactive topologies, in this example:

TopologyId     : 6E680C1A-14F3-4280-8524-CDBC52E0AEF2
CreationDate   : 8/24/2013 7:45:00 AM
State          : Active
ComponentCount : 6

The new active topology from this example will have a component count of six.

 - Verify that all components of the new search topology are running correctly. At the Windows PowerShell command prompt, type the following command:

Get-SPEnterpriseSearchStatus -SearchApplication $ssa -Text

This command should return a list of all the active search components. The state of the active search components should be displayed as Active.

Voila ! Your topology is now ready for use :)

Thursday, August 22, 2013

Keyword Query in SharePoint 2013


With the release of SharePoint 2013, a lot has changed with the way things were being implemented. For instance, till SP 2010, it was possible to use FullTextSQLQuery to query the results obtained from SharePoint Search Crawls. It was much easier to use considering its syntax was similar to SQL.

Now, in SP 2013, it has been deprecated. There is not even a provision to support backward compatibility FullTextSQLQuery on SharePoint 2013 platform. The only place we developers can now resort to is the KeywordQuery. It can be implemented in the pretty much same way as it was implemented on SP 2010.

So, let me take this opportunity to shed some light on Keyword Query and how it can be used to query crawl results.

KeywordQuery supports two syntax for query string formation –
  1. Keyword Query Language (KQL) and
  2. FAST Query Language (FQL)

KQL is the default syntax which can be used. FQL needs to be explicitly enabled to use it. Following is the sample code which showcases both these approaches –

Approach 1 – KeywordQuery using KQL

static void Main(string[] args)
{
SPSite site = new SPSite("url_whose_results_you_wish_to_query");
SearchServiceApplicationProxy proxy = (SearchServiceApplicationProxy)SearchServiceApplicationProxy.GetProxy(SPServiceContext.GetContext(site));

using (KeywordQuery keywordQuery = new KeywordQuery(proxy))
   {
    keywordQuery.ResultsProvider = SearchProvider.Default;
    keywordQuery.StartRow = 0;
    keywordQuery.RowLimit = 500;
    keywordQuery.EnableStemming = true;
    keywordQuery.TrimDuplicates = false;
    keywordQuery.AuthenticationType = QueryAuthenticationType.PluggableAuthenticatedQuery;
    keywordQuery.Culture = CultureInfo.CurrentCulture;
    keywordQuery.KeywordInclusion = KeywordInclusion.AllKeywords;
    keywordQuery.QueryText = "scope:\"All Sites\" AND (contentclass:\"STS_Site\" OR contentclass:\"STS_Web\")";
    keywordQuery.SelectProperties.Add("path");
    keywordQuery.SelectProperties.Add("title");
    keywordQuery.SelectProperties.Add("contentclass");
    SearchExecutor executor = new SearchExecutor();
    ResultTableCollection resultTableCollection = executor.ExecuteQuery(keywordQuery);
    var resultTables = resultTableCollection.Filter("TableType", KnownTableTypes.RelevantResults);
    var resultTable = resultTables.FirstOrDefault();
    }
}


In the above code snippet, note the SPSite URL which should be URL of the site whose search results you wish to query.

In the previous version of SharePoint, RowLimit actually had no limits. But in newer versions, it has the maximum limit of 500. This number is however configurable if we run PowerShell script on the SharePoint Search Service Application.

Also, note that now, we cannot directly execute the Query. Earlier we would simply call the method

KeywordQuery.ExecuteQuery()

and it would fetch the results for us. Now, SP 2013 introduces a new class SearchExecutor specifically built to execute queries. So in order to run a query, we would first have to initialize this class and then call its ExecuteQuery method on our KeywordQuery.

ResultType class and its corresponding KeywordQuery.ResultType property are also now obsolete. Instead we would now need to call a filter method on our resultant collection to get our desired results (see the code above).

Notice the query text in the above snippet. It is much similar to what was used in SP 2010.

Another important thing to notice above is that we would need to explicitly specify which columns should be returned in the query result. Of course, it was done earlier and in much simpler fashion using FullTextSQLQuery. Now, we would need to call the method –

keywordQuery.SelectProperties.Add("<column_name>")

to return this column in the result table collection.


Approach 2 – KeywordQuery using FQL
  
static void Main(string[] args)
{
    SPSite site = new SPSite("<url_whose_results_you_wish_to_query>");
    SearchServiceApplicationProxy proxy = (SearchServiceApplicationProxy)SearchServiceApplicationProxy.GetProxy(SPServiceContext.GetContext(site));
    using (KeywordQuery keywordQuery = new KeywordQuery(proxy))
    {
        keywordQuery.ResultsProvider = SearchProvider.Default;
        keywordQuery.SourceId = new Guid("<RESULT_SOURCE_GUID>");
        keywordQuery.EnableFQL = true;
        keywordQuery.StartRow = 0;
        keywordQuery.RowLimit = 500;
        keywordQuery.EnableStemming = true;
        keywordQuery.TrimDuplicates = false;
        keywordQuery.AuthenticationType = QueryAuthenticationType.PluggableAuthenticatedQuery;
        keywordQuery.Culture = CultureInfo.CurrentCulture;
        keywordQuery.KeywordInclusion = KeywordInclusion.AllKeywords;
        keywordQuery.QueryText = "and(scope:string(\"All Sites\"), or(contentclass:string(\"STS_Site\") , contentclass:string(\"STS_Web\")))";
        keywordQuery.QueryText = "and(scope:string(\"All Sites\"), or(contentclass:STS_Site, contentclass:STS_Web))";
        keywordQuery.SelectProperties.Add("path");
        keywordQuery.SelectProperties.Add("title");
        keywordQuery.SelectProperties.Add("contentclass");
        SearchExecutor executor = new SearchExecutor();
        ResultTableCollection resultTableCollection = executor.ExecuteQuery(keywordQuery);
        var resultTables = resultTableCollection.Filter("TableType", KnownTableTypes.RelevantResults);
        var resultTable = resultTables.FirstOrDefault();
    }
}


Notice the highlighted lines of code in Cyan color in the above snippet. Only those lines are different from what we saw earlier. Rest all settings remain the same. in the above example, i have used two types of FQL queries. You can use either of them.

SourceID needs to be explicitly mentioned here because in SharePoint 2013, we need to create a custom Result Source which possesses a different query string in it. I would cover creating Result Sources in SharePoint 2013 in a separate post.


Happy coding !!

WCF - Custom Binding to support SOAP1.2



WCF Service Binding determines how a Client or rather a Consumer of the WCF service is going to communicate with it. There are many bindings available. Mostly used ones are –

  1. WSHTTPBinding
  2. WebHTTPBinding
  3. Custom Binding

This post talks about Custom Binding and how it can be implemented to support SOAP 1.2 standards. Please note that WSHTTPBinding supports SOAP 1.2 by default. However, some firms find security-related issues with using this binding. The WS-Addressing functionality is enabled for this binding which cannot be changed.
Let us first look at the Web.config settings required to implement CustomBinding –

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <bindings>
      <customBinding>
          <binding name="UPAHubAccessWS12">
            <textMessageEncoding messageVersion="Soap12" />
            <httpsTransport requireClientCertificate="True" />
          </binding>
        </customBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="BehaviorName" name="ServiceName">
        <endpoint address=""  binding="customBinding" bindingConfiguration="BindingName" contract="ServiceInterfaceName" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name=" BehaviorName">
          <serviceMetadata httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
</system.serviceModel>

Please make note of the following values specified in the above configuration –
- BehaviorName – Denotes the service behavior configuration to be used for the WCF service. Here, it allows HTTPS request (required for service hosted on HTTPS).

- ServiceName – Denotes the name of your WCF service

- BindingName – Denotes the name you give to your binding configuration

- ServiceInterfaceName – Denotes the name of the Interface class or the contract of your WCF service.


In one of my posts, I had created the client programmatically using C#, the above configuration settings correspond to the same code used but the initialization part is done at the Client’s end.



Wednesday, August 21, 2013

Initializing WCF client programmatically


Usually, developers follow the practice of making use of Web.config to set all the configuration values for a WCF client. But in some cases, that approach is not always applicable.

For example, if we are trying to call a WCF service through some SharePoint page which was deployed using a feature, in this case, the Web.config resides at a different location and hence the code would not be able to fetch this data.

The more desired approached is to initialize it through your code itself.

Below is the code which I had used to initialize a WCF Client for a service which uses Custom Binding and SOAP 1.2

using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

public static CustomBinding GetBinding()
{
   CustomBinding binding = new CustomBinding();
   binding.Name = "Name_of_your_binding";
   binding.CloseTimeout = TimeSpan.Parse("00:05:00");
   binding.OpenTimeout = TimeSpan.Parse("00:05:00");
   binding.ReceiveTimeout = TimeSpan.Parse("00:10:00");
   binding.SendTimeout = TimeSpan.Parse("00:10:00");
   binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap12, System.Text.Encoding.UTF8));
   HttpsTransportBindingElement hbe = new HttpsTransportBindingElement();
   hbe.RequireClientCertificate = true;
   hbe.AllowCookies = false;
   hbe.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;
   hbe.BypassProxyOnLocal = false;
   hbe.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
   hbe.KeepAliveEnabled = true;
   hbe.ManualAddressing = false;
   hbe.MaxBufferPoolSize = Convert.ToInt64(int.MaxValue);
   hbe.MaxBufferSize = int.MaxValue;
   hbe.MaxReceivedMessageSize = Convert.ToInt64(int.MaxValue);
   hbe.ProxyAuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;
   hbe.Realm = "";
   hbe.TransferMode = TransferMode.Buffered;
   hbe.UnsafeConnectionNtlmAuthentication = false;
   hbe.UseDefaultWebProxy = true;
   binding.Elements.Add(hbe);
   return binding;
}


public static EndpointAddress GetEndpointAddress()
{
   EndpointAddress endpoint = new EndpointAddress(<URL_string>);
   return endpoint;
}


public static void Main(string[] args)
{
   CustomBinding binding = GetBinding();
   EndpointAddress endpoint = GetEndpointAddress();
   <Proxy_Client_Name> client = new <Proxy_Client_Name>(binding, endpoint);
}

Above, Proxy_Client_Name denotes the name specified for your Client Class in the WCF Service Proxy file which you might have generated from your WSDL or must have been handed over to you by the WCF service providers.

One of the drawbacks of using this approach is that you cannot change the configuration settings at run-time. Apart from that, I would personally suggest all of you to go ahead with it :) ...  

Monday, August 19, 2013

Console Application to store User Profile Data into a CSV file


This post is gonna help you create a simple console application which would query the User Profile Application of your SharePoint farm and store its user profile data into a CSV file.

Let us first create two public classes - one corresponding to a CSV row and the other corresponding to the Writer object -

Class 1 - extended from a List of type string
 
 public class CsvRow : List<string>
{
    public string LineText { get; set; }
}

Class 2 - extended from StreamWriter class. It also includes logic to handle special characters in data

public class CsvFileWriter : StreamWriter
{
    public CsvFileWriter(Stream stream): base(stream)
    {
    }

    public CsvFileWriter(string filename): base(filename)
    {
    }

    public void WriteRow(CsvRow row)
    {
        StringBuilder builder = new StringBuilder();
        bool firstColumn = true;
        foreach (string value in row)
        {
// Add separator if this isn't the first value
          if (!firstColumn)
              builder.Append(',');
// Implement special handling for values that contain comma or quote
// Enclose in quotes and double up any double quotes
          if (value.IndexOfAny(new char[] { '"', ',' }) != -1)
              builder.AppendFormat("\"{0}\"", value.Replace("\"", "\"\""));
          else
              builder.Append(value);
          firstColumn = false;
        }
        row.LineText = builder.ToString();
        WriteLine(row.LineText);
    }
}


Now the next step's the very basic, creating the Service Context object in the main function as follows -

SPServiceContext _servicecontext = SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, new SPSiteSubscriptionIdentifier(Guid.Empty));

UserProfileManager CurrentUserProfileManager = new UserProfileManager(_servicecontext);

UserProfileConfigManager CurrentUserProfileConfigManager = new UserProfileConfigManager(_servicecontext);


Now, we would create an object of the above custom CsvFileWriter class and include the rest of the code in it -

using (CsvFileWriter writer = new CsvFileWriter(@"E:\Results.csv"))
{
    var Profiles = CurrentUserProfileManager.GetEnumerator();
    CsvRow columnRow = new CsvRow();
    columnRow.Add("Property1");
    columnRow.Add("Property2");
    columnRow.Add("Property3");
    writer.WriteRow(columnRow);
    while (Profiles.MoveNext())
    {
         UserProfile profile = (UserProfile)Profiles.Current;
         CsvRow row = new CsvRow();
         row.Add(profile["<Property1_Name>"].Value.ToString());
         row.Add(profile["<Property2_Name>"].Value.ToString());
         row.Add(profile["<Property3_Name>"].Value.ToString());
         writer.WriteRow(row);
    }

}

Happy Coding ppl ...

Accessing SharePoint User Profiles using PowerShell commands


This post will help you access the user profiles stored within your User Profile Service Application. It is applicable to both SharePoint 2010 as well SharePoint 2013.

Load the SharePoint snap-in into your management shell -

$snapinName = "Microsoft.SharePoint.PowerShell"
if ((Get-PSSnapin | Where-Object {$_.Name -eq $snapinName }) -eq $NULL)
{
  write-host "SharePoint SnapIn not loaded. Loading..."
  Add-PSSnapin $snapinName -ErrorAction SilentlyContinue
}

Create the SPService Context used to initialize the Profile Manager instance -

$proxyGroup = Get-SPServiceApplicationProxyGroup -default
$subId = [Microsoft.SharePoint.SPSiteSubscriptionIdentifier]::Default
$context = [Microsoft.SharePoint.SPServiceContext]::GetContext($proxyGroup, $subId)

Initialize the ProfileManager object using the created Context object -

$ProfileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

Using this object, create an Enum type object to iterate / enumerate through all the user profiles -

$Profiles = $ProfileManager.GetEnumerator()

Now, there are two ways to loop through these profiles -

1. Using foreach loop

foreach($profile in $Profiles)
{
$property1 = $profile["<Property_Name>"].Value
$property2 = $profile["<Property_Name>"].Value
}

Above, <Property_Name> denotes the name of any user profile property you have created or is available out-of-the-box.

2. Using while loop

while($Profiles.MoveNext())
{
$profile = $Profiles.Current
                $property1 = $profile["<Property_Name>"].Value
$property2 = $profile["<Property_Name>"].Value
}


If you wish to save or export the profile data into a CSV file, you can modify your code above to something like below -

Using foreach loop approach -

Get the location of the file which should save your data -

$propertiesFileName = "\UPA-Profiles.csv"
$outputFile = (Get-Location -PSProvider FileSystem).ProviderPath + $propertiesFileName

Create a Collection which would every single row of your CSV file -

$collection = @()

Then, the loop -

foreach($profile in $Profiles)
{
$profileData = "" | select "Property1","Property2","Property3"
$profileData.Property1= $profile["<Property_Name>"].Value
$profileData.Property2= $profile["<Property_Name>"].Value
$profileData.Property3= $profile["<Property_Name>"].Value
$collection += $profileData
}
$collection | Export-Csv $outputFile -NoTypeInformation


Hope this helps ...