ToRecipients Will Not UpdateEWS Managed API 2.2 - powershell

According to MSDN
I am trying to update ToRecipients property is writable.
When I run the following code in Powershell:
foreach ( $Item in $SearchResults ) {
Write-Output $item.Subject
$Item.Load()
$Item.Sender.Name = 'TS'
$item.IsRead = $false
$item.Subject = 'Test'
$item.ToRecipients.Name = 'DisplayName Three'
$Item.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)
}
It would Save subject, however neither Sender or ToRecipients get updated.
Could someone please advise what I am doing wrong?
Thank you

According to MSDN I am trying to update ToRecipients property is writable
No that property is ReadOnly according to the documentation eg
That property is just a cacluated property based on the contents of the Recipients collection which I believe is also ReadOnly on a Message once its been received in EWS.

Related

ExtendedPropertyDefinition declaration for EmailMessage in Powershell throws exception

since I got to know that ExtendedProperties have its limit for a specific mailbox in the EWS cloud I am trying to switch up my code to have only one ExtendedProperty and just change its value each time I am assigning the property to an e-mail message I am sending to then find it and work on the e-mail message object later on in the program.
I am having a hard time setting this up correctly even though I am following the docs, but it just seems to not work out for me.
This is the code part that throws an Exception: "Multiple ambigious overloads found for "ExtendedPropertyDefinition" and the argument count "3" :
# email declaration exposing the $email object
.
.
.
# property declaration and setting the value
# since I want to have only one extended property, this is actually a valid GUID string that I then # convert to a Guid type
$GUIDproperty = "00000000-0000-0000-0000-000000000000"
$propertyGUID = [Guid]$GUIDproperty
# since I want to have a unique value each time set to the existing extended property
$propertyValue = [guid]::NewGuid().ToString()
$propertyName = "Id"
$ExtendedProperty = [Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition]::new($propertyGUID, $propertyName, $propertyType)
# well I dont even reach this part, but just for the big picture
$email.SetExtendedProperty($ExtendedProperty, $propertyValue)
The docs I have followed for that are the following:
https://learn.microsoft.com/en-us/dotnet/api/microsoft.exchange.webservices.data.extendedpropertydefinition.-ctor?view=exchange-ews-api#microsoft-exchange-webservices-data-extendedpropertydefinition-ctor(microsoft-exchange-webservices-data-defaultextendedpropertyset-system-string-microsoft-exchange-webservices-data-mapipropertytype)
https://learn.microsoft.com/en-us/dotnet/api/microsoft.exchange.webservices.data.folder.setextendedproperty?redirectedfrom=MSDN&view=exchange-ews-api#Microsoft_Exchange_WebServices_Data_Folder_SetExtendedProperty_Microsoft_Exchange_WebServices_Data_ExtendedPropertyDefinition_System_Object_
https://learn.microsoft.com/en-us/dotnet/api/system.guid?view=net-7.0
The following works okay for me
$propertyType = [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String
$GUIDproperty = "82e3d64f-e26d-4321-8fc3-c31aa790197c"
$propertyGUID = [Guid]$GUIDproperty
$propertyValue = [guid]::NewGuid().ToString()
$propertyName = "MyPropId"
$ExtendedProperty = [Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition]::new($propertyGUID, $propertyName, $propertyType)
return $ExtendedProperty
You don't specify what you using in the $propertyType so that maybe it, could also be to do with the versions you using. What version of PowerShell and the EWS Managed API are you trying ?

How to replace/update the Value of an Attribute in LDAP Directory using PowerShell?

The entries in our companys Non-AD LDAP Server look like this:
uid = e145871
sn = Smith
givenName = John
department = Research & Development
department = Human Resource
And so on...
I've developed a PowerShell script to add specific attributes and values which is working just fine. Now I need to replace specific values but the issue is the identical attribute name. (In this case it's "department")
My goal is to replace "Research & Development" with "Something Else". If I run the following script it gets replaced but Human Resource is deleted as well. Is it possible to replace only one value without touching/deleting the other?
$r = New-Object -TypeName System.DirectoryServices.Protocols.ModifyRequest
$r.DistinguishedName = "uid=e145871,ou=identities,ou=users,o=items,dc=company,dc=domain,dc=com"
$DirectoryRequest_value = New-Object "System.DirectoryServices.Protocols.DirectoryAttributeModification"
$DirectoryRequest_value.Name = "department"
$DirectoryRequest_value.Contains("Research & Development")
$DirectoryRequest_value.Operation = [System.DirectoryServices.Protocols.DirectoryAttributeOperation]::Replace
$DirectoryRequest_value.Add("SomethingElse")
$r.Modifications.Add($DirectoryRequest_value)
$result = $connection.SendRequest($r)
Thanks!
The LDAP Replace operation replaces (or overwrites) the entire value of the attribute, including any existing values that might exist as part of a multi-valued attribute.
From RFC4511 §4.6 - "Modify Operation":
- operation: Used to specify the type of modification being
performed. Each operation type acts on the following
modification. The values of this field have the following
semantics, respectively:
[...]
replace: replace all existing values of the modification
attribute with the new values listed, creating the attribute
if it did not already exist. A replace with no value will
delete the entire attribute if it exists, and it is ignored
if the attribute does not exist.
Instead, add two separate modifications to the request - one to add "SomethingElse" and one to remove "Research & Development":
$targetObject = 'uid=e145871,ou=identities,ou=users,o=items,dc=company,dc=domain,dc=com'
$attributeName = 'department'
$oldValue = 'Research & Development'
$newValue = 'SomethingElse'
$request = [System.DirectoryServices.Protocols.ModifyRequest]::new()
$request.DistinguishedName = $targetObject
# This modification will add the new value "SomethingElse"
$addNewDepartment = #{
Name = $attributeName
Operation = 'Add'
} -as [System.DirectoryServices.Protocols.DirectoryAttributeModification]
$addNewDepartment.Add($newValue) |Out-Null
$request.Modifications.Add($addNewDepartment) |Out-Null
# This modification will remove the old value "Research & Development"
$removeOldDepartment = #{
Name = $attributeName
Operation = 'Delete'
} -as [System.DirectoryServices.Protocols.DirectoryAttributeModification]
$removeOldDepartment.Add($oldValue) |Out-Null
$request.Modifications.Add($removeOldDepartment) |Out-Null
$result = $connection.SendRequest($request)

