Showing posts with label SharePoint Online. Show all posts
Showing posts with label SharePoint Online. Show all posts

Sunday, June 5, 2016

Getting the files modified by a specified user

If you have any requirement to find out the files which has been modified by a specific user in sharepoint online.

Then here is the powershell script which will serve the purpose.

param
(
    [Parameter(Mandatory=$true)]
    [string]$SPSite,

    [Parameter(Mandatory=$true)]
    [string]$LoginName
)

function GetWebFiles($ctx, $web, $userId)

    Write-Host
    write-host "SITE: $($web.Url)"

    # Create a new custom object to hold our result.
    $siteObject = new-object PSObject

    # Add our data to $contactObject as attributes using the add-member commandlet
    $siteObject | add-member -membertype NoteProperty -name "Site URL" -Value $($web.Url)

    # Save the current $contactObject by appending it to $resultsArray ( += means append a new element to ‘me’)
    $resultsarray += $siteObject
    
    $strQuery = "<View Scope='RecursiveAll'><Query><Where><And>
                <Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>0</Value></Eq>
                <Or><Eq><FieldRef ID='Author' LookupId='True' /><Value Type='Lookup'>$($user.Id)</Value></Eq>
                <Eq><FieldRef ID='Editor' LookupId='True' /><Value Type='Lookup'>$($user.Id)</Value></Eq></Or>
                </And></Where></Query></View>"                  
     
    $lists = $web.Lists
        
    $ctx.Load($lists)
    $ctx.ExecuteQuery()

    foreach ($l in $lists)
    {       
        if ($l.BaseType.ToString() -eq "DocumentLibrary")
        {
            $camlQuery = new-object Microsoft.SharePoint.Client.CamlQuery
            $camlQuery.ViewXml = $strQuery

            $items = $l.GetItems($camlQuery)

            $ctx.Load($items)
            $ctx.ExecuteQuery()
       
            if ($items.Count -gt 0)
            {
                foreach ($item in $items)
                {
                    Write-Host "$($SPSite)$($item["FileRef"])" #"$($web.Url)$($item["FileRef"])"

                    # Create a new custom object to hold our result.
                    $siteObject = new-object PSObject

                    # Add our data to $contactObject as attributes using the add-member commandlet
                    $siteObject | add-member -membertype NoteProperty -name "Site URL" -Value "$($web.Url)$($item["FileRef"])"

                    # Save the current $contactObject by appending it to $resultsArray ( += means append a new element to ‘me’)
                    $resultsarray += $siteObject
                }
            }
        }       
    }
   
    $subWebs = $web.Webs

    $ctx.Load($subWebs)
    $ctx.ExecuteQuery()

    foreach ($subWeb in $subWebs)
    {
        GetWebFiles $ctx $subWeb $userId
    }
}

$username = Read-Host -Prompt "Enter Username"
$password = Read-Host -Prompt "Enter Password" -AsSecureString

$scriptPath = Split-Path $MyInvocation.MyCommand.Path

Add-Type -Path "$($scriptPath)\Microsoft.SharePoint.Client.dll"
Add-Type -Path "$($scriptPath)\Microsoft.SharePoint.Client.Runtime.dll"

# Declare an array to collect our result objects
$resultsarray =@()

try
{
    $teamSites = import-csv “$($scriptPath)\O365DTeamSites.csv”

    ForEach ($item in $teamSites)
    {
        $siteUrl = $item.(“Site URL”)

        #Write-Output “Site URL: $siteUrl”

        try
        {
            $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)
   
            $creds = New-Object System.Net.NetworkCredential($username, $password)
            $ctx.Credentials = $creds;
                      
            $user = $ctx.Web.SiteUsers.GetByLoginName($LoginName)
                            
            $rootWeb = $ctx.Site.RootWeb  

            $ctx.Load($rootWeb)
            $ctx.Load($user)
            $ctx.ExecuteQuery()

            GetWebFiles $ctx $rootWeb $user.Id       
        }
        catch [Exception]
        {
            if($($_.Exception.Message) -ne "User cannot be found.")
            {
                write-host "Error checking site: $($siteUrl) -> $($_.Exception.Message)"
            }
            continue;
        }
    }

    $resultsarray| Export-csv $($scriptPath)\UserSites.csv -notypeinformation
}
catch [Exception]
{
    write-host "Error -> $($_.Exception.Message)"
    continue;
}


Happy Coding!!!

Retrieve My sites list in SharePoint online

When i was working on branidng for my sites, then i should get the list of my sites so that i can apply the custom branding to all the my sites.
So, in order to get the list of my sites, i have written the below code.

