Reset unique permission for SharePoint document library and files

Sometime we need to reset the unique permission for document library, sub folders and files. If the document library has only 1-2 documents then we can handle it manually, but if you have thousands of files and folder so its quite difficult to reset it for all one by one. Below piece of code can help to reset unique permission for document library and its content. This script will take the top level permission from document library.


function ResetUniquePermission {
Param(
[Parameter(Mandatory = $true, HelpMessage="Enter the site url")][ValidateNotNullorEmpty()][string] $SiteURL ,
[Parameter(Mandatory = $true, HelpMessage="Enter the library name")][ValidateNotNullorEmpty()][string] $LibraryName,
[Parameter(Mandatory = $true, HelpMessage="Total number of files")][ValidateNotNullorEmpty()][int] $TotalFiles

)

$Web = Get-SPWeb $SiteURL 
$List= $Web.Lists[$LibraryName]
$Query = New-Object Microsoft.SharePoint.SPQuery
$Query.ViewXml =  @"
<View Scope="RecursiveAll">
    <Query>
        <OrderBy><FieldRef Name='ID' Ascending='TRUE'/></OrderBy>
    </Query>
    <RowLimit Paged="TRUE">$TotalFiles</RowLimit>
</View>
"@;

$Items = $List.GetItems($Query)
for($j=0;$j -lt $Items.Count ;$j++)
{
    $Items[$j].ResetRoleInheritance()
    Write-Host "Permission reset done for file "$Items[$j]["Title"] -ForegroundColor Green
}
}

SharePoint Installation Error: Windows cannot find e:\prerequisiteinstaller.exe

To install SharePoint we attaching SharePoint setup ISO. It seems due to the same after installation complete, it is looping this error after login to server.

This issue I face in SharePoint 2013 to SharePoint 2019 and the solution will work for all the version mentioned. So just run the below powershell script it will delete the .CMD file from startup and after that command popup won’t appear after login to server.

$path="C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
$file= Get-ChildItem $path -Recurse -Force -Filter SharePointServerPreparationToolStartup* | Where-Object {!$_.PSIsContainer}
if($file -ne $null) 
{
	$file | Remove-Item
	Write-Host "File $($file.Name) removed successfully" -ForegroundColor green
}
else
{
   Write-Host "File not found" -ForegroundColor red
}

Bulk update resource level custom field in Project Server

There are plenty of blogs available about the same, I am writing it again because I found most of the code is not working else throwing the error, here I have tested these code with Project Server online and Project Server on-prem version, and it works like charm.

This is a very common scenario where every project server developer needed once a time in his career.

So this is the solution, just need to replace site URL, username, and password and custom field which you wanted to update.

<# Below is CSV sample which I am using for this code. First Column is headers. #>;
<#
ResourceName,ResourceEmailAddress,EmpRate
Kuldeep, kuldeep.verma@xyz.com, 10000
Rajdeep, rajdeep.sardesai@xyz.com, 20000
Jaydeep, Jaydeep.prajapat@xyz.com, 40000
#>

#Download and install Microsoft Client Component from https://www.microsoft.com/en-in/download/details.aspx?id=42038
#Microsoft SharePoint Client Component is mandatory to move further.
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.ProjectServer.Client.dll"

#replace CSV path
$csvpath="C:\FakePath\FileName.csv"
$siteURL = "{Site URL}"
$loginname = "{UserName}"
$pwd = "{Password}"
$securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force
$creds = New-Object System.Management.Automation.PsCredential $loginname,$securePassword
$projContext = New-Object Microsoft.ProjectServer.Client.ProjectContext($siteURL)
$projContext.Credentials = $creds
$customfields = $projContext.CustomFields
$projContext.Load($customfields)
$projContext.ExecuteQuery()

And if you don’t know the Internal Name of the field then simply use the below script after running the above code.

#get custom field by anem
$customfield = $customfields | select InternalName, Name | WHERE {$_.Name -eq "&lt;Field display name&gt;"}

If you wanted to list down all custom fields then you can simply use the below piece of code.

#get all custom field
$customfields | select InternalName, Name, IsRequired

Below I am comparing the resource email and updating the custom field, you can use the Resource Name also for comparison.

Import-Csv $csvpath | ForEach-Object {
Try {
Write-Host "Updateding Resource $($_.ResourceName)..." -ForegroundColor Green
$resourceEmail = $_.ResourceEmailAddress
$resource = $projContext.EnterpriseResources | select Id, Name, Email, UserPrincipalName | where { $_.Email -eq $resourceEmail }
if ($resource -ne $null) {
$res = $projContext.EnterpriseResources.GetByGuid($resource.Id)
#update $_.Value with your field name of CSV and Change the Internal field name
$res["{Internal Field Name}"] = $_.EmpRate
$projContext.EnterpriseResources.Update()
$projContext.ExecuteQuery()
Write-Host "Updated Resource $($_.ResourceName) successfully!" -ForegroundColor Green
}
else {
Write-Host "Resource $($_.ResourceName) not found!" -ForegroundColor DarkCyan
}
}
catch {
$_ | select -expandproperty invocationinfo
Write-Host "Error occurred while updating $($_.ResourceName)..." -ForegroundColor Red
write-host "$($_.Exception.Message)" -foregroundcolor DarkRed
}
}
Write-Host "Script executed successfully" -ForegroundColor Yellow