Add RoleAssignment Member to SPItem Using PowerShell

I will be executing a script to remove permissions from a SPitem. However, a rollback plan is required and I am required to create a separate script which will add the permission of the user back to the SPitem if required.
Below is my code snippet which removes a user from the SPitem:
ForEach ($RDfolderId in $RDfolderSplit)
{
$query = New-Object Microsoft.SharePoint.SPQuery
$query.ViewXml = "#<View Scope='RecursiveAll'><Query><Where><Eq><FieldRef Name='Title' /><Value Type='Text'>$RDfolderId</Value></Eq></Where></Query></View>"
$RDfolder = $RDlist.GetItems($query)
foreach($role in $RDfolder.RoleAssignments)
{
if ($role.Member.Name.Equals($userToAction))
{
#$RDitem.BreakRoleInheritance($true)
#$RDitem.RoleAssignments.RemoveById($roleAssignment.Member.ID)
#$RDitem.Update()
}
}
}
I have seen code samples online on adding roles back to the SPitem. However, there is an additional field RoleDefinitions declared.
Is it compulsary to have the value declared when adding a user to a SPitem?
Below is the code sample for adding:
$web = Get-SPWeb http://sp-2010
$account = $web.EnsureUser("SHAREPOINT\mray")
$role = $web.RoleDefinitions["Contribute"] #is this value compulsory?
$list = $web.Lists["Shared Documents"]
$list.BreakRoleInheritance($true)
$assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
$assignment.RoleDefinitionBindings.Add($role)
$list.RoleAssignments.Add($assignment)
$list.Update()
$web.Dispose()
source
Short answer - Yes.
Let's break this sample up and explain each part:
$web = Get-SPWeb http://sp-2010
$web - SharePoint Web object aka. Site we are working on.
$account = $web.EnsureUser("SHAREPOINT\mray")
$account - User account we are working with.
$role = $web.RoleDefinitions["Contribute"] #is this value compulsory?
$role - This is the Role Definition aka permissions like Contribute/Read/Approve. Yes. This is mandatory as it is the permissions you are going to add back.
$list = $web.Lists["Shared Documents"]
$list - The List we are working with.
$list.BreakRoleInheritance($true)
BreakRoleInheritance - This is if we need unique permissions on the List and to turn inheritance off. We don't have to do this every time, and likely in this example, you don't have to break inheritance.
Now, we are onto the permissions pieces.
$assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
$assignment - First, we need to get all the SharePoint roles currently assigned to our user.
$assignment.RoleDefinitionBindings.Add($role)
Add($role) - Add the Role Definition i.e. "Contribute" to the user object. This does nothing to the list on SharePoint.
$list.RoleAssignments.Add($assignment)
Add($assignment) - Add user with the new permissions to the List object. This does nothing to the list on SharePoint. We are manipulating the end state of the list that we want.
$list.Update()
Update - Now do something on SharePoint. Actually apply the changes we have made to the List object to SharePoint.
$web.Dispose()
Dispose - cleanup our objects.
Now. Saying all of that. This is a good script for setting permissions. You also have a script for removing permissions. The point of a rollback script is that you need to record what those permissions originally were before you remove them. i.e. once you remove them, there isn't a magic undo button. ;-)

