Extract domain users from AD group of SharePoint site using PowerShell

In one my project, there was a requirement to extract domain users from the AD group which was added to the site permission in SharePoint 2010. So to do that I found below PowerShell script to extract domain users from the Group:

$site = Get-SPSite "http://mysharepoint"
$web = $site.RootWeb
$foreach($permission in $web.permissions) {
    if ($permission.Member.IsDomainGroup) {
        $reachedMax = $false
        $login = $permission.Member.LoginName
        $ADGroup = $web.EnsureUser($login)
        $users = [Microsoft.SharePoint.Utilities.SPUtility]::GetPrincipalsInGroup($web, $ADGroup, 10, [ref]$reachedMax)
        $foreach($user in $users){
            #User object found here
        }
    }
}

GetPrincipalsInGroup is the main code to get the user extracted from the domain group.

Advertisements

How to create log file in PowerShell

As a developer, we rely on logs/log files while executing any operations with the PowerShell scripts. So here is the code snippet for how we can create the log file with the PowerShell.

Below is the one of the simple method LogWrite that we can use:

$LogTime = Get-Date -Format yyyy-MM-dd_hh-mm
$Logfile = "E:\Powershell\$(gc env:computername)$LogTime.log" #Specify the log file name along with the path.
#Get TimeStamp
Function Get-TimeStamp {
    return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date)
}
#Log File Write Method
Function LogWrite {
    Param ([string]$logstring)
    $logWithTime = $(Get-TimeStamp) + " " + $logstring
    Add-content $Logfile -value $logWithTime
}

Example to use this function is as below:

LogWrite "Log starts here.."

Above snippet will create log file at the location specified in the $LogTime variable which is E:\PowerShell, where $(gc env:computername) is just current computer name and the timestamp $LogTime. .log will be the file’s extension.
Also All the message will be prefixed with the time when started its execution.

Happy Scripting!

Download WSP from SharePoint Farm

Many times we come across a situation where we have the latest WSP with us in the Solution form (Visual Studio Solution), but we don’t have the installed version of WSP from the SharePoint farm (Central Administrations > System Settings > Manage farm Solutions).

So to get a copy of Installed version of WSP file from the SharePoint farm, following is the PowerShell snippet, which will download the WSP file to the location specified in the cmdlet:

$farm = Get-SpFarm
$file = $farm.Solutions.Item("MyWSPName.wsp").SolutionFile
$file.SaveAs("C:\Backup\MyWSPName.wsp")

Above snippet will save WSP file to the path C:\Backup. Make sure WSP file name MyWSPName.wsp specified does exist on the farm.

Note that in order to run this command, you need to be a member of the Farm Administrators group and have permission to the configuration database.

Add user to SP Shell Admin group of SharePoint

Pre-requisites

  • You must have membership in the securityadmin fixed server role on the SQL Server instance.
  • You must have membership in the db_owner fixed database role on all databases that are to be updated.
  • You must be a member of the Administrators group on the server on which you are running the Windows PowerShell cmdlet.

If these permissions are not satisfied, contact your Setup administrator or SQL Server administrator to request these permissions.

Add-SPShellAdmin

  • Adds a user to the SharePoint_Shell_Access role for the specified database.
  • If you specify only the user, the user is added to the role for the farm configuration database.
C:\PS>Add-SPShellAdmin -UserName CONTOSO\User1

This example adds a new user named User1 to the SharePoint_Shell_Access role in the farm configuration database only, and also ensures the user is added to the WSS_Admin_WPG local group on each server in the farm.

  • If you use the database parameter, the user is added to the role on the farm configuration database, the Central Administration content database, and the specified database.
C:\PS>Add-SPShellAdmin -UserName CONTOSO\User1 -database 4251d855-3c15-4501-8dd1-98f960359fa6

This example adds a new user named User1 to the SharePoint_Shell_Access role in both the specified content database and the configuration database by passing a database GUID to the cmdlet.

    • Using the database parameter is the preferred method because most of the administrative operations require access to the Central Administration content database
  • Use the Add-SPShellAdmin cmdlet to add a user to the SharePoint_Shell_Access role as follows:
    1. Start the SharePoint Management Shell. On the Start screen, click SharePoint Management Shell.

      If SharePoint Management Shell is not on the Start screen: Search in Start, with the keyword SharePoint Management Shell and then click SharePoint Management Shell.

This cmdlet is intended only to be used with a database that uses Windows authentication. There is no need to use this cmdlet for databases that use SQL authentication; in fact, doing so may result in an error message.

    1. To add User1 to the WSS_Content database, run the following snippet:
C:\PS>Get-SPDatabase | ?{$_.Name -eq "WSS_Content"} | Add-SPShellAdmin -Username CONTOSO\User1

This example adds a new user named User1 to the SharePoint_Shell_Access role of both the specified content database and the configuration database by passing the name of the database to the cmdlet. In addition to Add-SPShellAdmin you can also call Get-SPShellAdmin and Remove-SPShellAdmin to administer account rights.

Sync TaxonomyHiddenList after updating Term value programmatically for SharePoint 2013/2016

In one of my project, there was a requirement to manually update term set title and see the updated version in library view. When I did that it didn’t reflect the change on demand. So let me share my experience with the below scenario:

I have one library where I have added a custom field of type managed metadata type.

Columns

These fields (Regions, Survey Title) are targeting to its related TermSet from the Term Store and showing it on the library view.

When I added a new item to the library, I selected it’s metadata and saved the document.

Now I had change request to update metadata term’s title. Let’s consider Region has one value “Colorado” and change request was to change it to “CO”.

To achieve this, I first updated the term title in the term store manager but change wasn’t reflected immediately.

Below are the different ways to achieve the changes immediately:

Out of the Box way:

There is a Timer job for this, it actually sync the term store data to the hidden taxonomy list for that site collection and update wherever term fields are used.

Though to run this job manually, below are steps I followed:

  • Go to the Central Administration > Monitoring > Job DefinitionsTaxonomy Update Scheduler (for your web application). Open it.
  • By default that Job will run hourly, so to run it manually you have to click on Run Now.
  • Once Job is successful, Data from term store will be synced to the TaxonomyHiddenList for that site collection and I was able to see the updated metadata field title for the CO in place of Colorado.

Programmatically with PowerShell:

This could also be done by PowerShell, Below is the snippet I used:

$siteUrl = "http://mysharepoint:1327/"
$site = Get-SPSite $siteUrl
[Microsoft.SharePoint.Taxonomy.TaxonomySession]::SyncHiddenList($site)
$site.dispose()

Programatically with C# SharePoint Console Application:

Similar way you can achieve the same with Server side object model. Following code snippet by creating simple console application and run where SharePoint is installed. Below was the snippet I used:

using Microsoft.SharePoint;
using Microsoft.SharePoint.Taxonomy;
using System;

namespace TaxonomyUpdater
{
    public static class TaxonomyHiddenList
    {
        public static void Update(string SiteUrl)
        {
            SPSite Site2Update = new SPSite(SiteUrl);
            TaxonomySession.SyncHiddenList(Site2Update);
            Site2Update.Dispose();
        }
    }
}

Additional Problem:

There was a situation where I wasn’t able to update the termset data by any of the above solution, from this blog post: Taxonomy Update Scheduler not working? I was able to figure out there was a table in the MMS database called ECMUsedTerm. This table wasn’t updated with all the terms data in it. This could be caused by two different scenarios:

  1. If we recreated the Managed Metadata Service with a clean database, importing the terms with the same id’s then of course the ECMUsedTerm table is empty / information is lost.
  2. If we moved the content database from one farm to another (maybe from staging to prod) which of course has a new Managed Metadata Service, then the ECMUsedTerm table is of course not in sync.

Solution:

To solve this issue, from the article referred I found the below PowerShell code, which will sync the ECMUsedTerm data.

$url = "https://yoursite"
$site = Get-SPSite $url
$tax = Get-SPTaxonomySession -Site $url
$ts = $tax.TermStores[0]
$ts.UpdateUsedTermsOnSite($site)
$site.dispose()

By using this snippet, I was able to update the records in the ECMUsedTerm table of MMS database and now my term set was reflecting once any of the above solution or timer job is ran successfully.

Happy SharePointing!!

Add External DLL with SharePoint WSP to GAC

In this blog, I will explain how you can refer external dll in your SharePoint solution to make it work wherever this dll is not there in the Global Assembly Cache. So the solution itself must contain the dll. To add dll into your SharePoint solution below are the steps:

  1. Reference the dll in the Solution references first.
    1
  1. Now add the dll into your solution by selecting the dll. Once you add it, it will appear in the References list. But it will not be added to the package of Solution, which we have to manually do that.
  1. Open package file
    2
  1. Open Advanced Click Add > Add Existing Assembly
    3
  1. Select dll source path. Now click OK. Make sure Deployment Target is
    4

Once you are done with above steps. Now verify that WSP is containing that dll.

In my case I have renamed it from EmbedExternalDLLs.wsp file  to EmbedExternalDLLs.cab and extract it to the folder. In that folder you will find that added dll.

Restore Site Collection with new Content database to existing web application.

In one of my project, I had requirement to migrate record center site collection to the new server but in that requirement I had to create only new site collection with existing web application and different database.

So to achieve this, below is the detailed snippet of PowerShell script.

First of all I took backup of the source site collection:

Backup-SPSite –Identity http://sharepointolddev –LiteralPath "C:\Backup\olddev.bak"

Now to restore above backup into new site collection I needed to create separate content database. Below is the script to create new content database under a web application.

New-SPContentDatabase -Name "WSS_Content_DBNew" -DatabaseServer "MYDBNAME"  -WebApplication http://sharepointdev/

Once that Database is created I created empty site collection with record center site template. Below is the snippet to create new site collection with created content database.

$site = "http://sharepointdev/sites/newdev"
$dbname = Get-SPContentDatabase "WSS_Content_DBNew"
$ownerAlias = "sp\prathod";
New-SPSite -URL $site -OwnerAlias $ownerAlias -SecondaryOwnerAlias $ownerAlias -ContentDatabase $dbname -Template "OFFILE#1"

Once site collection is created I simply restored existing site collection backup with below snippet:

Restore-SPSite –Force –Identity http://sharepointdev –LiteralPath "C:\Backup\olddev.bak"

That’s it, site collection is restored with new content database in existing web application.