Use PowerShell to Update Item Permssions in SharePoint

What if you want to update the item permissions on every item in a list or library, BUT you don’t want to trigger an associated workflow?

Why?

Request came in to add a new SharePoint group to all the items in a library.  Options were to update EVERY item in the library and let the workflow update the permissions, update the items ONE AT A TIME…

OR

Use PowerShell to update item permissions and not stress the server(s).


# add powershell snapin
$web = Get-SPWeb -Identity "http://sharepointed.com"
$list = $web.Lists.TryGetList("Taco Time")
$group = "Taco Makers"
$PermissionLevel = "Read"

#get site group and setup permission/role
$group = $web.Groups[$group]
$roleAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($group)
$roleDefinition = $web.RoleDefinitions[$PermissionLevel];
$roleAssignment.RoleDefinitionBindings.Add($roleDefinition);

if ($list -ne $null)
{
	foreach ($item in $list.Items)
	{
		if ($item.HasUniqueRoleAssignments -eq $False)
		{
			$item.BreakRoleInheritance($True)
		}
	       
                if ($web.SiteGroups[$group] -ne $null)
		{
			$item.RoleAssignments.Add($roleAssignment)
		}
		else
		{
			Write-Host "Group is not valid."
		}		
	}
}
$web.Dispose()

Update People Picker Using PowerShell

Recently had a new domain added to our forest. After this happened, users would see duplicate values in the SharePoint people picker. The values would both look like John Doe and John Doe, but their underlying domains were different. This caused all sorts of fun when people started emailing “john doe can’t access my site.”

To fix this, the people picker property for each web application in the farm needed to be updated.

There are a lot of properties and options that you can update. I’m only updating my people picker to show one domain.

More on the people picker:
http://msdn.microsoft.com/en-us/subscriptions/cc263012(v=office.12).aspx


#add the powershell snapin

$contentWebAppServices = (Get-SPFarm).services |
 ? {$_.typename -eq "Microsoft SharePoint Foundation Web Application"}

foreach($webApp in $contentWebAppServices.WebApplications)
{
 Set-SPSite $webApp.Url -UserAccountDirectoryPath "DC=YourDomain,DC=Com"
}

What I’m doing is getting all the web applications in the SharePoint farm.  Looping through the applications and updating the people picker.

Use PowerShell to Check SharePoint Library Version History

Randomly ran across a library that a user had jacked versioning up to 99 versions.

So, how do you audit every list and library in a web app / site collection / site.

In the script below, I set the write-host to only be triggered if major or minor versions is greater than 20.

$siteURL = "http://webapp1.sharepointed.com/"
$rootSite = New-Object Microsoft.SharePoint.SPSite($siteUrl)
$spWebApp = $rootSite.WebApplication

foreach($site in $spWebApp.Sites)
{
	foreach($s in $site.AllWebs)
	{
		foreach($l in $s.lists)
		{
			$maj = $l.MajorVersionLimit
			$majMinor = $l.MajorWithMinorVersionsLimit
			
			if(($maj -gt 20) -or ($majMinor -gt 20))
			{
				Write-Host $s.Url
				Write-Host $l.Title
				Write-Host "Major: " $maj
				Write-Host "Minor: " $majMinor
			}
		}
	$s.Dispose()
	}
}

JQuery Total Calculated Column in SharPoint 2010

Working off Paul Grenier’s post JQuery for Everyone: Total Calculated Columns and some hair loss, I got this working in SharePoint 2010.

Need to sum / total a calculated column in SharePoint 2010, here is the answer.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script> 
<script type="text/javascript">
function addCommas(nStr) {//formats number
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}
$(function() {//sums money in specific list column
	var col = 2; //which column to sum
	var m = "$"; //change to "" for non-money format
	var headers = $("table.ms-listviewtable:first> tbody> tr:first th").get();
 	var arrayList = $("table.ms-listviewtable:first> tbody> tr:gt(1)").find(">td:eq("+col+")").get();
	var x = 0;
	var p1 = "";
	var p2 = "";
	$.each(arrayList, function(){
		x += Number($(this).text().replace(/\$|,|\)/g, "").replace(/\(/g,"-"));
	});
	if (x < 0) {//format for negative numbers
		p1 = "(";
		p2 = ")";
		x = Math.abs(x);
	}
	
	$(".ms-listviewtable:first> tbody> tr:eq(1)").find(">td:eq("+col+")")
		.css("text-align","middle")
		.html("<b>Total = "+p1+m+addCommas(x.toFixed(2))+p2+"</b>");
});
</script>

A query to retrieve form data cannot be completed because this action would violate cross-domain restrictions.

