FIMAutomation on a computer without the FIM service

Yet again Paolo has a useful FIM post: https://espace.cern.ch/idm/Lists/Posts/Post.aspx?ID=25 (Thank you, Paolo!)

This time it’s on installing the FIMAutomation on a computer without the FIM service installed.

I had to change one minor thing in his steps, so wanted to post them here mainly as a bookmark for myself. I’ve just copied and pasted his post but changed the step to what worked for me.

From the C:\Program Files\Microsoft Forefront Identity Manager\2010\Service folder on the FIM server, copy the following files:
•Microsoft.ResourceManagement.Automation.dll
•Microsoft.IdentityManagement.Logging.dll
•Microsoft.ResourceManagement.dll
Then, from an elevated visual studio prompt [edit: I was able to do this with a regular command prompt opened via “Run as Administrator”], register the snapin and GAC-install the other assemblies:
(1) > InstallUtil.exe -i .\Microsoft.ResourceManagement.Automation.dll
(2) > gacutil -i Microsoft.ResourceManagement.dll
(3) > gacutil -i Microsoft.IdentityManagement.Logging.dll
If you are installing the FIM PowerShell snapin on a 64-bit machine, make sure that you are running the correct version of InstallUtil, which should be
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\InstallUtil.exewhile the VS prompt picks by default the one in
C:\Windows\Microsoft.NET\Framework\v2.0.50727\

SharePoint CheckSuspiciousFilePath

I recently installed SharePoint Foundation and when I tried to navigate to Central Administration, I was receiving the Resource Not Found 404 error.

By doing a View Source on the page, I saw that the error was being thrown in a method called CheckSuspiciousFilePath.

So, I went to IIS and checked the physical path in the basic settings for the administration site. Turns out, the file path had a duplicate \ in it: D:\\. By changing that to D:\, the site started working.

