Wednesday 14 October 2015

SharePoint Permission Matrix generated by PowerShell

I found the most awesome PowerShell script which generates a csv of all the permission access within a SharePoint site. It works so well.

One of the biggest issues in SharePoint, is access. Making sure the right people have the right access to the right things, and more importantly the wrong people don't have access. But SharePoint doesn't give you a good overview of this information. This is why this script is so nice. Its shows, who has access, and where, and with what level.

Original Article from Microsoft SharePoint TechNet:
http://social.technet.microsoft.com/wiki/contents/articles/14242.sharepoint-2010-export-all-unique-permissions-from-site-collection-using-powershell.aspx

How to get it to work:

  1. Save the script as a PowerShell script, example: CreatePermissionMatrix.ps1
  2. Goto the SharePoint Server.
  3. Create a folder, example: C:\PermissionLog
  4. Copy the script in here.
  5. Open "SharePoint Management Shell", as Administrator.
  6. Run the PowerShell script, example: . C:\PermissionLog\CreatePermissionMatrix.ps1
  7. The script will then ask for the SharePoint site URL, you want to report on.
  8. The script will then ask for the location, where the csv file will be generated, example: C:\PermissionLog
  9. Script Done :)
  10. Then you can go a retrieve the csv file.
  11. It will show: Who has access, and where, and with what level

PowerShell Script:

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


$properties=@{SiteUrl='';SiteTitle='';ListTitle='';ObjectType='';ObjectUrl='';ParentGroup='';GroupOwner='';MemberType='';MemberName='';MemberLoginName='';JobTitle='';Department='';RoleDefinitionBindings='';};
$Permissions=@(); 

$UserInfoList=""; 

$RootWeb=""; 

$SiteCollectionUrl = Read-Host "Enter a Site Collection Url"; 

