Error: Collection was modified; enumeration operation may not execute

Many times I encountered error while executing PowerShell snippet: “Collection was modified; enumeration operation may not execute” while using ForEach loop of the list object. Here is the code that throws an error:

$web = Get-SPWeb "http://sharepointsiteurl"
ForEach($list in $web.Lists)
{
     if (!$list.Hidden)
     {
         # do something to change the list or add list
         $list.Views.Add(.......)
         # Error: "Collection was modified; enumeration operation may not execute..."
     }
}
$web.Dispose()

To overcome this issue simply need to change ForEach loop to For, see below updated snippet to use:

For($i=0; $i -lt $web.Lists.count; $i++)

And if working for deletion of list in the collection, loop the collection in reverse order, see below code:

For ($i=$web.Lists.count-1; $i –gt 0; $i--)
Advertisements

Get PublicKeyToken of DLL

Many times I wondered how can I get PublicKeyToken of DLL file so for that here is the found trick to get it using PowerShell, below is the statement to be executed:

([system.reflection.assembly]::loadfile("C:\SomeDLL.dll")).FullName

The output will provide the VersionCulture and PublicKeyToken as shown below:

SomeDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a

Check Not Null condition in Keyword Query Language for SharePoint Search

In one of my project, I was using Keyword query language to generate search query string. There was a situation where I spent lot of time to find to see if I can apply not null condition for the specific text field(EnterpriseKeyword).

Unfortunately that’s not possible in direct way where you use just one keyword like NotNull or something else to achieve it.

By default, SharePoint can’t search empty values using Keyword Query Language.

Because empty value is not stored in index, so if you want to filter the manged property which is not empty, so there is different unearthly way to achieve is that you need to identify in the query how to include everything that has any value:

Text values consist of alphabetical characters (a..z) and numerical characters (0..9). SharePoint isn’t case sensitive so you have to do it only once per letter, see below example:

(EnterpriseKeyword:a* OR EnterpriseKeyword:b* OR EnterpriseKeyword:c* OR EnterpriseKeyword:d* OR EnterpriseKeyword:e* OR EnterpriseKeyword:f* OR EnterpriseKeyword:g* OR EnterpriseKeyword:h* OR EnterpriseKeyword:i* OR EnterpriseKeyword:j* OR EnterpriseKeyword:k* OR EnterpriseKeyword:l* OR EnterpriseKeyword:m* OR EnterpriseKeyword:n* OR EnterpriseKeyword:o* OR EnterpriseKeyword:p* OR EnterpriseKeyword:q* OR EnterpriseKeyword:r* OR EnterpriseKeyword:s* OR EnterpriseKeyword:t* OR EnterpriseKeyword:u* OR EnterpriseKeyword:v* OR EnterpriseKeyword:w* OR EnterpriseKeyword:x* OR EnterpriseKeyword:y* OR EnterpriseKeyword:z* OR EnterpriseKeyword:1* OR EnterpriseKeyword:2* OR EnterpriseKeyword:3* OR EnterpriseKeyword:4* OR EnterpriseKeyword:5* OR EnterpriseKeyword:6* OR EnterpriseKeyword:7* OR EnterpriseKeyword:8* OR EnterpriseKeyword:9* OR EnterpriseKeyword:0*)

Above example will help you apply not null condition for any text field in Keyword Query Language.

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.

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.