(Thanks to this post: http://mosshowto.blogspot.com/2008/10/ressource-cannot-be-found-error.ht… for the helpful tip on using View Source to see the error.)

FIM Troubleshooting

The “Service not available” message is one of the most frustrating things to see when working with FIM. Thomas posted a great post on how to get the stack trace instead. (http://setspn.blogspot.com/2010/06/fim-2010-enable-advanced-error-loggin…) I always forget commenting out the ILMErrors section. (Thanks, Thomas!)

Additionally, the problem I encounter sometimes is a double http://http:// in the service address in the web.config. Not sure what causes the FIM installation to do that on repair (I probably did something wrong), but it’s easy to fix once you can see the error messages.

C# Create Management Policy Rule (MPR) with FIM 2010 Resource Management Client

The developers of the Codeplex project for the FIM 2010 Resource Management Client (http://fim2010client.codeplex.com/) did a great job providing a tool that is straightforward to use and easy to learn.

One thing I could not find an example for was creating a management policy rule. It didn’t take too long to figure out, but I thought I’d post the code here.

There are functions to do the following:

– Create a Set
– Retrieve the ObjectID of the Set
– Create the MPR

I only needed one specific type of MPR, so the code isn’t ideal, but may help someone get started a little faster than I did.

==========
CREATE SET
==========
public void CreateSet(string sSetName, string sFilter)
{
using (DefaultClient client = new DefaultClient())
{

credentials = new NetworkCredential(“user”, “pwd”, “domain”);
client.ClientCredential = credentials;
client.RefreshSchema();

RmSet set = new RmSet()
{
DisplayName = sSetName,
Filter = @”” + sFilter + “”
};

RmReference newSetId = client.Create(set);

}

}

=================
GET SET OBJECT ID
=================
private RmReference GetSetObjectID(string sDisplayName)
{

RmReference sObjectID = null;
credentials = new NetworkCredential(“user”, “password”, “domain”);
using (DefaultClient client = new DefaultClient())
{

client.ClientCredential = credentials;

lblResults.Text = “/Set[DisplayName='” + sDisplayName + “‘]”;

foreach (RmSet set in client.Enumerate(“/Set[DisplayName='” + sDisplayName + “‘]”))
{
sObjectID = set.ObjectID;

}

}

return sObjectID;
}

==========
CREATE MPR
==========
public void CreateMPR(string sMPRName, string sRequestorSet, string sTargetSet)
{
using (DefaultClient client = new DefaultClient())
{

credentials = new NetworkCredential(“user”, “password”, “domain”);
client.ClientCredential = credentials;
client.RefreshSchema();

RmResource mprNew = new RmResource();

mprNew.ObjectType = “ManagementPolicyRule”;
mprNew.DisplayName = sMPRName;
//Grant Right
var keyGrantRight = new RmAttributeName(“GrantRight”);
if (!mprNew.Attributes.ContainsKey(keyGrantRight))
{
var attributeValueGrantRight = new RmAttributeValueSingle();
//Have to add the attribute to the user since the request would not have returned it.
mprNew.Attributes.Add(keyGrantRight, attributeValueGrantRight);
}
mprNew[“GrantRight”].Value = “true”;

//Action Parameter
var keyActionParameter = new RmAttributeName(“ActionParameter”);
if (!mprNew.Attributes.ContainsKey(keyActionParameter))
{
var attributeValueActionParameter = new RmAttributeValueSingle();

mprNew.Attributes.Add(keyActionParameter, attributeValueActionParameter);
}
mprNew[“ActionParameter”].Value = “*”;

//ActionType – Multivalued attribute
var keyActionType = new RmAttributeName(“ActionType”);
if (!mprNew.Attributes.ContainsKey(keyActionType))
{
var attributeValueActionType = new RmAttributeValueMulti();
mprNew.Attributes.Add(keyActionType, attributeValueActionType);
}
mprNew[“ActionType”].Values.Add(“Create”);
mprNew[“ActionType”].Values.Add(“Delete”);
mprNew[“ActionType”].Values.Add(“Modify”);
mprNew[“ActionType”].Values.Add(“Read”);
mprNew[“ActionType”].Values.Add(“Add”);
mprNew[“ActionType”].Values.Add(“Remove”);

//Principal Set
var keyPrincipalSet = new RmAttributeName(“PrincipalSet”);
if (!mprNew.Attributes.ContainsKey(keyPrincipalSet))
{
var attributeValuePrincipalSet = new RmAttributeValueSingle();

mprNew.Attributes.Add(keyPrincipalSet, attributeValuePrincipalSet);
}
mprNew[“PrincipalSet”].Value = GetSetObjectID(sRequestorSet);

//Resource Current Set
var keyResourceCurrentSet = new RmAttributeName(“ResourceCurrentSet”);
if (!mprNew.Attributes.ContainsKey(keyResourceCurrentSet))
{
var attributeValueResourceCurrentSet = new RmAttributeValueSingle();

mprNew.Attributes.Add(keyResourceCurrentSet, attributeValueResourceCurrentSet);
}
mprNew[“ResourceCurrentSet”].Value = GetSetObjectID(sTargetSet);

//Resource Final Set
var keyResourceFinalSet = new RmAttributeName(“ResourceFinalSet”);
if (!mprNew.Attributes.ContainsKey(keyResourceFinalSet))
{
var attributeValueResourceFinalSet = new RmAttributeValueSingle();

mprNew.Attributes.Add(keyResourceFinalSet, attributeValueResourceFinalSet);
}
mprNew[“ResourceFinalSet”].Value = GetSetObjectID(sTargetSet);

//Management Policy Rule Type
var keyManagementPolicyRuleType = new RmAttributeName(“ManagementPolicyRuleType”);
if (!mprNew.Attributes.ContainsKey(keyManagementPolicyRuleType))
{
var attributeValueManagementPolicyRuleType = new RmAttributeValueSingle();

mprNew.Attributes.Add(keyManagementPolicyRuleType, attributeValueManagementPolicyRuleType);
}
mprNew[“ManagementPolicyRuleType”].Value = “Request”;

RmReference newMprId = client.Create(mprNew);
}
}

FIM: failed to process the request: unknownerror and Unable to Process Your Request errors

I was getting variations on the Unable to Process Your Request error in the FIM portal whenever I tried to update or delete an object.

In addition to the generic error, I also received “failed to process the request: unknownerror” and my PowerShell commands all failed with refusing to dispatch the endpoint.

After about an hour of stumbling around, I realized the disk on the SQL Server was full.

PowerShell script for FIM and ILM to save Run Details

In order to better log errors in PowerShell, I wanted to export the results of the management agent run to an XML file.

The idea is to then leverage this XML file to parse out the objects that errored and save their state at the time of the error, as well as any updates that were trying to be performed.

With the help of two TechNet articles, I cobbled together the following. It’s just a start, but I was happy it worked!

# RunMA.ps1
# Accepts MAName and Run Profile Name with optional ILM Servername
# Returns errorlevel 0 on success, 1 on any failure
#
# Setup the argument parameters
# Declare the default ILM server as local
param([string]$MAName,[string]$RunProfileName,[string]$ILMServerName = “.”)

# Get the WMI Server object
$curMA = @(get-wmiobject -class “MIIS_ManagementAgent” -namespace “root\MicrosoftIdentityIntegrationServer” -computername $ILMServerName -filter “Name=’$MAName'”)
# Validate that the MA exists
if($curMA.count -eq 0){throw “MA not found”}

Write-Host “`nStarting $RunProfileName on $MAName”
$Status = $($curMA[0].Execute($RunProfileName).ReturnValue)
Write-Host “Result: $Status`n”

$runDetails = $curMA[0].RunDetails().ReturnValue

$doc = New-Object System.Xml.XmlDocument

$doc.LoadXml($runDetails)
$dNow = Get-Date -format “yyyy-MM-dd HH-mm”

Write-Host($dNow)
$doc.Save(“C:\FIMLogs\”+ $MAName + ” ” + $RunProfileName + ” ” + $dNow +”.xml”)

#————————————————————————————————–
trap
{
Write-Host “`nError: $($_.Exception.Message)`n” -foregroundcolor white -backgroundcolor darkred
exit 1
}
#————————————————————————————————–

if($Status -ne “success”){exit 1}

Thanks to the following forum posts:

http://social.technet.microsoft.com/Forums/en-US/identitylifecyclemanage…

http://social.technet.microsoft.com/Forums/en-US/ilm2/thread/cce395ad-e3…

Internet connection in VMWare machine

I had set up a test DC environment and after I did so, whenever I spun up a new VM, I couldn’t connect to the internet.

The solution was to disable the DCHP service on the test DC, change the Network Adapter settings in the VM to NAT and restart the machine.

Once rebooted, an ipconfig /release then ipconfig /renew at the command line fixed it right up.

Thanks to my sys ad for the help!

Windows Phone 7 Open Browser from Button

I love Stack Overflow… They saved me from a Windows Phone 7 problem.http://stackoverflow.com/questions/4253186/webbrowsertask-fails

Basically, I was trying to use a WebBrowserTask to open a URL in a browser from my phone app. It kept opening a browser, but without the address bar populated.

Turns out, when you are debugging your application, it fails. Running outside of debug mode, the browser opens to the proper link just fine.

WebBrowserTask task = new WebBrowserTask();
task.URL = Uri.EscapeDataString(sURL);
task.Show();

Hiding the Change Password link in Live@edu

In Powershell, connect to your Live@edu service as normal and then use these commands. You might want to try it out in a test environment first. Also, this only hides the link in outlook.com not for other Live services.:

New-ManagementRole -Name MyOptions_Custom_NoPwdChg -Parent MyBaseOptions_DefaultMailboxPlan

Set-ManagementRoleEntry MyOptions_Custom_NoPwdChg\Set-Mailbox -Parameters Password -RemoveParameter

New-ManagementRoleAssignment -Name MyBaseOptions_DefaultMailboxPlan-RoleAssignmentPolicyNoPwdChg -Role Custom_NoPwdChg -Policy RoleAssignmentPolicy-DefaultMailboxPlan

Get-ManagementRoleAssignment -RoleAssignee RoleAssignmentPolicy-DefaultMailboxPlan | Set-ManagementRoleAssignment -Enabled:$True -confirm

Enable the MyBaseOptions_DefaultMailboxPlan-RoleAssignmentPolicy-NoPwdChg assignment.

Get-ManagementRoleAssignment -RoleAssignee RoleAssignmentPolicy-DefaultMailboxPlan | Set-ManagementRoleAssignment -Enabled:$False -confirm

Disable the MyBaseOptions_DefaultMailboxPlan-RoleAssignmentPolicy_DefaultMai assignment.

For GALDisabled, I followed the same steps, but based things on the GalDisabled plan:

New-ManagementRole –Name Custom_NoPasswordChangeGAL_Role -Parent MyBaseOptions_GalDisabledMailboxPlan

New-ManagementRoleAssignment -Name MyBaseOptions_GALDisabledMBXPlan-RoleAssignmentPolicyNoPwdChg -Role Custom_NoPasswordChangeGAL_Role -Policy RoleAssignmentPolicy-GALDisabledMailboxPlan

RequiredAttendees with EWS

I was having trouble figuring out how to get the required attendees copied from Exchange 2007 to Exchange in the cloud.

After much searching I came across this post: http://stackoverflow.com/questions/3731303/exchange-web-services-create-…

While this gave me the bones to get the required attendees on an appointment, I needed to be able to add the attendees dynamically.

Here is what I came up with:

ResourceMailboxes.ExchangeWebServices.ItemInfoResponseMessageType rmResponseMessage = giResponse.ResponseMessages.Items[0] as ResourceMailboxes.ExchangeWebServices.ItemInfoResponseMessageType;

ResourceMailboxes.ExchangeWebServices.CalendarItemType ciCalentry = (ResourceMailboxes.ExchangeWebServices.CalendarItemType)rmResponseMessage.Items.Items[0];
int i = 0;

string strAttendees = string.Empty;

foreach (ResourceMailboxes.ExchangeWebServices.AttendeeType atAttendee in ciCalentry.RequiredAttendees)
{
if (atAttendee.Mailbox.EmailAddress.ToString().Trim() != string.Empty)
{
if (strAttendees == string.Empty)
{
strAttendees = atAttendee.Mailbox.EmailAddress.ToString();
}
else
{
strAttendees += “:” + atAttendee.Mailbox.EmailAddress.ToString();
}
Console.WriteLine(strAttendees);
//arrAttendees[i] = atAttendee.Mailbox.EmailAddress.ToString();
i++;
}
}
string[] arrAttendees = strAttendees.Split(new char[] { ‘:’ });
ResourceMailboxes.LiveEduWebService.AttendeeType[] arrAttendeeType = new ResourceMailboxes.LiveEduWebService.AttendeeType[i];
for (int x = 0; x < i; x++)
{
ResourceMailboxes.LiveEduWebService.AttendeeType attType = new ResourceMailboxes.LiveEduWebService.AttendeeType
{
Mailbox = new ResourceMailboxes.LiveEduWebService.EmailAddressType
{
EmailAddress = arrAttendees[x].ToString(),
RoutingType = “SMTP”
}
};
arrAttendeeType[x] = attType;
}
calendarItem.RequiredAttendees = arrAttendeeType;