$ExportFileDirectory = Read-Host "Enter the Directory Path to create permissions export file";
if(Test-Path $ExportFileDirectory){
$spAssgn = Start-SPAssignment;
Get-SPSite $SiteCollectionUrl -AssignmentCollection $spAssgn|Get-SPWeb -limit ALL -AssignmentCollection $spAssgn|%{
$web = $_; 



#Root Web of the Site Collection 

if($web.IsRootWeb -eq $True){ 

$RootSiteTitle = $web.Title; 

$RootWeb = $web; 

$UserInfoList = $RootWeb.GetList([string]::concat($web.Url,"/_catalogs/users"));

$siteUrl = $web.Url; 

$siteRelativeUrl = $web.ServerRelativeUrl; 

Write-Host $siteUrl -Foregroundcolor "Red"; 

$siteTitle = $web.Title; 



#Get Site Level Permissions if it's unique 

if($web.HasUniqueRoleAssignments -eq $True){ 



$web.RoleAssignments|%{ 

$RoleDefinitionBindings=@(); 



$_.RoleDefinitionBindings|%{ 

$RoleDefinitionBindings += $_.Name; 






$MemberName = $_.Member.Name; 

$MemberLoginName = $_.Member.LoginName; 

$MemberType = $_.Member.GetType().Name; 

$GroupOwner = $_.Member.Owner.Name; 



if($MemberType -eq "SPGroup"){ 



$JobTitle="NA"; 

$Department="NA"; 



$permission = New-Object -TypeName PSObject -Property $properties; 

$permission.SiteUrl =$siteUrl; 

$permission.SiteTitle = $siteTitle; 

$permission.ListTitle = "NA"; 

$permission.ObjectType = "Site"; 

$permission.ObjectUrl = $siteRelativeUrl; 

$permission.MemberType = $MemberType; 

$permission.ParentGroup = $MemberName; 

$permission.GroupOwner = $GroupOwner; 

$permission.MemberName = $MemberName; 

$permission.MemberLoginName = $MemberLoginName; 

$permission.JobTitle = $JobTitle; 

$permission.Department = $Department; 

$permission.RoleDefinitionBindings = $RoleDefinitionBindings -join ","; 





$Permissions +=$permission; 



#Expand Groups 

$web.Groups[$MemberName].Users|%{ 



$JobTitle="NA"; 

$Department="NA"; 



try{ 

$userinfo = $UserInfoList.GetItemById($_.ID); 

$JobTitle=$userinfo["JobTitle"]; 

$Department=$userinfo["Department"]; 


catch{ 




$permission = New-Object -TypeName PSObject -Property $properties; 

$permission.SiteUrl =$siteUrl; 

$permission.SiteTitle = $siteTitle; 

$permission.ListTitle = "NA"; 

$permission.ObjectType = "Site"; 

$permission.ObjectUrl = $siteRelativeUrl; 

$permission.MemberType = "SPGroupMember"; 

$permission.ParentGroup = $MemberName; 

$permission.GroupOwner = $GroupOwner; 

$permission.MemberName = $_.DisplayName; 

$permission.MemberLoginName = $_.UserLogin; 

$permission.JobTitle = $JobTitle; 

$permission.Department = $Department; 

$permission.RoleDefinitionBindings = $RoleDefinitionBindings -join ","; 



$Permissions +=$permission; 





elseif($MemberType -eq "SPUser"){ 



$JobTitle="NA"; 

$Department="NA"; 



try{ 

$userinfo = $UserInfoList.GetItemById($_.ID); 

$JobTitle=$userinfo["JobTitle"]; 

$Department=$userinfo["Department"]; 


catch{ 




$permission = New-Object -TypeName PSObject -Property $properties; 

$permission.SiteUrl =$siteUrl; 

$permission.SiteTitle = $siteTitle; 

$permission.ListTitle = "NA"; 

$permission.ObjectType = "Site"; 

$permission.MemberType = $MemberType; 

$permission.ObjectUrl = $siteRelativeUrl; 

$permission.ParentGroup = "NA"; 

$permission.GroupOwner = "NA"; 

$permission.MemberName = $MemberName; 

$permission.MemberLoginName = $MemberLoginName; 

$permission.JobTitle = $JobTitle; 

$permission.Department = $Department; 

$permission.RoleDefinitionBindings = $RoleDefinitionBindings -join ","; 



$Permissions +=$permission; 








#Get all Uniquely secured objects 

$uniqueObjects = $web.GetWebsAndListsWithUniquePermissions(); 



#Get uniquely secured Lists pertaining to the current site 

$uniqueObjects|?{$_.WebId -eq $web.Id -and $_.Type -eq "List"}|%{ 



$listUrl = ($_.Url); 

$list = $web.GetList($listUrl); 



#Exclude internal system lists and check if it has unique permissions 

if($list.Hidden -ne $True){ 



Write-Host $list.Title -Foregroundcolor "Yellow"; 

$listTitle = $list.Title; 

#Check List Permissions 



if($list.HasUniqueRoleAssignments -eq $True){ 



$list.RoleAssignments|%{ 



$RoleDefinitionBindings=""; 

$_.RoleDefinitionBindings|%{ 

$RoleDefinitionBindings += $_.Name; 




$MemberName = $_.Member.Name; 

$MemberLoginName = $_.Member.LoginName; 

$MemberType = $_.Member.GetType().Name; 

$JobTitle="NA"; 

$Department="NA"; 



if($MemberType -eq "SPUser"){ 

try{ 

$userinfo = $UserInfoList.GetItemById($_.ID); 

$JobTitle=$userinfo["JobTitle"]; 

$Department=$userinfo["Department"]; 


catch{ 





$permission = New-Object -TypeName PSObject -Property $properties; 

$permission.SiteUrl =$siteUrl; 

$permission.SiteTitle = $siteTitle; 

$permission.ListTitle = $listTitle; 

$permission.ObjectType = $list.BaseType.ToString(); 

$permission.ObjectUrl = $listUrl; 

$permission.ParentGroup = "NA"; 

$permission.GroupOwner = "NA"; 

$permission.MemberType=$MemberType; 

$permission.MemberName = $MemberName; 

$permission.MemberLoginName = $MemberLoginName; 

$permission.JobTitle = $JobTitle; 

$permission.Department = $Department; 

$permission.RoleDefinitionBindings = $RoleDefinitionBindings -join ","; 



$Permissions +=$permission; 





if($list.BaseType -eq "DocumentLibrary"){ 



#Check All Folders 

$list.Folders|%{ 

$folderUrl = $_.Url; 



if($_.HasUniqueRoleAssignments -eq $True){ 



$_.RoleAssignments|%{ 

$RoleDefinitionBindings=""; 



#Get Permission Level against the Permission 

$_.RoleDefinitionBindings|%{ 

$RoleDefinitionBindings += $_.Name; 




$MemberName = $_.Member.Name; 

$MemberLoginName = $_.Member.LoginName; 

$MemberType = $_.Member.GetType().Name; 



$JobTitle="NA"; 

$Department="NA"; 



if($MemberType -eq "SPUser"){ 

try{ 

$userinfo = $UserInfoList.GetItemById($_.ID); 

$JobTitle=$userinfo["JobTitle"]; 

$Department=$userinfo["Department"]; 


catch{ 





$permission = New-Object -TypeName PSObject -Property $properties; 

$permission.SiteUrl =$siteUrl; 

$permission.SiteTitle = $siteTitle; 

$permission.ListTitle = $listTitle; 

$permission.ObjectType = $list.BaseType.ToString(); 

$permission.ObjectUrl = $folderUrl; 

$permission.MemberType = $MemberType; 

$permission.ParentGroup = "NA"; 

$permission.GroupOwner = "NA"; 

$permission.MemberName = $MemberName; 

$permission.MemberLoginName = $MemberLoginName; 

$permission.JobTitle = $JobTitle; 

$permission.Department = $Department; 

$permission.RoleDefinitionBindings = $RoleDefinitionBindings -join ","; 



$Permissions +=$permission; 






#Check All Items 

$list.Items|%{ 



$fileUrl = $_.File.Url; 

$file=$_.File; 

if($_.HasUniqueRoleAssignments -eq $True){ 



$_.RoleAssignments|%{ 

$RoleDefinitionBindings=""; 

$_.RoleDefinitionBindings|%{ 

$RoleDefinitionBindings += $_.Name; 




$MemberName = $_.Member.Name; 

$MemberLoginName = $_.Member.LoginName; 

$MemberType = $_.Member.GetType().Name; 

$JobTitle="NA"; 

$Department="NA"; 



if($MemberType -eq "SPUser"){ 

try{ 

$userinfo = $UserInfoList.GetItemById($_.ID); 

$JobTitle=$userinfo["JobTitle"]; 

$Department=$userinfo["Department"]; 


catch{ 





$permission = New-Object -TypeName PSObject -Property $properties; 

$permission.SiteUrl =$siteUrl; 

$permission.SiteTitle = $siteTitle; 

$permission.ListTitle = $listTitle; 

$permission.ObjectType = $file.GetType().Name; 

$permission.ObjectUrl = $fileUrl; 

$permission.MemberType=$MemberType; 

$permission.MemberName = $MemberName; 

$permission.MemberLoginName = $MemberLoginName; 

$permission.JobTitle = $JobTitle; 

$permission.Department = $Department; 

$permission.RoleDefinitionBindings = $RoleDefinitionBindings -join ","; 



$Permissions +=$permission; 









if($_.IsRootWeb -ne $True){ 

$_.Dispose(); 



#Dispose root web 

$RootWeb.Dispose(); 

Stop-SPAssignment $spAssgn;
$exportFilePath = Join-Path -Path $ExportFileDirectory -ChildPath $([string]::Concat($RootSiteTitle,"-Permissions.csv"));
$Permissions|Select SiteUrl,SiteTitle,ObjectType,ObjectUrl,ListTitle,MemberName,MemberLoginName,MemberType,JobTitle,Department,ParentGroup,GroupOwner,RoleDefinitionBindings|Export-CSV -Path $exportFilePath -NoTypeInformation;
}
else{
Write-Host "Invalid directory path:" $ExportFileDirectory -ForegroundColor "Red";
}

Monday 15 June 2015

Content Search Query rules to find all Sub Sites within the Current Site

Query:

contentclass:STS_Web 
Path:{Site.URL} 
Site<>{Site.URL}

How-to:

  1. This rule will only show sites. At this stage it shows all the sites across the whole environment.
  2. This rule will limit the results to sites with the current site. This also include the top level site.
  3. This rule removed the top level site, thus only showing the sub sites. 
  4. This rule removed the top level site, thus only showing the sub sites. 

How to Map the "Expires" date column in the Search Schema for SharePoint Online (Office 365)

With SharePoint Online you can’t create a New mapped search column as simply as SharePoint On-Prem. With SharePoint Online it is best to use one of the pre-created mapped search columns, created for you, by SharePoint to use. I.e. RefinableString, RefinableDate, RefinableInt and RefinableDecimal.

For this example I will be Mapping this column, for my whole SharePoint Online environment, so all my Site Collection can access this Search Mapped Column.

  1. Goto your SharePoint Online Admin Center
  2. Click "search" on the quick links menu (on the left)
  3. Filter by "refinabledate"
  4. Click "RefinableDate00"
  5. You can see that this column is already for searching, and has been configured to be a "Date and Time" column type
  6. Add an Alias to this column. This will inform other and "future you", what this column is for. 
    Alias: AnnouncementExpiryDate
  7. Scroll down to "Mapping to crawl properties", and click "Add a Mapping"
  8. Find "Search for crawled property name": Expires
  9. Select "ows_Expires"
  10. Click "OK"
  11. Click "OK"
  12. To see the column mapped, filter again by "refinabledate"
Now you just have to wait for the SharePoint Online Crawl to run :)

Content Search Query Rule for showing item with a future Expiry Date, or have Blank Dates.

There are so many cool ways you can use the Content Search Query rule, I blog about last (Content Search Query Rule for showing Items Modified Today).

So in this example, I have a list of Announcements. These Announcements have an Expiry Date. This Expiry Date column can be blank or have a date.

The Content Search Rollup must show all item which has a future Expiry Date, or are blank.

Note: The column which is being used to compare the date, must be a mapped in the Search Schema as a DATE (Date and Time) column. 

Note: The default “Expires” column is not automatically mapped, by the Search Schema. There is a mapped column called “ExpiresOWSDATE”, but this column is mapped as text. 

Query Rule:
-RefinableDate00:1900-01-01..{Today}




The reason this is such a cool rule, is because it show items with Blank Dates.

Please see next blog on: How to Map the "Expires" date column in the Search Schema for SharePoint Online (Office 365)

Tuesday 9 June 2015

Content Search Query Rule for showing Items Modified Today

I just learnt a really cool Content Search Query Rule which I just have to share.

So in the Content Search Web Part Query, you add:
-LastModifiedTime:1900-01-01..{Today-1}


The Search result will then only show you item which where modified today. Thus is removing anything from 1900-01-01 to anything created Yesterday (Today-1).