Getting a FieldLookupValue from Sharepoint in Powershell

Looking on the net I came up with this 2 functions to request Sharepoint using this 3 DLL with powershell :
Microsoft.SharePoint.Client.dll
Microsoft.SharePoint.Client.Taxonomy.dll
Microsoft.SharePoint.Client.Runtime.dll
This function is used to get all items from a list
Function Get-ListItems([Microsoft.SharePoint.Client.ClientContext]$Context, [String]$ListTitle) {
$list = $Context.Web.Lists.GetByTitle($listTitle)
$qry = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery()
$items = $list.GetItems($qry)
$Context.Load($items)
$Context.ExecuteQuery()
return $items
}
And this one to work the list :
Function getChangeListsFromSharepoint(){
$context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$items = Get-ListItems -Context $context -ListTitle $listName
foreach($item in $items)
{
/** Working HERE **/
}
$context.Dispose()
}
Now when I'm displaying all item content using Write-Host $item.Fields I've got something like this :
[Title,"blabla"]
...
[SpecialField,Microsoft.SharePoint.Client.FieldLookupValue[]]
[OtherField,Microsoft.SharePoint.Client.FieldLookupValue]
I'm trying to get the value of SpecialField and OtherField. To do so I'm using $item["SpecialField"].LookupValue. And I've got no problem. But when I'm doing it on OtherField the value is empty. If I try to use $item["OtherField"].LookupID the value is not empty and I've got an ID. How can I get the value behind this ID ? What's the difference between FieldLookupValue[] and FieldLookupValue ?
FieldLookupValue[] is a multi-value lookup column.
It has property Allow multiple values set to true and contains an array of items.
So, $item["OtherField"].LookupValue will not work here, you need to iterate it over as below:
#multi-value lookup
$mvLookup = [Microsoft.SharePoint.Client.FieldLookupValue[]] $item["OtherField"]
$mvLookup |% { "Lookup Value: $($_.LookupId):$($_.LookupValue)" }
which results in values as below:
FieldLookupValue is a single value lookup column. It has the Allow multiple values set to false and contains a single item. So, $item["SpecialField"].LookupValue will work here
So the solution was easy : my user didn't had the rights to explore the (field)list because it was from a (sharepoint)list on wich he didn't had any rights. What is strange is that on the website the value was visible but it's not when using powershell.

powershell returning username from the security log

I have a script which returns me user name, date , logon type and message from the security log with event ids 4624 and 4634 with logon type 2.
the problem is that it returns me only a part of the username. E.g. if the username is aaaa.bbbb it returns only aaaa. if the user name is cccc it returns cccc. How can i get the entire username please?
$content = $i.message| Find-Matches -Pattern “Kontoname:\s+\w+”
if($content.Count -eq 2) {$account = $content[1]} else {$account = $content}
$account = (($account -split “:”)[1]) -replace “\s+”,”"`
I don't have any example data to work with for events 4623 and 4634, but I've found the 'Properties' property or 'ToXML' method from the resulting System.Diagnostics.Eventing.Reader.EventLogRecord to be quite helpful. Much more helpful than trying to manually parse the 'Message' content.
Try this
#Get an example event to work with
$EventExample = Get-WinEvent <#your params here#> | Select -first 1
#Using properties property
#This will list some data you can access through the properties member
#From here, just figure out which array index you need
$EventExample.Properties
#Using ToXML method
#This will list the same data as properties...
#With a Name (key) and a #text (value) that you can use to help identify the data
$EventXML = [xml]$EventExample.ToXML()
$EventXML.event.eventdata.data
Here is a lengthy writeup on pulling this event data from Ashley McGlone.
Good luck!