Initialize-SPOCSOMObjectProperty.ps1
############################## #.SYNOPSIS #Initiaizes a specific properties on a CSOM object that was not originally returned. # #.DESCRIPTION #Initialized specific properties on CSOM objects by creating lambda expressions to load into the context. # #.PARAMETER Objects #The objects that contain the properties we want initialized or returned. # #.PARAMETER PropertyName #The name of the properties we want returned. # #.PARAMETER Context #The context these objects are from. This is used for bulk processing the commands. # #.PARAMETER BulkProcess #This specified whether to attempt to return the properties in bulk. CSOM object become overloaded with more than 15 requests at a time. This can #significantly reduce the execution time. However, it is unpredictable as wo what will cause a request overload. So this feature can be skipped using #this switch. # #.EXAMPLE #Initialize-SPOCSOMObjectProperty -Objects $Context.Web.Webs[0] -PropertyName "HasUniqueRoleAssignments" -BulkProcess -Context $Context # #Initialize-SPOCSOMObjectProperty -Objects $Context.Web.Webs -PropertyName @("HasUniqueRoleAssignments","MembersCanShare") # #.NOTES #It would be nice to get the bulk process to work better. Some sort of load query management system or check. ############################## Function Initialize-SPOCSOMObjectProperty() { [CmdletBinding()] param( #Provide the object(s) to be iterated trough [Parameter(Mandatory=$true,ValueFromPipeline,ParameterSetName="Object")] [Microsoft.SharePoint.Client.ClientObject[]] $Objects, #Supply the property names to generate the lambda expressions for CSoM [Parameter(Mandatory=$true,ParameterSetName="Object")] [String[]] $PropertyName, # Providing a context will allow for bulk processing [Parameter(Mandatory=$false,ParameterSetName="Object")] [Microsoft.SharePoint.Client.ClientContext] $Context, # Providing a context will allow for bulk processing [Parameter(Mandatory=$false,ParameterSetName="Object")] [Switch] $BulkProcess ) Begin{ #Check if all the objects have the same context. If so, speed of the process by assigning it to $context. if($objects.Count -gt 1){ if((-not ($Objects | Where-Object {$_.Context -ne $Objects[0].Context})) -And (-Not $Context)){ Write-Verbose -Message "No Context Supplied, but all objects are in the same context. Assigning to Context Variable." $context = $objects[0].Context } } } Process{ #Iterate through each object supplied Write-Verbose -Message "Creating Lambda Expression for each property and object supplied." Foreach($Object in $Objects){ Write-Progress -Activity "Initializing CSOM Collections" -PercentComplete (($Objects.IndexOf($Object) / $Objects.Length) * 100) $Expressions = @() #$load = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load") $type = $Object.GetType() Foreach($pn in $PropertyName){ #Creates a ParamaterExpression node that can be used to identify a parameter or variable in an expression tree. Object Type and Object type name. $Parameter = [System.Linq.Expressions.Expression]::Parameter(($type), $type.Name) #Creates a member expression that represents accessing a property or field. $PropertyExpression = [System.Linq.Expressions.Expression]::PropertyOrField($Parameter,$pn) #Creates a unary expression that represents a type conversion $UnaryExpression = [System.Linq.Expressions.Expression]::Convert($PropertyExpression,[System.Object]) #Creates a lambda expression by first constructing a delegate type. $Expression = [System.Linq.Expressions.Expression]::Lambda($UnaryExpression,$($Parameter)) $Expressions += @($Expression) } #Load the object and lambda expressions to the Context. $Object.Context.Load($Object,$Expressions) #If no $context is set, execute the query against the Objects Context. if(-not $Context -or -not $BulkProcess){ Write-Verbose -Message "Executing Single CSOM Query" $Object.Context.Load($Object,$Expressions) $object.Context.ExecuteQuery() } #If a conext was provided/derived, bulk process the requests. Process the requests 14 a time to prevent the request from using too many resources elseif(($objects.IndexOf($Object) % 12) -eq 0){ Write-Verbose -Message "Reached resource limit for CSOM. Executing Query." $context.Load($object,$Expressions) $Context.ExecuteQuery() } } } End{ If($Context){ Write-Verbose -Message "Final Execute Query." $Context.ExecuteQuery() } } } |