One of the great features of FIM is that it is relatively easy to plugin custom functionality. You can extend the synchronization engine by developing rules extension and you can add custom workflows to the FIM portal. Rules extensions run under the FIM synchronization service account, workflows under the FIM service service account. This article describes an approach to enable communication to external systems (eg Exchange). Because you typically do not grant a service account rights to Microsoft Exchange, you need the ability to run part of your code using different credentials.
You do not want to have passwords in clear text in configuration files or source code. That is where encryption comes into play. Encryption can be handled in a myriad of different ways. The method described here uses powershell cmdlets, which keeps it quite simple and understandable.
So, how do we convert plain text to something more secure that cannot be read by anyone who happens to have read access to the files? Following two powershell commands are the answer:
$secureString = ConvertTo-SecureString -AsPlainText
-Force -String $pwd
$text = ConvertFrom-SecureString $secureString
creates a secure string object from the password stored in the variable
variable is a textual representation of the secure string and looks something like this:
To decrypt the password in powershell, use the
The output of this cmdlet is a secure string object which can be used to build a
To perform decryption in C# you need to add a reference to
in your project. To export the dll to the current directory execute following powershell cmd:
Copy ([PSObject].Assembly.Location) .
Following code shows how to use the PowerShell library to construct a PSCredential object. The PSCredential object can then be used to perform management operations on Exchange.
private string PWD = "01000000d08c9ddf0115d1118c7
private string USER = @"is4u\sa-ms-exch";
private PSCredential getPowershellCredential()
string powershellUsername = USER;
SecureString pwd = getPowershellPassword(PWD);
if (pwd != null)
powershellCredential = new
throw new Exception("Password is invalid");
private SecureString getPowershellPassword(string encryptedPwd)
SecureString pwd = null;
using (PowerShell powershell = PowerShell.Create())
Collection<PSObject> results = powershell.Invoke();
if (results.Count > 0)
PSObject result = results;
pwd = (SecureString)result.BaseObject;
If your operation requires you to connect using a network credential instead of a PSCredential object, this is very easy. You can get the corresponding
object from the
private NetworkCredential getNetworkCredential()
NetworkCredential cred = getPowershellCredential().GetNetworkCredential();
Only the user account that encrypted the password can decrypt it (because Kerberos keys are used under the hood). This is illustrated in following screenshot. If you look carefully, you can check I did not cheat on the parameter.
The approach described here is simple, quick and secure. You need to run a few PowerShell commands and you can store passwords securely in your configuration files. Make sure to encrypt the required password using the service account that will be performing the decryption. Note that this technique is not limited to use in FIM deployments. You can use this technique in any .Net/Windows context.
Scripting Guy - Decrypt PowerShell Secure String Password