private static void GetMySites()
        {
            string siteUrl = "<root my site url>";
            string userName = "<Enter tenant admin user name>";
            string password = "<Enter tenant admin password>";

            SecureString securePassword = new SecureString();
            foreach (char c in password)
            {
                securePassword.AppendChar(c);
            }

            using (ClientContext clientContext = new ClientContext(siteUrl))
            {
                clientContext.Credentials = new SharePointOnlineCredentials(userName, securePassword);

                Web web = clientContext.Web;
                clientContext.Load(web);
                clientContext.ExecuteQuery();

                List<SiteEntity> mysites = web.MySiteSearch();

                Console.WriteLine("My sites count: " + mysites.Count);

                string filePath = "D:\\GetMySites\MySites.txt";
                if (!System.IO.File.Exists(filePath))
                {
                    System.IO.File.Create(filePath).Close();
                }

                StringBuilder sbSites = new StringBuilder();
                using (System.IO.TextWriter writer = System.IO.File.CreateText(filePath))
                {
                    foreach (SiteEntity site in mysites)
                    {
                        sbSites = sbSites.Append(site.Url + ";");
                    }
                    writer.WriteLine(sbSites);
                }
            }
        }


Hope this code helps you to get the list of my sites in a text file.

Happy coding :)

Update User Profile properties in SharePoint online

I had a requirement from our client that we need to update some of the user AD properties with the SharePoint user profile properties regularly.

So, for that i have build a console application to update the properties and i have scheduled it as a Windows scheduler.

I have kept all the settings (LDAP connection string, AD admin username, password etc.. ) in the app.config file so that i don't have to specify them in the code.

Below is the App.Config file code.

<appSettings>
    <add key="tenantAdministrationUrl" value=""/>
    <add key="tenantAdminLoginName" value=""/>
    <add key="tenantAdminPassword" value=""/>
    <add key="UserProfileProperties" value="WorkPhone|CellPhone"/>   
    <add key="UserProfilePrimeProperty" value="WorkEmail"/>
    <add key="LDAP" value="LDAP://OU="/>
    <add key="ADAdminUserName" value="" />
    <add key="ADAdminPassword" value="" />
    <add key="Properties" value="telephoneNumber|mobile"/>
    <add key="PrimeProperty" value="mail"/>
  </appSettings>
 


Below is the code to retrieve the settings from the app.config file.
Consts._UserProfilePrimeProperty = ConfigurationManager.AppSettings["UserProfilePrimeProperty"];
Consts.ADAdminUserName = ConfigurationManager.AppSettings["ADAdminUserName"];
Consts.ADAdminPassWord = ConfigurationManager.AppSettings["ADAdminPassWord"];
Consts._ProfileProperties = ConfigurationManager.AppSettings["Properties"];
Consts._PrimeProperty = ConfigurationManager.AppSettings["PrimeProperty"];
Consts._tenantAdministrationUrl = ConfigurationManager.AppSettings["tenantAdministrationUrl"];
Consts._tenantAdminLoginName = ConfigurationManager.AppSettings["tenantAdminLoginName"];
Consts._tenantAdminPassword = ConfigurationManager.AppSettings["tenantAdminPassword"];
Consts._UserProfileProfileProperties = ConfigurationManager.AppSettings["UserProfileProperties"];