Download complete source code from GitHub

Get error line number powershell program

If someone wrote a PowerShell program, with multiple lines and without caring the coding standard and you got stuck to find where the error is, so very simplest way which I am thinking is just use below piece of code which saves your time and let you know about a line which is having an issue.

InvocationInfo can provide information about how and where this command was invoked

So just use simple try-catch like below

try {
    #&lt;replace with your code&gt;
}
catch {
    $_ |select -expandproperty invocationinfo
    write-host "$($_.Exception.Message)" -foregroundcolor red  
    break;
}

Publish multiple pages in SharePoint

As a SharePoint admin most of the time we are getting requirement to publish pages or while working on migration for some cases we would require to publish pages. Here is the small piece of code which can help to publish single page or multiple pages using Powershell.

This piece of code is required for both

$LibraryTitle = "<Replace with Page Library Name>"
$SiteURL = "<Replace with your site URL>"
$oWEb = Get-SPWeb $SiteURL
$PublishingComment ="Published using powershell"

Use below block if you wanted to publish a single page, replace with your page url.

<# Single page publish #>
$pageURL = "https://digiboek.net/sites/demo/SitePages/Sample.aspx"
$file = $oWEb.GetFile($pageURL)
$file.Publish($PublishingComment);

If you wanted to publish multiple pages then use below piece of code

<# Publish all pages from library #>
$oLib = $oWEb.GetFolder($LibraryTitle)
$files = $oLib.Files | select Name, Url
foreach ($file in $files) {
    $ofileURL = $SiteURL + "/" + $file.Url
    $oFile = $oWEb.GetFile($ofileURL)
    if ($oFile.Exists -eq $true) {
        $oFile.Publish($PublishingComment);
        Write-Host $file.Name" Page published successfully..." -foreground Green
    }
}

Happy Coding 😊

PowerShell to install uninstall dll from GAC

Most of the we need to install and uninstall dll from GAC,so here is the simple set of script to simplify this task.

#replace it with your dll path 
$dllPath ="C:\temp\FileName.dll" 
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")            
$publish = New-Object System.EnterpriseServices.Internal.Publish      

#to unistall dll from GAC
$publish.GacRemove($dllPath)
iisreset

#to install dll from GAC
$publish.GacInstall($dllPath)
iisreset

Download Source code

Deactivate multiple accounts from EPM/Project Server

Sometimes it required to deactivated multiple accounts in EPM. So here is the script which can help you to deactivate multiple accounts. Account deactivation takes so much time so it is recommended to do this activity non business hour.

<# Below is CSV sample which I am using for this code. First Column is headers. #>;
<#
ResourcesEmail
kuldeep.verma@xyz.com
rajdeep.sardesai@xyz.com
Jaydeep.prajapat@xyz.com
#>

#Download and install Microsoft Client Component from https://www.microsoft.com/en-in/download/details.aspx?id=42038
#Microsoft SharePoint Client Component is mandatory to move further.
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.ProjectServer.Client.dll"

#replace CSV path
$path = "<Path of input CSV file>"
$siteURL = "<Replace With PWA URL>"  
$loginname = "<User Account>"  
$pwd = "<Password>"  
$securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force
$creds = New-Object System.Management.Automation.PsCredential $loginname, $securePassword
$projContext = New-Object Microsoft.ProjectServer.Client.ProjectContext($siteURL)
$projContext.Credentials = $creds
$resources = $projContext.EnterpriseResources
$projContext.Load($resources)
$projContext.ExecuteQuery()
Import-Csv $path | ForEach-Object {
    $UserEmail=$_.ResourcesEmail
    <#Check user is available or not in resource center#>
    $resourcesToDeactivate = $resources | ? { $_.Email -eq $UserEmail -and $_.IsActive -eq $true }
    if($null -ne $resourcesToDeactivate)
    {
        $Name =$resourcesToDeactivate.Name
        Write-Host "$Name started to deactivating" -foreground yellow
        $resourcesToDeactivate.IsActive = $false
        $projContext.EnterpriseResources.Update()
        $projContext.ExecuteQuery()
        Write-Host "$Name account has been deactivated" -foreground green
    }
}
Write-Host "All users has been deactivated successfully" -foreground blue