Enable-CSUser Insufficient Permission

Enabling users from both the Lync control panel and PowerShell was producing this error:

“Active Directory operation failed on “abc.domain.com”. You cannot retry this operation: “Insufficient access rights to perform the operation
00002098: SecErr: DSID-03150E8A, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0
“.You do not have the appropriate permissions to perform this operation in Active Directory. One possible cause is that the Lync Server Control Panel and Remote Windows PowerShell cannot modify users who belong to protected security groups (for example, the Domain Admins group). To manage users in the Domain Admins group, use the Lync Server Management Shell and log on using a Domain Admins account. There are other possible causes. For details, see Lync Server 2010 Help.”

Most solutions to this topic mention ensuring that Inheritable Permissions are set on the user’s security tab in AD, but in our case these were already set.

A user with Domain Admin privileges could enable the users but not our Lync Admin account that had both CSAdministrator and RTCUniversalUserAdmins membership.

After much head scratching, it turned out that the Lync server had been removed from the membership in the RTCUniversalUserAdmins group. Adding the computer back to that group was the solution.

Sharing internet connection with Hyper-V client

Had to do this a little differently than all of the blog posts I’d seen because using an Internal virtual switch and trying to allow it to share my local network resulted in an IP address conflict.

The fix was to create an External virtual switch with “Allow management operating system to share this network adapter” checked. Creating this takes a minute and Internet connectivity is dropped for a second while it applies changes.

Then, in the VM settings, select this new switch as the network adapter.

The VM might need to be turned off when making this setting change, but it worked for me while the VM was running.

FIM Workflow Updating Items with Enumerate Resources Activity

There is a great write up on how to use the enumerate Resources Activity to update items in FIM here: http://www.fimspecialist.com/fim-portal/custom-workflow-examples/custom-workflow-example-enumerate-resources-activity/

I only had to do one thing differently to get it working in my environment. In the designer.cs file, I commented out the line:

this.Activities.Add(this.sequenceActivity1);

and instead add the activity on the enumerateResourcesActivity:

this.enumerateResourcesActivity1.Activities.Add(this.sequenceActivity1);

Unrelated to the post that explains updating objects with enumerateResourcesActivity, I got a rather misleading error when executing the update: “CompositeActivity cannot transition to ‘Closed’ status when there are active child context still exist for child activity.”

Apart from the confusing grammar, I assumed something was wrong with the sequence I was using to update the object. It turned out to be much simpler: I had a typo in one of the attribute names I was updating. I think this error is thrown if the update fails and the activity doesn’t get to close.

SharePoint: Allow web part to use System.DirectoryServices

A web part I developed needed to access Active Directory. A lot of posts say to just set the site’s trust level to Full, but that is a security risk.

The solution I found was to use a wss_custom trust level.

First, I copied the wss_minimal.config file in the CONFIG file of the 14-hive and named it wss_custom.config.

I then modified it as described in this post: http://www.derkeiler.com/Newsgroups/microsoft.public.dotnet.security/2004-10/0240.html

I added this to <SecurityClasses>:

< SecurityClass Name=”DirectoryServicesPermission”  Description=”System.DirectoryServices.DirectoryServicesPermission,  System.DirectoryServices, Version=1.0.5000.0, Culture=neutral,  PublicKeyToken=b03f5f7f11d50a3a”/>

Then I added the “DirectoryServicesPermission” to the “NamedPermissionSet” of “ASP.NET”:
<PermissionSet class=”NamedPermissionSet” version=”1″  Name=”ASP.Net”>
<IPermission class=”DirectoryServicesPermission” version=”1″  Unrestricted=”true”/> 
</PermissionSet>

[Note: I didn’t remove the other entries in those two sections.]

In the web.config file, I added this to the <securityPolicy> settings:

<trustLevel name=”WSS_Custom” policyFile=”C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\config\wss_custom.config” />

Next, I changed the trust level in the web.config file to WSS_Custom.

<trust level=”WSS_Custom” originUrl=”” />

[In addition to the post referenced above, this post helped me understand the steps to use a customized Code Access Security policy: http://blog.tylerholmes.com/2008/11/creating-custom-cas-policy-file-for.html]

In my web part C# code, I used PrincipalContext with a user with appropriate AD permissions:

PrincipalContext cxt = new PrincipalContext(ContextType.Domain, sDomain, sUser, sPwd);

using (UserPrincipal user = UserPrincipal.FindByIdentity(cxt, sAccountName))

{

DirectoryEntry entry = user.GetUnderlyingObject() as DirectoryEntry;

DirectorySearcher searcher = new DirectorySearcher(entry);

searcher.PropertiesToLoad.Add(“proxyAddresses”);

searcher.Filter = “(&(objectClass=user)(|(sAMAccountName=” + sAccountName + “)))”;

SearchResult result = searcher.FindOne();

if (result == null)

{

litResult.Text += “Error: User not found.”;

}

else

{

//do something

}

}

entry.Close();

entry.Dispose();

searcher.Dispose();

cxt.Dispose();

Sending Email via PowerShell and EWS

Just a sample script. I forgot that the message body needed to be converted to a string format and, as this script was being called by a back end process, it took me a while to figure out what the error was.

Code:

 

Add-Type -Path ‘F:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll’

#Create the EWS service object
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2010_SP1

#Set the credentials for Exchange Online
#$service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList `
#$Credential.UserName, $Credential.GetNetworkCredential().Password
$service.UseDefaultCredentials = $true
$service.AutoDiscoverUrl(“sender@domain.com”)

#Determine the EWS endpoint using autodiscover
#$service.AutodiscoverUrl($Credential.UserName, {$true})

#Get the email body
$body = Get-Content “C:\Files\EmailTemplate.htm”
$body = $body -replace “Placeholder”, $Placeholder

#Have to convert the object to a string to use in the mail body.
[string]$msgBody = $body

#Create the email message and set the Subject and Body
$message = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $service
$message.Body.BodyType = ‘HTML’
$message.From = “sender@domain.com”
$message.Subject = “A message for you”
$message.Body = $msgBody

$message.ToRecipients.Add($CreatorEmail)

#Send the message and save a copy in the users Sent Items folder (Alt is message.Send which will not save a copy.)
$message.SendAndSaveCopy()