Using InfoPath to retrieve data from SQL Server, I received this error:
A query to retrieve form data cannot be completed because this action would violate cross-domain restrictions.

Fix:
Update the InfoPath Form Services settings in Central Admin
Central Admin –> General Application Settings –> Configure InfoPath Form Services
Cross-Domain Access for User Form Templates

http://CA-ADDRESS/_admin/ipfsConfig.aspx

Search Topology Not Responding

If one of the servers in your Search Application Topology is showing a Status of Not Responding, try and restart service app for the server in question.

One of my Crawl Components was not responding, but the server was online and working.  The script below helped to re-sync the server.

-identity “Search Service Application

Replace Search Service Application with the name of your Search App.


$SearchApp = Get-SPEnterpriseSearchServiceApplication -identity "Search Service Application"

$SearchApp | Get-SPEnterpriseSearchQueryTopology | Get-SPEnterpriseSearchQueryComponent | Where-Object {$_.ServerName -eq 'Server Name That is Stuck'}  | Restart-SPEnterpriseSearchQueryComponent

Use PowerShell to Compare Two SharePoint Lists

What if, for some random reason you wanted to compare two SharePoint Lists or Libraries and find the differences.

For the setup, I created two Lists (A and B).  I then added a few items to the Lists. Notice, that List A has two extra items, 6 and 7.

     

 


$mSite = Get-SPweb "http://sharepointed.com/site/taco"
$aList = $mSite.lists["A"]
$bList = $mSite.lists["B"]

$arrA = @()
$arrB = @()

foreach($iA in $aList.Items)
{
 $arrA += $iA["Title"]
}

foreach($iB in $bList.Items)
{
 $arrB += $iB["Title"]
}

$c = Compare-Object -ReferenceObject $arrA -DifferenceObject $arrB -PassThru
Write-Host $c

Output of the above script is: 6 7

More about the Compare-Object cmdlet:

http://technet.microsoft.com/en-us/library/ee156812.aspx

 

STSADM Access Denied Server 2003

Recently was tasked with updating passwords on an older SharePoint 2007 farm.  The fun part, Windows Server 2003 was the host OS.   I hit a wall right out of the gate when I tried to run my STSADM command.

STSADM.EXE -o updatefarmcredentials -identitytype configurableid -userlogin “domain\SP_Admin” -password Cool@Password

Error: Access Denied

What the $#%##, I know I have full access to the farm and databases.

In Windows Server 2003, to launch the command prompt, right-click and select Run As.  THEN, un-check Run this program with restricted access.  Now run the STSADM command again.

 

create a list of groups and the users in each group

As we all know, digging through SharePoint groups looking to see what users are in each, is no fun.

To solve this, I created a new List, and added the groups I wanted to monitor.  Then, added a little PowerShell to update a column in the List with the members in each group.

Setup:

Create a new List.

New Columns:

SPgroup 

Type: Person or Group

Allow selection of: People or Group

Users

Type: Multiple lines of text

Specify the type of text to allow: 

Update Column:

Title

Require that this column contains information: No

The PowerShell script below does the following:

Get the SharePoint Site and List.

Loop through each item in the List.

Retrieve the value of the SPgroup field.

Truncate the Users field.

Loop through the users in the SPgroup.

Update the Users field with the values from SPgroup.


if(-not(Get-PSSnapin | where { $_.Name -eq "Microsoft.SharePoint.PowerShell"}))
{
      Add-PSSnapin Microsoft.SharePoint.PowerShell;
}

$sSite = Get-SPweb "http://reinmoto.com/sites/taco"
$sList=$sSite.Lists["SP Group Permissions"]
$i = 0

foreach($item in $sList.Items)
{
	$sFieldValue = $item["SPgroup"].ToString().Split('#')[1]
	$sGroup = $sSite.SiteGroups[$sFieldValue]

	If($sGroup.Users.Count -ge 0)
	{
		$item["Users"] = ""
		$item.Update()

		foreach($usr in $sGroup.Users)
			{
				if($i -eq 0)
				{
					$item["Users"] = $usr.DisplayName
				}
				else
				{
					$item["Users"] = $item["Users"] + ", " + $usr.DisplayName
				}
				$item.Update()
				$i=$i+1
			}
		$i=0
	}
}
$sSite.dispose()

Save the PowerShell script to your server.

Create a scheduled task to run the script hourly, daily, weekly, monthly…

Export a list of all sites in a Site Collection

How do you use PowerShell to export a list of all the sites in a Site Collection?


if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
 Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}

$site = Get-SPSite "http://reinmoto.com/customers"

foreach($s in $site.AllWebs)
 {
 Write-Host $s.title
 Add-Content -Path "C:\file.txt" -Value $s.URL
 $s.Dispose()
 }