Below method will retrieve the AD information.

 
public static void getADInformation()
        {
            string ldap = ConfigurationManager.AppSettings["LDAP"];
            Console.WriteLine(ldap);
            if (!string.IsNullOrEmpty(ldap))
            {
                try
                {
                    using (DirectoryEntry ou = new DirectoryEntry(ldap))
                    {
                        DirectorySearcher searcher = new DirectorySearcher(ou);
                        searcher.Filter = "(&(objectClass=user)(objectCategory=person))";
                        searcher.SearchScope = SearchScope.Subtree;
                        searcher.PageSize = 1000;//This has to be set to return all the results from AD, if not set then it will limit the results to 1000 only

                        string[] tempProp = Consts._ProfileProperties.Split('|');
                        string[] properties = new string[tempProp.Count() + 1];
                        properties[0] = Consts._PrimeProperty;
                        for (int i = 1; i <= tempProp.Count(); i++)
                        {
                            properties[i] = tempProp[i - 1];
                        }

                        foreach (var property in properties)
                        {
                            searcher.PropertiesToLoad.Add(property);
                        }

                        SearchResult result;
                        List<string[]> columnValues = new List<string[]>();

                        searcher.PropertiesToLoad.Add("userPrincipalName");
                        searcher.PropertiesToLoad.Add("samAccountName");

                        SearchResultCollection resultCol = searcher.FindAll();
                        Console.WriteLine("Find all");
                        if (resultCol != null)
                        {
                            Console.WriteLine(resultCol.Count + " Results found in AD");
                            for (int i = 0; i < resultCol.Count; i++)
                            {
                                result = resultCol[i];
                                Console.WriteLine(result.Properties["samAccountName"][0] + "-" + result.Properties["userPrincipalName"][0]);

                                string[] tempPropVal = new string[properties.Count()];
                                int propCnt = 0;
                                //get each property value to array
                                foreach (var property in properties)
                                {
                                    if (result.Properties.Contains(property))
                                    {
                                        tempPropVal[propCnt] = Convert.ToString(result.Properties[property][0]);
                                    }
                                    else
                                    {
                                        tempPropVal[propCnt] = "";
                                    }
                                    propCnt++;
                                }
                                columnValues.Add(tempPropVal);
                            }
                        }

                        string[] tempUserProfileProp = Consts._UserProfileProfileProperties.Split('|');
                        string[] userProfileProperties = new string[tempUserProfileProp.Count() + 1];
                        userProfileProperties[0] = Consts._UserProfilePrimeProperty;
                        for (int i = 1; i <= tempUserProfileProp.Count(); i++)
                        {
                            userProfileProperties[i] = tempUserProfileProp[i - 1];
                        }

                        Consts.UserProdDataCol = new List<Dictionary<string, ExpandoObject>>();

                        foreach (string[] columnValue in columnValues)
                        {
                            dynamic data = new ExpandoObject();
                            //get the first object which is the account
                            string account = columnValue[0];
                            Dictionary<string, ExpandoObject> userProfData = new Dictionary<string, ExpandoObject>();
                            if (!string.IsNullOrEmpty(account))
                            {
                                for (int j = 1; j < userProfileProperties.Count(); j++)
                                {
                                    ((IDictionary<String, Object>)data).Add(userProfileProperties[j], columnValue[j]);
                                }
                                userProfData.Add(account, data);
                                Consts.UserProdDataCol.Add(userProfData);
                            }
                            else
                            {
                                Console.WriteLine(account + " is empty");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.StackTrace);
                }
            }
        }

Below is the method which will import AD data to user profile.

public static void ImportDatatoCloud(TextWriter writer)
        {
            List<Dictionary<string, ExpandoObject>> dataCollection = Consts.UserProdDataCol;
            int count = 1;
            int totalUsers = dataCollection.Count;
            foreach (var dataCol in dataCollection)
            {
                Generic.LogMessage(string.Format("processing user '{0}' of {1}...", count, totalUsers), Consts.LogLevel.Information);
                var userName = dataCol.Keys.FirstOrDefault();
                dynamic propertySet = dataCol.Values.FirstOrDefault();

                string UserAccountName = Consts._sPOProfilePrefix + userName;

                try
                {
                    using (ClientContext clientContext = new ClientContext(Consts._tenantAdministrationUrl))
                    {
                        SecureString passWord = new SecureString();

                        foreach (char c in Consts._tenantAdminPassword.ToCharArray()) passWord.AppendChar(c);

                        clientContext.Credentials = new SharePointOnlineCredentials(Consts._tenantAdminLoginName, passWord);

                        // Get the people manager instance for tenant context
                        PeopleManager peopleManager = new PeopleManager(clientContext);

                        foreach (var property in propertySet)
                        {
                            string propName = property.Key;
                            string propVal = property.Value;
                            Console.WriteLine(userName + " - " + propName + "->" + propVal);

                            if (propVal.Contains('|'))
                            {
                                // List Multiple values
                                List<string> propValues = propVal.Split('|').ToList<string>();

                                // Update the SPS-Skills property for the user using account name from profile.
                                peopleManager.SetMultiValuedProfileProperty(UserAccountName, propName, propValues);
                            }
                            else
                            {
                                // Update the AboutMe property for the user using account name.
                                peopleManager.SetSingleValueProfileProperty(UserAccountName, propName, propVal);
                            }
                        }

                        clientContext.ExecuteQueryRetry();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Issue in updating the profile properties for :" + UserAccountName);
                    writer.WriteLine("Issue in updating the profile properties for :" + UserAccountName);
                    writer.WriteLine(ex.ToString());
                }

                count++;
            }
            Generic.LogMessage("Processing finished for " + totalUsers + " user profiles. Import Complete!", Consts.LogLevel.Warning);
        }

Points to remember: 
Remember to add the sharepoint online client dll's - Microsoft.SharePoint.Client.dll, Microsoft.SharePoint.Client.Runtime.dll, Microsoft.SharePoint.Client.UserProfiles.dll

Hope this code helps you.

Happy Coding :)