Quantcast
Channel: SharePoint Pals - PowerShell
Viewing all 31 articles
Browse latest View live

Resource Quota and Throttling in SharePoint Online

$
0
0

One or other day you might end up seeing this message in SharePoint Online Admin center stating  that your resource quota is full.

clip_image002

First let’s try to understand what have gone wrong. If you create your site collection using PowerShell script and If you don’t provide any value for the QUOTA parameter, the default value would be taken for consideration and that is 300 and that’s the same case if you create from UI (Admin center) 300 is the pre-defined value.

Assume we end up creating thousands of site with 300 as the default value then, at one point in time we would end up seeing this.

As per MS: Total server resource quota is based upon the number of users in your tenant and is intended to be shared across all site collections. more

Since MS is going to depreciate Sandbox Solution, is it recommended to have 0 resources allotted to the Site collection? The resource quota comes into picture only if you have sandbox solutions active on your site collections. You can have site collections having no resources allocated.

Now let’s see how to bring the resource number down

 foreach($S in (Get-Content C:\test\resource.txt)) { 	Set-SPOSite -Identity $S -ResourceQuota 0 	#Get-SPOSite -Identity $S |select ResourceQuota |ft 	Write-Host $S }  

The resource.txt should have all the site collection to which you want to bring the resource to 0.

Note: If your tenant resources are completely full, we mightn’t be able to run this script, in that case, for the first couple of site collection you might have reduce site manually (may be for 5 site collection) and then re-run this script.

Next part, I would like to share is more on the SharePoint online getting Throttled.

If you’re migrating content in GB’s/modifying metadata for (1000) of files (Right now we don’t have a correct number shared by MS) but let me take a scenario if we’re moving GB’s of data with one single account, it’s expected that our tenant would get throttle.

What MS says:

What is throttling?

SharePoint Online uses throttling to maintain optimal performance and reliability of the SharePoint Online service. Throttling limits the number of user actions or concurrent calls (by script or code) to prevent overuse of resources.

That said, it is extremely rare for a user to get throttled in SharePoint Online. The service is robust, and it is designed to handle very high volume. If you do get throttled, 99% of the time it is because of custom code. That doesn’t mean that there aren’t other ways to get throttled, just that they are less common. For example, you spin up 10 machines and have a sync client going on all 10. On each sync 1TB of content. This would likely get you throttled.

Work Around

Here is what we did to overcome throttling because of migrating the data, we created multiple account and move these data using each of the account, since MS throttles based on individual user account…

Please refer to know more around throttling.


How to block or disable Office 365 Services

$
0
0

We don’t have any clear mechanism to disable POWER APP and MS FLOW from the ADMIN Centre of Office 365, as MS as moved these two services under E 4 license

The below PowerShell script would help disabling those:

 import-csv calip.csv | foreach-object {     // Input UPN name from the file and Start the Loop    $Teams = "Disabled"; $Sway = "Enabled"; $flow ="Disabled" ; $powerapps = "Disabled" ; $rms = "Disabled"; $voice = "Disabled" ; $project = "Enabled" $intune = "Enabled" ; $yammer = "Enabled" ; $office = "Enabled" ; $mcost = "Enabled" ; $spwac = "Enabled" ; $sp = "Enabled" ; $exc = "Enabled"         // Declare Variables  (Get-MsolUser -User $_.Upn).Licenses[0].ServiceStatus | ForEach {          //Check the Current license status for all the users   If ($_.ServicePlan.ServiceName -eq "SWAY" –and $_.ProvisioningStatus -eq "Disabled") { $Sway = "Disabled" }   // If exisiting status is Disabled update the Variable to Disabled  If ($_.ServicePlan.ServiceName -eq "PROJECTWORKMANAGEMENT" –and $_.ProvisioningStatus -eq "Disabled") { $project = "Disabled" }  If ($_.ServicePlan.ServiceName -eq "INTUNE_O365" –and $_.ProvisioningStatus -eq "Disabled") { $intune = "Disabled" }  If ($_.ServicePlan.ServiceName -eq "YAMMER_ENTERPRISE" –and $_.ProvisioningStatus -eq "Disabled") { $yammer = "Disabled" }  If ($_.ServicePlan.ServiceName -eq "MCOSTANDARD" –and $_.ProvisioningStatus -eq "Disabled") { $mcost = "Disabled" }  If ($_.ServicePlan.ServiceName -eq "SHAREPOINTWAC" –and $_.ProvisioningStatus -eq "Disabled") { $spwac = "Disabled" }  If ($_.ServicePlan.ServiceName -eq "SHAREPOINTENTERPRISE" –and $_.ProvisioningStatus -eq "Disabled") { $sp = "Disabled" }  If ($_.ServicePlan.ServiceName -eq "EXCHANGE_S_ENTERPRISE" –and $_.ProvisioningStatus -eq "Disabled") { $exc = "Disabled" }  }   $DisabledOptions = @()   //Declare Array   If ($Sway -eq "Disabled") { $DisabledOptions += "SWAY" }        // Based on the variable Add the plans to disable in Variable  If ($Teams -eq "Disabled") { $DisabledOptions += "TEAMS1" }    // Append the plans to Disable  If ($flow -eq "Disabled") { $DisabledOptions += "FLOW_O365_P2" }  If ($powerapps -eq "Disabled") { $DisabledOptions += "POWERAPPS_O365_P2" }  If ($rms -eq "Disabled") { $DisabledOptions += "RMS_S_ENTERPRISE" }  If ($voice -eq "Disabled") { $DisabledOptions += "MCOVOICECONF" }  If ($project -eq "Disabled") { $DisabledOptions += "PROJECTWORKMANAGEMENT" }  If ($intune -eq "Disabled") { $DisabledOptions += "INTUNE_O365" }  If ($yammer -eq "Disabled") { $DisabledOptions += "YAMMER_ENTERPRISE" }  If ($mcost -eq "Disabled") { $DisabledOptions += "MCOSTANDARD" }  If ($spwac -eq "Disabled") { $DisabledOptions += "SHAREPOINTWAC" }  If ($sp -eq "Disabled") { $DisabledOptions += "SHAREPOINTENTERPRISE" }  If ($exc -eq "Disabled") { $DisabledOptions += "EXCHANGE_S_ENTERPRISE" }   $LicenseOptions = New-MsolLicenseOptions –AccountSkuId "Collaboration:ENTERPRISEWITHSCAL" –DisabledPlans $DisabledOptions     // Store the new license option in the Variable 
  Set-MsolUserLicense –User $_.UPN –LicenseOptions $LicenseOptions    // Apply the new license option from the file 
  $cool = $_.UPN  // Used to check how many users completed from the file in case if script breaks due to server error    }

Note: Disabling TEAM using PowerShell didn’t work as expected, the only option to disable TEAM is by going to Services & add-ins under ADMIN Center and disable TEAM.

To know the latest happening around PowerAPP and MS FLOW please refer

StaffHub

It’s a new feature from MS and it’s in preview, Once you have signed up for the preview, you can assign the Microsoft StaffHub licenses to users. This PowerShell Script will apply the license to EVERYONE in your tenant.  Note: Please make sure everyone you want to have access to Microsoft StaffHub ALSO has a K1, E1, E3, or E5 license assigned.

 Connect-MsolService  $licenseObj = Get-MsolAccountSku | Where-Object {$_.SkuPartNumber -eq “DESKLESS"}  $license = $licenseObj.AccountSkuId  Get-MSOLUser -All | Set-MsolUserLicense -AddLicenses $license 

PowerShell Script To Uninstall App From SharePoint Online

$
0
0

In the recent past we added some third party apps from SharePoint Store to SharePoint Online App catalog site. But they where not available for users on SPO site's under "Apps You can Add" section.
So, we  tried uninstalling the APP and got the following error messages

The Url '/sites/TSTAppCatalogue/APP NAME' cannot be resolved to a web. The web may be temporarily unavailable. And received the following error too.

An expected exception was thrown while running task 'GetMyApps'. Microsoft.SharePoint.SPException: Error in the application.     at Microsoft.SharePoint.ApplicationPages.StorefrontBase.TaskGetMyApps()

We suspect that the app was not properly installed because of the presence of a stale entry and we are looking for possibilities to completely remove the app from appcatalog and then re-install it again.

Manual un-installing wasn’t fixing the issue. But removing it Via script work.

Uninstallation Script

 [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client") [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")   Function Get-ClientContext([string]$Url,[string]$UserName,[string]$Password) {     $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force     $context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)     $context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)     return $context }   Function Uninstall-AppInstance([Microsoft.SharePoint.Client.ClientContext]$Context,[Guid]$AppInstanceId) {     $appInst = $Context.Web.GetAppInstanceById($AppInstanceId)     $appInst.Uninstall()     $context.ExecuteQuery()  }   $UserName = "USER ID" $Password = Read-Host -AsSecureString "Enter the password"     $Url = " appcatalog URL" $AppInstanceid = New-Object Guid("xxxx-xx-xx-xx-xxxx")  #specify App Instance Id here  $creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $Password)  $context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)   $context.credentials = $creds    Uninstall-AppInstance -Context $context -AppInstanceId $AppInstanceid $context.Dispose()

PowerShell Script – CSOM – Enable Disable Modern UI and Classic UI in SharePoint Office 365

$
0
0

In this article, we can see a handy script to toggle between the Modern UI and Classic UI in SharePoint Office 365.

The default Modern UI of Site will be as below.

clip_image002

To enable the Classic View, we have a link on the left bottom.

clip_image003



The PowerShell Script to toggle between the Modern UI and the Classic UI is as below.

 # Add Necessary Client DLLs Add-Type -Path "C:\SATHISH\ARTICLES\ClientDLLs\Microsoft.SharePoint.Client.dll"  Add-Type -Path "C:\SATHISH\ARTICLES\ClientDLLs\Microsoft.SharePoint.Client.Runtime.dll"   #Get the UserName and Password $UserName = "sathish@*****.onmicrosoft.com" $password = Read-Host 'Enter Password' -AsSecureString $Url = "https://**********.sharepoint.com/sites/DeveloperSite/" $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName , $Password)  $context = New-Object Microsoft.SharePoint.Client.ClientContext($Url) $context.Credentials = $credentials          #Get the Web Scoped Feature  $web = $context.Web # Feature Title : EnableDefaultListLibrarExperience, Scope : Web $featureguid = new-object System.Guid "52E14B6F-B1BB-4969-B89B-C4FAA56745EF"   #To Enable/Disable the Modern UI, comment and uncomment the below two lines, either to Add or Remove #$web.Features.Add($featureguid, $true, [Microsoft.SharePoint.Client.FeatureDefinitionScope]::None) $web.Features.Remove($featureguid, $true)          $context.ExecuteQuery()     #Get the Site Scoped Feature $Site = $context.Site # Feature Title : EnableDefaultListLibrarExperience, Scope : Site $featureguid = new-object System.Guid "E3540C7D-6BEA-403C-A224-1A12EAFEE4C4"   #To Enable/Disable the Modern UI, comment and uncomment the below two lines, either to Add or Remove #$Site.Features.Add($featureguid, $true, [Microsoft.SharePoint.Client.FeatureDefinitionScope]::None) $Site.Features.Remove($featureguid, $true)          $context.ExecuteQuery()   


Happy Coding,

Sathish Nadarajan.

Lambda Expression in SharePoint CSOM PowerShell

$
0
0

In the CSOM, we might have using the Lambda Expression => frequently to load only the required properties. But the Lambda Expression is an Operator in C# not in PowerShell. When, we started coding with the PowerShell CSOM intensively, I required this Lambda to be replaced with its equivalent. When searching for that, Got a wonderful article by Gary here. Wanted to make it to be handy here as well.

To be more precise, let us see a scenario in C#.

 using (var ctx = authMgr.GetSharePointOnlineAuthenticatedContextTenant(siteUrl, userName, password))             {                 Web web = ctx.Web;                 ctx.Load(web.Lists);                 ctx.Load(web);                  ctx.ExecuteQueryRetry();                  List list = web.Lists.GetByTitle("D1");                 ctx.Load(list);                 ctx.Load(list, li => li.HasUniqueRoleAssignments);                 ctx.ExecuteQuery();                  System.Console.WriteLine(Convert.ToString(list.HasUniqueRoleAssignments));             } 
Gary has come up with a Method which is equivalent to our Lambda Expression – Load-CSOMProperties

The Lambda Expression method is as below. (Re-wrote from Gary’s article)

 <# .Synopsis     Facilitates the loading of specific properties of a Microsoft.SharePoint.Client.ClientObject object or Microsoft.SharePoint.Client.ClientObjectCollection object. .DESCRIPTION     Replicates what you would do with a lambda expression in C#.      For example, "ctx.Load(list, l => list.Title, l => list.Id)" becomes     "Load-CSOMProperties -object $list -propertyNames @('Title', 'Id')". .EXAMPLE     Load-CSOMProperties -parentObject $web -collectionObject $web.Fields -propertyNames @("InternalName", "Id") -parentPropertyName "Fields" -executeQuery     $web.Fields | select InternalName, Id .EXAMPLE    Load-CSOMProperties -object $web -propertyNames @("Title", "Url", "AllProperties") -executeQuery    $web | select Title, Url, AllProperties #>  function global:Load-CSOMProperties {     [CmdletBinding(DefaultParameterSetName='ClientObject')]     param (         # The Microsoft.SharePoint.Client.ClientObject to populate.         [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0, ParameterSetName = "ClientObject")]         [Microsoft.SharePoint.Client.ClientObject]         $object,          # The Microsoft.SharePoint.Client.ClientObject that contains the collection object.         [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0, ParameterSetName = "ClientObjectCollection")]         [Microsoft.SharePoint.Client.ClientObject]         $parentObject,          # The Microsoft.SharePoint.Client.ClientObjectCollection to populate.         [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 1, ParameterSetName = "ClientObjectCollection")]         [Microsoft.SharePoint.Client.ClientObjectCollection]         $collectionObject,          # The object properties to populate         [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "ClientObject")]         [Parameter(Mandatory = $true, Position = 2, ParameterSetName = "ClientObjectCollection")]         [string[]]         $propertyNames,          # The parent object's property name corresponding to the collection object to retrieve (this is required to build the correct lamda expression).         [Parameter(Mandatory = $true, Position = 3, ParameterSetName = "ClientObjectCollection")]         [string]         $parentPropertyName,          # If specified, execute the ClientContext.ExecuteQuery() method.         [Parameter(Mandatory = $false, Position = 4)]         [switch]         $executeQuery     )      begin { }     process {         if ($PsCmdlet.ParameterSetName -eq "ClientObject") {             $type = $object.GetType()         } else {             $type = $collectionObject.GetType()              if ($collectionObject -is [Microsoft.SharePoint.Client.ClientObjectCollection]) {                 $type = $collectionObject.GetType().BaseType.GenericTypeArguments[0]             }         }          $exprType = [System.Linq.Expressions.Expression]         $parameterExprType = [System.Linq.Expressions.ParameterExpression].MakeArrayType()         $lambdaMethod = $exprType.GetMethods() | ? { $_.Name -eq "Lambda" -and $_.IsGenericMethod -and $_.GetParameters().Length -eq 2 -and $_.GetParameters()[1].ParameterType -eq $parameterExprType }         $lambdaMethodGeneric = Invoke-Expression "`$lambdaMethod.MakeGenericMethod([System.Func``2[$($type.FullName),System.Object]])"         $expressions = @()          foreach ($propertyName in $propertyNames) {             $param1 = [System.Linq.Expressions.Expression]::Parameter($type, "p")             try {                 $name1 = [System.Linq.Expressions.Expression]::Property($param1, $propertyName)             } catch {                 Write-Error "Instance property '$propertyName' is not defined for type $type"                 return             }             $body1 = [System.Linq.Expressions.Expression]::Convert($name1, [System.Object])             $expression1 = $lambdaMethodGeneric.Invoke($null, [System.Object[]] @($body1, [System.Linq.Expressions.ParameterExpression[]] @($param1)))               if ($collectionObject -ne $null) {                 $expression1 = [System.Linq.Expressions.Expression]::Quote($expression1)             }             $expressions += @($expression1)         }           if ($PsCmdlet.ParameterSetName -eq "ClientObject") {             $object.Context.Load($object, $expressions)             if ($executeQuery) { $object.Context.ExecuteQuery() }         } else {             $newArrayInitParam1 = Invoke-Expression "[System.Linq.Expressions.Expression``1[System.Func````2[$($type.FullName),System.Object]]]"             $newArrayInit = [System.Linq.Expressions.Expression]::NewArrayInit($newArrayInitParam1, $expressions)              $collectionParam = [System.Linq.Expressions.Expression]::Parameter($parentObject.GetType(), "cp")             $collectionProperty = [System.Linq.Expressions.Expression]::Property($collectionParam, $parentPropertyName)              $expressionArray = @($collectionProperty, $newArrayInit)             $includeMethod = [Microsoft.SharePoint.Client.ClientObjectQueryableExtension].GetMethod("Include")             $includeMethodGeneric = Invoke-Expression "`$includeMethod.MakeGenericMethod([$($type.FullName)])"              $lambdaMethodGeneric2 = Invoke-Expression "`$lambdaMethod.MakeGenericMethod([System.Func``2[$($parentObject.GetType().FullName),System.Object]])"             $callMethod = [System.Linq.Expressions.Expression]::Call($null, $includeMethodGeneric, $expressionArray)                          $expression2 = $lambdaMethodGeneric2.Invoke($null, @($callMethod, [System.Linq.Expressions.ParameterExpression[]] @($collectionParam)))              $parentObject.Context.Load($parentObject, $expression2)             if ($executeQuery) { $parentObject.Context.ExecuteQuery() }         }     }     end { } }  
After this, we can use the method Load-CSOMProperties which is similar to our Lambda Expression.

The actual Usage is as follows.

 # Add Necessary Client DLLs Add-Type -Path "C:\SATHISH\ClientDLLs\Microsoft.SharePoint.Client.dll"  Add-Type -Path "C:\SATHISH\ ClientDLLs\Microsoft.SharePoint.Client.Runtime.dll"   #Get the UserName and Password $UserName = "sathish@*******.onmicrosoft.com" $password = Read-Host 'Enter Password' -AsSecureString $Url = "https://*******.sharepoint.com/sites/DeveloperSite/" $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName , $Password)  $context = New-Object Microsoft.SharePoint.Client.ClientContext($Url) $context.Credentials = $credentials            #Get the Web $web = $context.Web $context.Load($web) #Get the Lists in the Web $context.Load($web.Lists) $context.ExecuteQuery()   #Get a specific List $list = $web.Lists.GetByTitle("RamList")  #Usage of Lambda Operator.  I am Loading the HasUniqueRoleASsignments similar to #the Lambda Operator  Load-CSOMProperties -object $list -propertyNames @("HasUniqueRoleAssignments")  $context.ExecuteQuery();  Write-Host $list.HasUniqueRoleAssignments  

Happy Coding,

Sathish Nadarajan.

How to Update Navigation (Quick Launch and Top NavigationBar) URLs in SharePoint 2010 using PowerShell CSOM

$
0
0

During the Migration from SP2010 to SP2016, if the Quick Launch or the Top Navigation of the Source Sites were having the Full URL, (e.g., https://mySP2010Site.com/Sites/SiteCollection/MyList/Forms/AllItems.aspx), then any Migration tool will migrate the Navigation URLs as it is. Hence, in the Target, if we click on the Link, then it will go to the Source Link, not the Target Link. For that, before migrating the content, we can update the URLs with relating Path. i.e., /sites/sitecollection/MyList/Forms/AllItems.aspx. By doing this, when we migrate, the Target will also have the relative path which will be the corresponding target site collection’s path. Though this may not work for different web applications/different tenants, but somehow this will fix the initial problem statement.

Let us see the detailed script, which will update the Quick Launch and the Navigation Bars using PowerShell CSOM in SP2010 Environment. The below script, I wrote it for two levels only. We can make the update statement as a recursive method, so that it will update any level of the Links.

 # Update the Navigation (QuickLaunch and TopNavigationBar) URLs  ##================================================================================================ ## Description	:      #Update the Navigation (QuickLaunch and TopNavigationBar) URLs   ## Author		: Sathish Nadarajan ## Date			:  ##================================================================================================  # ============================================ Setup Input Paths =================================   cls    $Host.UI.RawUI.WindowTitle = "-- Update QuickLaunch and TopNavigationBar URLs--"  $StartDate = Get-Date Write-Host -ForegroundColor White "------------------------------------" Write-Host -ForegroundColor White "| Update QuickLaunch and TopNavigationBar URLs |" Write-Host -ForegroundColor White "| Started on: $StartDate |" Write-Host -ForegroundColor White "------------------------------------"  $LogTime = Get-Date -Format yyyy-MM-dd_hh-mm  ################# Set the Current Path as Execution Path ####################  $scriptBase = split-path $SCRIPT:MyInvocation.MyCommand.Path -parent Set-Location $scriptBase  ############# set the Error Preference ################  $ErrorActionPreference = "SilentlyContinue"  # Create Log File Folder if(!(TEST-PATH ".\Logs-$LogTime"))  {    NEW-ITEM ".\Logs-$LogTime" -type Directory }  # Assign the Log and Progress Files $TranscriptFile = ".\Logs-$LogTime\UpdateNavigationLinks.Transcript.rtf"  try{   stop-transcript|out-null } catch [System.InvalidOperationException]{}  start-transcript $TranscriptFile   function AddCSOM(){      #Load SharePoint client dlls       $a = [System.Reflection.Assembly]::LoadFile(    "$scriptBase\ClientLibraries\Microsoft.SharePoint.Client.dll")       $ar = [System.Reflection.Assembly]::LoadFile(    "$scriptBase\ClientLibraries\Microsoft.SharePoint.Client.Runtime.dll")             if( !$a ){          $a = [System.Reflection.Assembly]::LoadWithPartialName(        "Microsoft.SharePoint.Client")      }      if( !$ar ){          $ar = [System.Reflection.Assembly]::LoadWithPartialName(        "Microsoft.SharePoint.Client.Runtime")      }            if( !$a -or !$ar ){          throw         "Could not load Microsoft.SharePoint.Client.dll or Microsoft.SharePoint.Client.Runtime.dll"      }                  #Add overload to the client context.      #Define new load method without type argument      $csharp =     "       using Microsoft.SharePoint.Client;       namespace SharepointClient       {           public class PSClientContext: ClientContext           {               public PSClientContext(string siteUrl)                   : base(siteUrl)               {               }               // need a plain Load method here, the base method is a generic method               // which isn't supported in PowerShell.               public void Load(ClientObject objectToLoad)               {                   base.Load(objectToLoad);               }           }       }"            $assemblies = @( $a.FullName, $ar.FullName,     "System.Core")      #Add dynamic type to the PowerShell runspace      Add-Type -TypeDefinition $csharp -ReferencedAssemblies $assemblies }   AddCSOM  $credentials = Get-Credential  #Get inthe Input CSV File $SubSiteURLCSV = $scriptBase + "\" + "SubSiteURLs.csv"     cls  $originalURL = " https://mySP2010Site.com/"  #Read and Iterate through all the Sites Given in the SubSiteURLs.CSV import-csv $SubSiteURLCSV | where{     Write-Host "Processing the Site : " $_.SubSiteURL -ForeGroundColor Green                      $context = New-Object SharepointClient.PSClientContext($_.SubSiteURL)     $totalDocLibSize =0          $totalListSize=0     $totalWebSize=0           $context.Credentials = $credentials          #Load the basic information about the web and site     $context.Load($context.Web)     $context.Load($context.Web.Navigation.QuickLaunch)     $context.Load($context.Web.Navigation.TopNavigationBar)     $context.Load($context.Site)     $context.Load($context.Web.Lists)     $context.ExecuteQuery()                    ############### BEGIN QUICK LAUNCH ################################     Write-Host "Processing the Quick Launch (Left Navigation)"     foreach($quickLaunch in $context.Web.Navigation.QuickLaunch)     {         $context.Load($quickLaunch)         $context.Load($quickLaunch.Url)         $context.Load($quickLaunch.Children)         $context.ExecuteQuery()                  ############### PARENT LINKS #################################         if($quickLaunch.Url -like  ('*'+$originalURL+'*'))         {             Write-Host "Updating the Link : " $quickLaunch.Title             $temp = $quickLaunch.Url             $temp = $temp.Replace($originalURL, "")                          $quickLaunch.Url = $temp             $quickLaunch.Update()             $context.Load($quickLaunch)             $context.ExecuteQuery()         }                  ########### FIRST LEVEL CHILD LINKS ##########################         foreach($quickLink in $quickLaunch.Children)         {             $context.Load($quickLink)             $context.Load($quickLink.Url)             $context.ExecuteQuery()                      if($quickLink.Url -like ('*'+$originalURL+'*'))             {                 Write-Host "Updating the Child Link : " $quickLink.Title                 $temp = $quickLink.Url                 $temp = $temp.Replace($originalURL, "")                                  $quickLink.Url = $temp                 $quickLink.Update()                 $context.Load($quickLink)                 $context.ExecuteQuery()             }         }             }          ############ END QUICK LAUNCH ####################################          ############### BEGIN TOPNAVIGATIONBAR ################################     Write-Host "Processing the NavigationBar (Top Navigation)"          foreach($quickLaunch in $context.Web.Navigation.TopNavigationBar)     {         $context.Load($quickLaunch)         $context.Load($quickLaunch.Url)         $context.Load($quickLaunch.Children)         $context.ExecuteQuery()                  ############### PARENT LINKS #################################         if($quickLaunch.Url -like  ('*'+$originalURL+'*'))         {             Write-Host "Updating the Top Link : " $quickLaunch.Title             $temp = $quickLaunch.Url             $temp = $temp.Replace($originalURL, "")                          $quickLaunch.Url = $temp             $quickLaunch.Update()             $context.Load($quickLaunch)             $context.ExecuteQuery()         }                  ########### FIRST LEVEL CHILD LINKS ##########################         foreach($quickLink in $quickLaunch.Children)         {             $context.Load($quickLink)             $context.Load($quickLink.Url)             $context.ExecuteQuery()                      if($quickLink.Url -like ('*'+$originalURL+'*'))             {                 Write-Host "Updating the top Child Link : " $quickLink.Title                 $temp = $quickLink.Url                 $temp = $temp.Replace($originalURL, "")                                  $quickLink.Url = $temp                 $quickLink.Update()                 $context.Load($quickLink)                 $context.ExecuteQuery()             }         }             }          ############ END QUICK LAUNCH ####################################       }  Write-Host "Process Completed..  Press Enter to Exit" -ForeGroundColor Green   try{   stop-transcript|out-null } catch [System.InvalidOperationException]{}        

Happy Coding,

Sathish Nadarajan.

How to Execute the Client Object Model PowerShell Script and get the Client Context on SharePoint 2010

$
0
0

Recently for one of the requirement, we were supposed to write the PowerShell Client Object Model Script to run against SharePoint 2010. We have written a lot of code on the SSOM for SP2010 and CSOM for SP2013 or above. But, for the first time, met with this strange requirement stating CSOM Script for SP2010. Though it does not support few functionalities, we can achieve some of the basic functionalities with this.

In this article, we are going to see, how to add the Client DLL and how to create the client context. In the upcoming articles, let us see, how to do various functionalities using CSOM PowerShell in SP2010.

  cls    $Host.UI.RawUI.WindowTitle = "-- Get Site Context --"  $StartDate = Get-Date Write-Host -ForegroundColor White "------------------------------------" Write-Host -ForegroundColor White "| Get Site Context  |" Write-Host -ForegroundColor White "| Started on: $StartDate |" Write-Host -ForegroundColor White "------------------------------------"  $LogTime = Get-Date -Format yyyy-MM-dd_hh-mm  ################# Set the Current Path as Execution Path ####################  $scriptBase = split-path $SCRIPT:MyInvocation.MyCommand.Path -parent Set-Location $scriptBase  ############# set the Error Preference ################  $ErrorActionPreference = "SilentlyContinue"   # Create Log File Folder if(!(TEST-PATH ".\Logs-$LogTime"))  {    NEW-ITEM ".\Logs-$LogTime" -type Directory }  # Create Report File Folder if(!(TEST-PATH ".\Reports-$LogTime"))  {    NEW-ITEM ".\Reports-$LogTime" -type Directory }  # Assign the Log and Progress Files $TranscriptFile = ".\Logs-$LogTime\GetSiteInfo.Transcript.rtf"    try{   stop-transcript|out-null } catch [System.InvalidOperationException]{}  start-transcript $TranscriptFile  function AddCSOM(){      #Load SharePoint client dlls       $a = [System.Reflection.Assembly]::LoadFile(    "$scriptBase\ClientLibraries\Microsoft.SharePoint.Client.dll")       $ar = [System.Reflection.Assembly]::LoadFile(    "$scriptBase\ClientLibraries\Microsoft.SharePoint.Client.Runtime.dll")             if( !$a ){          $a = [System.Reflection.Assembly]::LoadWithPartialName(        "Microsoft.SharePoint.Client")      }      if( !$ar ){          $ar = [System.Reflection.Assembly]::LoadWithPartialName(        "Microsoft.SharePoint.Client.Runtime")      }            if( !$a -or !$ar ){          throw         "Could not load Microsoft.SharePoint.Client.dll or Microsoft.SharePoint.Client.Runtime.dll"      }                  #Add overload to the client context.      #Define new load method without type argument      $csharp =     "       using Microsoft.SharePoint.Client;       namespace SharepointClient       {           public class PSClientContext: ClientContext           {               public PSClientContext(string siteUrl)                   : base(siteUrl)               {               }               // need a plain Load method here, the base method is a generic method               // which isn't supported in PowerShell.               public void Load(ClientObject objectToLoad)               {                   base.Load(objectToLoad);               }           }       }"            $assemblies = @( $a.FullName, $ar.FullName,     "System.Core")      #Add dynamic type to the PowerShell runspace      Add-Type -TypeDefinition $csharp -ReferencedAssemblies $assemblies }  AddCSOM  $credentials = Get-Credential    cls        $SubSiteURL = "https://sppalsmvp.sharepoint2010.com/sites/myteamsite"      Write-Host "Processing the Site - " $SubSiteURL  -Foreground Yellow      $context = New-Object SharepointClient.PSClientContext($_.SubSiteURL)     $context.Credentials = $credentials                $web = $context.Web           $context.Load($web)           $context.Load($web.Lists)          $context.ExecuteQuery()        Write-Host "Web Title " $web.Title        Write-Host "Process Completed..  Press Enter to Exit" -ForeGroundColor Green   try{   stop-transcript|out-null } catch [System.InvalidOperationException]{}        
The above code will write the Web Title by CSOM.


DOWNLOAD THE DLLs HERE



Happy Coding,

Sathish Nadarajan.

PowerShell ISE is missing in Windows Server 2016 Development Box

$
0
0

Recently, I prepared a Dev box Windows Server 2016 and was about to write a PowerShell Script on it. But surprisingly, the PowerShell ISE was not available. I could see only the PowerShell Window.

To enable the PowerShell ISE

1. Go to Server Manager

2. Go the Features

3. Select the Feature Windows PowerShell ISE

4. Install.

clip_image002

After the installation, the ISE will be appearing.

clip_image004

Happy Coding,

Sathish Nadarajan.


How to Read the Data Source Information of a RDL RDLX files in SharePoint using PowerShell Script

$
0
0


In this article, let us see how to read the Data Source Information of RDL/RDLX file in SharePoint using PowerShell Script. This will fit for SP2010, 2013, 2016 as well. Only the Client DLLs should be updated accordingly. The core logic remains the same.

 ################# Set the Current Path as Execution Path ####################  $scriptBase = split-path $SCRIPT:MyInvocation.MyCommand.Path -parent Set-Location $scriptBase  ############# set the Error Preference ################  $ErrorActionPreference = "SilentlyContinue"   function AddCSOM(){      #Load SharePoint client dlls       $a = [System.Reflection.Assembly]::LoadFile(    "$scriptBase\ClientLibraries\Microsoft.SharePoint.Client.dll")       $ar = [System.Reflection.Assembly]::LoadFile(    "$scriptBase\ClientLibraries\Microsoft.SharePoint.Client.Runtime.dll")             if( !$a ){          $a = [System.Reflection.Assembly]::LoadWithPartialName(        "Microsoft.SharePoint.Client")      }      if( !$ar ){          $ar = [System.Reflection.Assembly]::LoadWithPartialName(        "Microsoft.SharePoint.Client.Runtime")      }            if( !$a -or !$ar ){          throw         "Could not load Microsoft.SharePoint.Client.dll or Microsoft.SharePoint.Client.Runtime.dll"      }                  #Add overload to the client context.      #Define new load method without type argument      $csharp =     "       using Microsoft.SharePoint.Client;       namespace SharepointClient       {           public class PSClientContext: ClientContext           {               public PSClientContext(string siteUrl)                   : base(siteUrl)               {               }               // need a plain Load method here, the base method is a generic method               // which isn't supported in PowerShell.               public void Load(ClientObject objectToLoad)               {                   base.Load(objectToLoad);               }           }       }"            $assemblies = @( $a.FullName, $ar.FullName,     "System.Core")      #Add dynamic type to the PowerShell runspace      Add-Type -TypeDefinition $csharp -ReferencedAssemblies $assemblies }   AddCSOM  $credentials = Get-Credential   #Create and add the headers on the CSV File Add-Content $DataSource_CSV_Path "FileURL, DataSourceName, DataSourceURL, ConnectString, DataSourceType"                           $context = New-Object SharepointClient.PSClientContext("https://MYSitecollection")               $context.Credentials = $credentials          #Load the basic information about the web and site     $context.Load($context.Web)     $context.Load($context.Site)     $context.Load($context.Web.Lists)     $context.ExecuteQuery()      #SSRS Proxy     $targeturl="$($context.Web.Url)/_vti_bin/ReportServer/ReportService2010.asmx";     $targetProxy = New-WebServiceProxy -Uri  $targeturl -UseDefaultCredential;       $($ssrs.url);       # Iterate through the Lists     foreach ($list in $context.Web.Lists)      {         #Load the information about the List         $context.Load($list)         $context.Load($list.BaseType)         $context.Load($list.Items)         $context.ExecuteQuery()                           # validate for Document Library         if ($list.BaseType -eq “DocumentLibrary”) 
         {                        $camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery             $camlQuery.ViewXml ="<View Scope='RecursiveAll' />";             $allItems=$list.GetItems($camlQuery)             $context.Load($allItems)             $context.ExecuteQuery()                         foreach($item in $allItems)             {                 if($item.FileSystemObjectType -eq "File")                 {                     $file = $item.File                     $fItem = $file.ListItemAllFields                     $context.Load($file)                     $context.Load($fItem)                                                         $context.ExecuteQuery()                                                #Read .rdl files available in the library                                                if($file.Name.ToLower().Contains(".rdl") -or $file.Name.ToLower().Contains("rdlx"))                                                {                                            $fullURL = 'http://Mysitecollection' + $file.ServerRelativeUrl                         $dataSources = $SSRS.GetItemDataSources($fullURL);                          Write-Host "RDL file Count : "  $dataSources.Count                          if ($datasources.count -gt 0)                         {                          foreach ($DataSource in $dataSources){                           Write-Host "$($DataSource.name) : $($DataSource.item.reference)";                            if($DataSource.item.reference)                           {                             $DataSourceType="Shared"                           }                           if($DataSource.Item.ConnectString)                           {                             $DataSourceType="Custom"                           }                           Add-Content -Path $DataSource_CSV_Path -Value ($fullURL+','+$DataSource.name +','+$DataSource.Item.Reference+','+$DataSource.Item.ConnectString+','+$DataSourceType)                         }                                                 }                    }                            }      }     }           } 

Happy Coding,

Sathish Nadarajan.

Converting document to record for onprem SharePoint site and changing back the settings to autodeclartion of record

$
0
0

If we are migrating data from other application or uploading data to record center through CSOM the data will be uploaded as record, but there is any issue if we want to update any meta data column, since record type is read only once we upload document we cant edit , to edit or to update any meta data column by default, to update the document properties, before uploading the document the autodeclartion of record settings need to change to manual declaration of record, after changing the settings document will be uploaded or migrate data in the form document, then after updating the metadata the document need to be converted as record

For Onprem site there is no client “RecordsRepository” dll exposed for converting document to record, so we need to go with powershell or server side, code let me explain the powershell script for converting document to record and changing back the settings to autodeclartion of record

Suppose if you have multiple sites or multiple list then provide Siteurl and ListName in the csv file and place it in common folder, while executing the provide the path of the csv file and I have logged only exception in the log file

 Add-PSSnapin "Microsoft.SharePoint.PowerShell" $File=REad-host -promp 'Enter the path for input CSV File' $LogFilePath="D:\recordlog\recordlog.log" $tblData=Import-CSV $File   foreach($row in $tblData) { try { $mySite = $row.SiteURL write-host $SiteURL $Listname=$row.ListName write-host $Listname $spSite = Get-SPSite -Identity $mySite; $spWeb = $spSite.OpenWeb(); Write-Host $spWeb.Url; $list = $spWeb.GetList($spWeb.Url + "/"+$Listname); Write-Host $list.Title Write-Host $list.ItemCount; foreach ($item in $list.Items) { try {  	$IsRecord = [Microsoft.Office.RecordsManagement.RecordsRepository.Records]::IsRecord($Item) $ItemType=$item.FileSystemObjectType  if($ItemType -eq "File") { 	if ($IsRecord -ne $true){ 		Write-Host "Declared for " $item.DisplayName 		[Microsoft.Office.RecordsManagement.RecordsRepository.Records]::DeclareItemAsRecord($Item) 	} } } catch{ $ErrorMessage = $_.Exception.Message Add-Content -Path $LogFilePath -Value $ErrorMessage Write-Host $ErrorMessage $ErrorActionPreference="SilentlyContinue"  } } $list.RootFolder.Properties["ecm_AutoDeclareRecords"]="True" $list.RootFolder.update() } catch{ $ErrorMessage = $_.Exception.Message Add-Content -Path $LogFilePath -Value $ErrorMessage Write-Host $ErrorMessage $ErrorActionPreference="SilentlyContinue"  } } Read-Host "Process Completed" 

How to Update the Custom Data Source Information of a RDL RDLX files in SharePoint using PowerShell Script

$
0
0


In the earlier article, we saw how to read the Data Source. In this article, let us see how to update the Custom Data Source using PowerShell Script.

The below script is self-explanatory.

 # This script will update the data source info for all the reports in a document library   ##================================================================================================ ## Description	:      #This script will update the data source info for all the reports in a document library    ## Author		: Sathish Nadarajan ## Date			:  ##================================================================================================  # ============================================ Setup Input Paths =================================   cls    $Host.UI.RawUI.WindowTitle = "-- Update Data Source for Reports Library --"  $StartDate = Get-Date Write-Host -ForegroundColor White "------------------------------------" Write-Host -ForegroundColor White "| Update the reports file with datasource url |" Write-Host -ForegroundColor White "| Started on: $StartDate |" Write-Host -ForegroundColor White "------------------------------------"  $LogTime = Get-Date -Format yyyy-MM-dd_hh-mm  ################# Set the Current Path as Execution Path ####################  $scriptBase = split-path $SCRIPT:MyInvocation.MyCommand.Path -parent Set-Location $scriptBase  ############# set the Error Preference ################  $ErrorActionPreference = "SilentlyContinue"   # Create Log File Folder if(!(TEST-PATH ".\Logs-$LogTime"))  {    NEW-ITEM ".\Logs-$LogTime" -type Directory }     # Assign the Log and Progress Files $TranscriptFile = ".\Logs-$LogTime\Transcript.rtf" $ProgressFile = ".\Logs-$LogTime\Progress.rtf"  try{   stop-transcript|out-null } catch [System.InvalidOperationException]{}  start-transcript $TranscriptFile   function AddCSOM(){      #Load SharePoint client dlls       $a = [System.Reflection.Assembly]::LoadFile(    "$scriptBase\ClientLibraries\Microsoft.SharePoint.Client.dll")       $ar = [System.Reflection.Assembly]::LoadFile(    "$scriptBase\ClientLibraries\Microsoft.SharePoint.Client.Runtime.dll")             if( !$a ){          $a = [System.Reflection.Assembly]::LoadWithPartialName(        "Microsoft.SharePoint.Client")      }      if( !$ar ){          $ar = [System.Reflection.Assembly]::LoadWithPartialName(        "Microsoft.SharePoint.Client.Runtime")      }            if( !$a -or !$ar ){          throw         "Could not load Microsoft.SharePoint.Client.dll or Microsoft.SharePoint.Client.Runtime.dll"      }                  #Add overload to the client context.      #Define new load method without type argument      $csharp =     "       using Microsoft.SharePoint.Client;       namespace SharepointClient       {           public class PSClientContext: ClientContext           {               public PSClientContext(string siteUrl)                   : base(siteUrl)               {               }               // need a plain Load method here, the base method is a generic method               // which isn't supported in PowerShell.               public void Load(ClientObject objectToLoad)               {                   base.Load(objectToLoad);               }           }       }"            $assemblies = @( $a.FullName, $ar.FullName,     "System.Core")      #Add dynamic type to the PowerShell runspace      Add-Type -TypeDefinition $csharp -ReferencedAssemblies $assemblies }   AddCSOM  $credentials = Get-Credential     cls            Write-Host "Processing the Site : " "https://mysitecollection" -ForeGroundColor Yellow              $context = New-Object SharepointClient.PSClientContext("https://mysitecollection")               $context.Credentials = $credentials          #Load the basic information about the web and site     $context.Load($context.Web)     $context.Load($context.Site)     $context.Load($context.Web.Lists)     $context.ExecuteQuery()      #SSRS Proxy     $targeturl="$($context.Web.Url)/_vti_bin/ReportServer/ReportService2010.asmx";     $targetProxy = New-WebServiceProxy -Uri  $targeturl -UseDefaultCredential;      $targetNS = $targetProxy.GetType().Namespace     $targetDataType = $targetNS + '.DataSourceDefinition'          # Iterate through the Lists     foreach ($list in $context.Web.Lists)      {         #Load the information about the List         $context.Load($list)         $context.Load($list.BaseType)         $context.Load($list.Items)         $context.ExecuteQuery()                           # validate for Document Library         if ($list.BaseType -eq “DocumentLibrary”) 
         {                        $camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery             $camlQuery.ViewXml ="<View Scope='RecursiveAll' />";             $allItems=$list.GetItems($camlQuery)             $context.Load($allItems)             $context.ExecuteQuery()                         foreach($item in $allItems)             {                 if($item.FileSystemObjectType -eq "File")                 {                     $file = $item.File                     $fItem = $file.ListItemAllFields                     $context.Load($file)                     $context.Load($fItem)                                                         $context.ExecuteQuery()                                                #Read .rdl files available in the library                                                if($file.Name.ToLower().Contains(".rdl") -or $file.Name.ToLower().Contains("rdlx"))                                                {                                            $fullURL = 'https://MySiteCollection.nee.com' + $file.ServerRelativeUrl                         $dataSources = $targetProxy.GetItemDataSources($fullURL)                         Write-Host "Count : "  $dataSources.Count                          foreach($dataSource in $dataSources)                         {                             Write-Host $dataSource.Name                             Write-Host $dataSource.Item.ConnectString                               #The below line is where actual updation is happening                                         $dataSource.item.ConnectString = "Updated Connection String Value"                                         $targetProxy.SetItemDataSources($fullURL, $dataSource)                                                                                                }                                 }                                         }                }             }                 }                try{   stop-transcript|out-null } catch [System.InvalidOperationException]{}    

Happy Coding,

Sathish Nadarajan.

How to Update the Shared Data Source Information of a RDL RDLX files in SharePoint using PowerShell Script

$
0
0

In the earlier article, we saw how to read the Data Source and Update the Custom Data Sources. In this article, let us see how to update the Shared Data Source using PowerShell Script.

The below script is self-explanatory.

# This script will update the Shared data source info for all the reports in a document library

 # This script will update the Shared data source info for all the reports in a document library   ##================================================================================================ ## Description	:      #This script will update the Shared data source info for all the reports in a document library    ## Author		: Sathish Nadarajan ## Date			:   ##================================================================================================  # ============================================ Setup Input Paths =================================   cls    $Host.UI.RawUI.WindowTitle = "-- Update Data Source for Reports Library --"  $StartDate = Get-Date Write-Host -ForegroundColor White "------------------------------------" Write-Host -ForegroundColor White "| Update the reports file with datasource url |" Write-Host -ForegroundColor White "| Started on: $StartDate |" Write-Host -ForegroundColor White "------------------------------------"  $LogTime = Get-Date -Format yyyy-MM-dd_hh-mm  ################# Set the Current Path as Execution Path ####################  $scriptBase = split-path $SCRIPT:MyInvocation.MyCommand.Path -parent Set-Location $scriptBase  ############# set the Error Preference ################  $ErrorActionPreference = "SilentlyContinue"   # Create Log File Folder if(!(TEST-PATH ".\Logs-$LogTime"))  {    NEW-ITEM ".\Logs-$LogTime" -type Directory }     # Assign the Log and Progress Files $TranscriptFile = ".\Logs-$LogTime\GetSiteInfo.Transcript.rtf" $ProgressFile = ".\Logs-$LogTime\GetSiteInfo.Progress.rtf"  try{   stop-transcript|out-null } catch [System.InvalidOperationException]{}  start-transcript $TranscriptFile   function AddCSOM(){      #Load SharePoint client dlls       $a = [System.Reflection.Assembly]::LoadFile(    "$scriptBase\ClientLibraries\Microsoft.SharePoint.Client.dll")       $ar = [System.Reflection.Assembly]::LoadFile(    "$scriptBase\ClientLibraries\Microsoft.SharePoint.Client.Runtime.dll")             if( !$a ){          $a = [System.Reflection.Assembly]::LoadWithPartialName(        "Microsoft.SharePoint.Client")      }      if( !$ar ){          $ar = [System.Reflection.Assembly]::LoadWithPartialName(        "Microsoft.SharePoint.Client.Runtime")      }            if( !$a -or !$ar ){          throw         "Could not load Microsoft.SharePoint.Client.dll or Microsoft.SharePoint.Client.Runtime.dll"      }                  #Add overload to the client context.      #Define new load method without type argument      $csharp =     "       using Microsoft.SharePoint.Client;       namespace SharepointClient       {           public class PSClientContext: ClientContext           {               public PSClientContext(string siteUrl)                   : base(siteUrl)               {               }               // need a plain Load method here, the base method is a generic method               // which isn't supported in PowerShell.               public void Load(ClientObject objectToLoad)               {                   base.Load(objectToLoad);               }           }       }"            $assemblies = @( $a.FullName, $ar.FullName,     "System.Core")      #Add dynamic type to the PowerShell runspace      Add-Type -TypeDefinition $csharp -ReferencedAssemblies $assemblies }   AddCSOM  $credentials = Get-Credential      cls             Write-Host "Processing the Site : " "https://mysitecollection" -ForeGroundColor Yellow              $context = New-Object SharepointClient.PSClientContext("https://mysitecollection")               $context.Credentials = $credentials          #Load the basic information about the web and site     $context.Load($context.Web)     $context.Load($context.Site)     $context.Load($context.Web.Lists)     $context.ExecuteQuery()      #SSRS     $SSRSurl = "$($context.Web.Url)/_vti_bin/ReportServer/ReportService2010.asmx";      $SSRS = New-WebServiceProxy -uri $SSRSurl -UseDefaultCredential;       $($ssrs.url);       # Iterate through the Lists     foreach ($list in $context.Web.Lists)      {         #Load the information about the List         $context.Load($list)         $context.Load($list.BaseType)         $context.Load($list.Items)         $context.ExecuteQuery()                           # validate for Document Library         if ($list.BaseType -eq “DocumentLibrary”) 
         {                        $camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery             $camlQuery.ViewXml ="<View Scope='RecursiveAll' />";             $allItems=$list.GetItems($camlQuery)             $context.Load($allItems)             $context.ExecuteQuery()                         foreach($item in $allItems)             {                 if($item.FileSystemObjectType -eq "File")                 {                     $file = $item.File                     $fItem = $file.ListItemAllFields                     $context.Load($file)                     $context.Load($fItem)                                                         $context.ExecuteQuery()                                                #Read .rdl files available in the library                                                if($file.Name.ToLower().Contains(".rdl") -or $file.Name.ToLower().Contains("rdlx"))                                                {                                            $fullURL = 'https://mysitecollection' + $file.ServerRelativeUrl                         $dataSources = $SSRS.GetItemDataSources($fullURL);                          Write-Host "Count : "  $dataSources.Count                          if ($datasources.count -gt 0)                         {                              for ($i = 0; $i -lt $dataSources.count; $i++)                              {                                                                        #The below Lines will update the Shared Data  Source                                   $proxyNamespace = $DataSources[$i].GetType().Namespace;                                    $DataSources[$i].Item = New-Object ("$proxyNamespace.DataSourceReference");                                    $DataSources[$i].Item.Reference = "https://mysitecollection/documentlibrary/RSDSFile.rsds";                                   $SSRS.SetItemDataSources($fullURL, $DataSources[$i])                                    write-output "Done";                                                                                         }                               }                              }                            }      }     }           }                 try{   stop-transcript|out-null } catch [System.InvalidOperationException]{}    

Happy Coding,

Sathish Nadarajan.

How to Disable/Enable User Alerts in SharePoint Office 365 using CSOM PowerShell

$
0
0

Any list will be having a “alert me” functionality and the user they themselves can create alerts like, whenever a new document is created/updated an email/sms will be triggered for those users.


image


During the Migration, if these alerts were enabled, then while doing a bulk upload, the end users will be getting a huge number of mails. Hence, we need to disable the alerts, not deleting the alerts. For that, there is no direct option on the screen, but Powershell does that.

 cls  Import-Module   'C:\SATHISH\PRACTICE SOURCE CODES\Office365.Console\packages\Microsoft.SharePointOnline.CSOM.16.1.6420.1200\lib\net45\Microsoft.SharePoint.Client.dll' Import-Module   'C:\SATHISH\PRACTICE SOURCE CODES\Office365.Console\packages\Microsoft.SharePointOnline.CSOM.16.1.6420.1200\lib\net45\Microsoft.SharePoint.Client.Runtime.dll'   #Mysite URL $site = 'https://**********.sharepoint.com/sites/TeamSite/'  #Admin User Principal Name $admin = 'sathish@********.OnMicrosoft.Com'  #Get Password as secure String $password = Read-Host 'Enter Password' -AsSecureString  #Get the Client Context and Bind the Site Collection $context = New-Object Microsoft.SharePoint.Client.ClientContext($site)  #Authenticate $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($admin , $password) $context.Credentials = $credentials   $context.Load($context.Web) $context.Load($context.Web.Alerts)  $context.ExecuteQuery()  foreach($alert in $context.Web.Alerts) {     if($alert.Status -eq 'On')     { #The below will enable the Alert # $alert.Status = 'On'   #The below will disable the Alert         $alert.Status = 'Off'         $alert.UpdateAlert()         $context.Load($alert)         $context.ExecuteQuery()     }     Write-Host $alert.Title + "-" + $alert.Status }  Write-Host $context.Web.Alerts.Count  

Happy Coding,

Sathish Nadarajan.

PowerShell tip to Identify lists with InfoPath Forms associated in SharePoint 2016 by using the Property “_ipfs_infopathenabled”

$
0
0


To identify whether a list is associated with InfoPath Form or not, we have a Property called _ipfs_infopathenabled, which will have a value of True. If the list is not attached, the property itself will not be available.

And specifically, the infopath can be associated to any of the content type. Hence, we need to iterate through the content types in the list and identify whether any of the content type is having the property or not.

 function AddPowerShellSnapin() {     try     {         Add-PSSnapin "Microsoft.SharePoint.PowerShell"         Write-Host "Adding PowerShell Snap-in" -ForegroundColor Yellow         # Try to get the PowerShell Snappin.  If not, then adding the PowerShell snappin on the Catch Block         Get-PSSnapin "Microsoft.SharePoint.PowerShell"      }     catch     {         if($Error[0].Exception.Message.Contains("No Windows PowerShell snap-ins matching the pattern 'Microsoft.SharePoint.PowerShell' were found"))         {             Add-PSSnapin "Microsoft.SharePoint.PowerShell"         }     }          Write-Host "Finished Adding PowerShell Snap-in" -ForegroundColor Green      }  function IsInfoPathUsed($List) {     $InfoPath_Used = "False"                 foreach($contentType in $list.ContentTypes) 	{ 		$InfoPath_Used = $contentType.ResourceFolder.Properties[“_ipfs_infopathenabled”]
 		if($InfoPath_Used -eq "True") 		{ 			break; 		} 	}	          return $InfoPath_Used }  AddPowerShellSnapin  $Web =  Get-SPWeb "http://sathishserver:555/sites/developersite"                   # Get the Lists             $Lists = $Web.Lists                  # Iterate through the Lists         foreach($List in $Lists)         {             write-Host "Get Lists With InfoPath in -" + $List.Title                               $IsInfoPathUsed = IsInfoPathUsed($List)                 if($IsInfoPathUsed -eq "True")                 {                     $output = $_.SiteCollectionURL + "," + $Web.Url + "," + $List.Title + "," + $List.DefaultViewUrl                      Add-Content $ListsWithInfoPath_CSV_Path $output                 }           }  

Happy Coding,

Sathish Nadarajan.

How to Get the Size of the Document Without Version in SharePoint using PowerShell Script – Client-Side Object Model

$
0
0

In the earlier article, we saw, how to get the size using SSOM. But in recent times, customers are interested in CSOM rather than SSOM.

The specific reason behind this could be, if the Content DB is not properly planned/configured, the executing a SSOM Power shell Script can cause a Content DB lock. Hence, if there is a huge Content DB, then always prefer the CSOM rather than SSOM, though the SSOM is having much more performance advantages.

The same piece of SSOM code runs much faster than CSOM code. But CSOM will not lock the DBs.

Hence, the same functionality, the below code is the equivalent CSOM script. But in CSOM, we cannot find the size of each version. At least as of now I guess.

The below code will get the Size of the Documents within a document library. The size is the final version size.

 cls  Import-Module   'C:\SATHISH\PRACTICE SOURCE CODES\Office365.Console\packages\Microsoft.SharePointOnline.CSOM.16.1.6420.1200\lib\net45\Microsoft.SharePoint.Client.dll' Import-Module   'C:\SATHISH\PRACTICE SOURCE CODES\Office365.Console\packages\Microsoft.SharePointOnline.CSOM.16.1.6420.1200\lib\net45\Microsoft.SharePoint.Client.Runtime.dll'  #Mysite URL $site = 'https://sppalsmvp.sharepoint.com/sites/DeveloperSite/'  #Admin User Principal Name $admin = 'sathish@sppalsmvp.OnMicrosoft.Com'  #Get Password as secure String $password = Read-Host 'Enter Password' -AsSecureString  #Get the Client Context and Bind the Site Collection $context = New-Object Microsoft.SharePoint.Client.ClientContext($site)  #Authenticate $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($admin , $password) $context.Credentials = $credentials  $list = $context.Web.Lists.GetByTitle('D1') $context.Load($list) $context.ExecuteQuery()  if ($list.BaseType -eq “DocumentLibrary”) 
         {             $docSize=0             $camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery             $camlQuery.ViewXml ="<View Scope='RecursiveAll' />";             $allItems=$list.GetItems($camlQuery)             $context.Load($allItems)             $context.ExecuteQuery()                          foreach($item in $allItems)             {                 if($item.FileSystemObjectType -eq "File")                 {                     $file = $item.File                     $fItem = $file.ListItemAllFields                     $context.Load($file)                     $context.Load($fItem)                                                         $context.ExecuteQuery()                         $docSize=$fItem["File_x0020_Size"]/1048576                                                                #Write-Host "Filename" $fItem["FileLeafRef"].Split('.')[0]                                       Write-Host $list.Title + ',' + $file.ServerRelativeUrl  + ',' + $fItem["FileLeafRef"].Split('.')[0] + ',' + $docSize                                                                                }             }         } 
Happy Coding,

Sathish Nadarajan.


SharePoint Office 365 - How to Get the Lists with Unique Permission – CSOM PowerShell

$
0
0

In this earlier article, We saw how to get the lists having unique permission using C#. In the same manner, let us see, how to get the unique permission lists using PowerShell.

The script is straight forward and does not require much explanation.

 

 cls  #Import the required client dlls Import-Module   'C:\SATHISH\PRACTICE SOURCE CODES\Office365.Console\packages\Microsoft.SharePointOnline.CSOM.16.1.6420.1200\lib\net45\Microsoft.SharePoint.Client.dll' Import-Module   'C:\SATHISH\PRACTICE SOURCE CODES\Office365.Console\packages\Microsoft.SharePointOnline.CSOM.16.1.6420.1200\lib\net45\Microsoft.SharePoint.Client.Runtime.dll'  #Generic method to load the properties Function Invoke-LoadMethod() { param(    [Microsoft.SharePoint.Client.ClientObject]$Object = $(throw "Please provide a Client Object"),    [string]$PropertyName )     $ctx = $Object.Context    $load = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load")     $type = $Object.GetType()    $clientLoad = $load.MakeGenericMethod($type)       $Parameter = [System.Linq.Expressions.Expression]::Parameter(($type), $type.Name)    $Expression = [System.Linq.Expressions.Expression]::Lambda(             [System.Linq.Expressions.Expression]::Convert(                 [System.Linq.Expressions.Expression]::PropertyOrField($Parameter,$PropertyName),                 [System.Object]             ),             $($Parameter)    )    $ExpressionArray = [System.Array]::CreateInstance($Expression.GetType(), 1)    $ExpressionArray.SetValue($Expression, 0)    $clientLoad.Invoke($ctx,@($Object,$ExpressionArray)) }   #Mysite URL $site = 'https://sppalsmvp.sharepoint.com/sites/DeveloperSite/'  #Admin User Principal Name $admin = 'sathish@sppalsmvp.OnMicrosoft.Com'  #Get Password as secure String $password = Read-Host 'Enter Password' -AsSecureString  #Get the Client Context and Bind the Site Collection $context = New-Object Microsoft.SharePoint.Client.ClientContext($site)  #Authenticate $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($admin , $password) $context.Credentials = $credentials  $list = $context.Web.Lists.GetByTitle('D1') $context.Load($list)    Invoke-LoadMethod -Object $list -PropertyName "HasUniqueRoleAssignments"  $context.ExecuteQuery()  Write-Host $list.HasUniqueRoleAssignments  

Happy Coding,

Sathish Nadarajan.

How to Get the Tenant ID of Office 365

$
0
0

In this article, let us see how to get the Tenant ID of our Office 365 Tenant.

Option 1 – Through the Screen

1. Get from the Azure Active Directory Properties.

2. Go to the Admin Portal and Click on the Azure Active directory - https://portal.office.com/adminportal/home#/homepage

clip_image002

3. On the Azure Active Directory page, the properties will be displayed as below. The Value on the Directory ID is the Tenant ID. Make a note of this and we can use wherever we want.

clip_image004

Option 2 – By PowerShell Script

 #Install the Microsoft Online Module  Install-Module MSOnline  #Get the Credentials and connect with the Tenant  $UserCredential = Get-Credential  Connect-MsolService -Credential $UserCredential  #Get the Tenant ID  Get-MSOLCompanyInformation | select objectID  

When we try to install the MSOnline module for the first time, it will prompt the below screen and give Yes in it.

clip_image006

Happy Coding,

Sathish Nadarajan.

Powershell script & Node module to Minify the JS files within directories & its sub-directories

$
0
0

Recently faced a requirement to search all the JS files from a visual studio solution, minify each & overwrite at the same location.

After some research I found a node component named as Uglify-JS to a achieve the functionality.

So, first I downloaded the Uglify-JS node component & which is placed to my local path: C:\Program Files\nodejs\node_modules\grunt-contrib-uglify\node_modules\uglify-js\bin\uglifyjs

Then, prepared a powershell script below to iterate each directory & its sub-directories specified in the input array, do the minification for each & overwrite to the same file.

 $arrayInput = ("C:\Projects\MinificationDemo\MinificationDemo\Scripts\", "C:\Users\Tarun\Desktop\test1", "C:\Users\Tarun\Desktop\test2")  foreach ($input in $arrayInput) {                 $folders =  Get-ChildItem -path $input -Recurse -include *.js                 Foreach ($fldr in $folders)                 {                                 if($fldr.Attributes -ne 'Directory')                                 {                                                 node " C:\Program Files\nodejs\node_modules\grunt-contrib-uglify\node_modules\uglify-js\bin\uglifyjs " --output $fldr.FullName  $fldr.FullName                                                 Write-Host $fldr.FullName "has been minified."                                 }                 } } 

Hope it will give the basic idea about how simply we can minify the JS files.

Happy Coding

Tarun Kumar Chatterjee

How to get the inventory of the existing SharePoint workflow using PowerShell

$
0
0

While planning for the Migration, we need to know the number of workflows associated with the Lists for planning the remediation and validation. This inventory is not available on any of the existing migration tools handy. For that, before even starting the migration, we need to know the counts and the lists associated for a better planning. The below script will give a clear output of the lists and the associated workflows.

 [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")  try {  #Create a variable based on the current date and time  $StartTime = (Get-Date -UFormat "%Y-%m-%d_%I-%M-%S %p").tostring()  $0 = $MyInvocation.MyCommand.Definition  $dp0 = [System.IO.Path]::GetDirectoryName($0)   $CSVoutput = $("$dp0\Result\WorkflowsInformation_" +$StartTime +".csv")  $logFile=$("$dp0\Logs\WorkflowInformationLog.txt")  Write "Script started running at " $StartTime >> $logFile  ##Creating and Returning a DataTable##   function createDT()   {   ###Creating a new DataTable###   $tempTable = New-Object System.Data.DataTable   ##Creating Columns for DataTable##   $col1 = New-Object System.Data.DataColumn("URL")   $col2 = New-Object System.Data.DataColumn("List Name")   $col3 = New-Object System.Data.DataColumn("Workflow Instances")   $col4 = New-Object System.Data.DataColumn("Workflow")  $col5 = New-Object System.Data.DataColumn("Workflow Created")  $col6 = New-Object System.Data.DataColumn("Site Colln URL")  $col7 = New-Object System.Data.DataColumn("Sub-Site URL")  ###Adding Columns for DataTable###   $tempTable.columns.Add($col1)   $tempTable.columns.Add($col2)   $tempTable.columns.Add($col3)   $tempTable.columns.Add($col4)  $tempTable.columns.Add($col5)  $tempTable.columns.Add($col6)  $tempTable.columns.Add($col7)  return ,$tempTable   }  [System.Data.DataTable]$dTable = createDT  #Initialize Workflow Count variable  $workflowcount = 0  $farm = [Microsoft.SharePoint.Administration.SPFarm]::Local  $websvcs = $farm.Services | where -FilterScript {$_.GetType() -eq [Microsoft.SharePoint.Administration.SPWebService]}  foreach ($websvc in $websvcs)   {  try  {  foreach ($webApplication in $websvc.WebApplications)   {  #Skip Admin Web Applicaiton  if($webApplication.DisplayName -match "SharePoint Central Administration")  {  continue;  }  try  {  Write "`r`n Inside the loop for web application" $webApplication.Url >> $logFile  foreach($site in $webApplication.Sites)  {  try  {  Write "`r`n Inside the loop for site" $site.Url >> $logFile  foreach($web in $site.AllWebs)  {  Write "`r`n Inside the loop for web" $web.Url >> $logFile  foreach($list in $web.Lists)  {  Write "`r`n Inside the loop for the list" $list.Title >> $logFile  foreach($wf in $list.WorkflowAssociations)  {  Write "`r`n Inside the loop for the workflow" $wf.Name >> $logFile  $workflowcount += 1  $row = $dTable.NewRow()   $row["URL"] = $web.Url   $row["List Name"] = $list.Title   $row["Workflow Instances"] = $wf.RunningInstances   $row["Workflow"] = $wf.Name  $row["Workflow Created"] = $wf.Created  $row["Site Colln URL"] = $site.Url  $row["Sub-Site URL"] = $web.Url  $dTable.rows.Add($row)  }  }  $web.Dispose()  }  }  catch [Exception]{  Write $_.Exception|format-list -force >>$logFile  Write-Host -f red $_.Exception|format-list -force  }  finally{  if($web){  $web.Dispose()  }  }  $site.Dispose()  }  }  catch [Exception]{  Write $_.Exception|format-list -force >>$logFile  Write-Host -f red $_.Exception|format-list -force  }  finally{  if($site){  $site.Dispose();  }  }  }  }  catch [Exception]{  Write $_.Exception|format-list -force >>$logFile  Write-Host -f red $_.Exception|format-list -force  }  }  if($dTable -ne $null)   {  $dTable | Export-CSV -path $CSVoutput -notype  #Write-Host "Done" -ForegroundColor Green  }   else   {   Write-Host "There are no workflows in SharePoint Farm" -ForegroundColor red  }  }  catch [Exception]{  Write $_.Exception|format-list -force >>$logFile  Write-Host -f red $_.Exception|format-list -force  }  $EndTime = (Get-Date -UFormat "%Y-%m-%d_%I-%M-%S %p").tostring()  Write "Script stopped at" $EndTime >> $logFile 

The output of the script will be as below.

clip_image002

Hope the handy script helps to get the inventory and save few hours of effort.

Happy Coding,

Hariramakrishnan Vasuthevan

PowerShell script to change Password for App pool and manage account in SharePoint Onprem server

$
0
0


In development machine if we install the SharePoint on premise(2010 or 2013 SharePoint server) with User or our Id , due to policy if we change our password for installation ID, then We will  face issue on access SharePoint site due to password , the work around solution for this is once the installation id password, changed then   the app pool and Manage account password also need to be changed, instead changing manually by going to IIS and SharePoint Central administration we can execute the below script on SharePoint server to change the password

App Pool Password change

 Add-PSSnapin "Microsoft.SharePoint.PowerShell"  Import-Module WebAdministration $applicationPools = Get-ChildItem IIS:\AppPools | where { $_.processModel.userName -eq "domain\username" }   foreach($pool in $applicationPools) {     $pool.processModel.userName = "domain\username"     $pool.processModel.password = "password"     $pool.processModel.identityType = 3     $pool | Set-Item }   Write-Host "Application pool passwords updated..." -ForegroundColor Magenta  Write-Host ""  Read-Host -Prompt "Press Enter to exit" 

Managed Account Password change

 $m = Get-SPManagedAccount -Identity “domain\username”
   Set-SPManagedAccount -Identity $m  -ExistingPassword (ConvertTo-SecureString "Password" -AsPlainText -force) –confirm
 


Hope the handy script helps you to change managed and app pool account password and save few hours of effort.


Happy Coding,

Hariramakrishnan Vasuthevan

Viewing all 31 articles
Browse latest View live