[Powershell + Exchange 2007 + WCF] Créer une nouvelle mailbox

Hello,

J’ai un petit soucis concernant un webservice que j’ai créé qui devrait permettre de créer une nouvelle mailbox en utilisant les fonctionnalités de script Powershell de Exchange 2007.

Le problème est un soucis de droits et d’impersonnalisation. En gros, j’ai une application (ASP) qui doit accéder à un webservice (WCF) qui va créer un Runspace pour exécuter un script Powershell qui va créer une nouvelle mailbox. (me demandez pas pourquoi c’est si compliqué, c’est moi qui choisit)

Mon code est tout à fait similaire à celui-ci, provenant de ce site.

[codebox]public static void CreateUserMailbox(string domain, string ou,

string database, string alias, string name,

string displayName, SecureString password)

{

string upn = string.Format("{0}@{1}", alias, domain);



ICollection<PSObject> results;



// Create a runspace. We can't use the RunspaceInvoke class this time

// because we need to get at the underlying runspace to explicitly

// add the commands.

RunspaceConfiguration rc = RunspaceConfiguration.Create();

PSSnapInException snapEx = null;

PSSnapInInfo info = rc.AddPSSnapIn(

	"Microsoft.Exchange.Management.PowerShell.Admin",

	out snapEx);

Runspace myRunSpace = RunspaceFactory.CreateRunspace(rc);

myRunSpace.Open();



// Create a pipeline...

Pipeline pipeLine = myRunSpace.CreatePipeline();



using (pipeLine)

{

	// Create a command object so we can set some parameters

	// for this command.

	Command newMbx = new Command("new-mailbox");

	newMbx.Parameters.Add("alias", alias);

	newMbx.Parameters.Add("database", database);

	newMbx.Parameters.Add("password", password);

	newMbx.Parameters.Add("Name", name);

	newMbx.Parameters.Add("DisplayName", displayName);

	newMbx.Parameters.Add("UserPrincipalName", upn);

	newMbx.Parameters.Add("OrganizationalUnit", ou);



	// Add the command we've constructed

	pipeLine.Commands.Add(newMbx);



	// Execute the pipeline and save the objects returned.

	results = pipeLine.Invoke();



	// Print out any errors in the pipeline execution

	// NOTE: These error are NOT thrown as exceptions!

	// Be sure to check this to ensure that no errors

	// happened while executing the command.

	if (pipeLine.Error != null && pipeLine.Error.Count > 0)

	{

		Trace.WriteLine("ERROR: There were pipeline errors...\n");

		foreach (object item in pipeLine.Error.ReadToEnd())

		{

			Trace.WriteLine("Error: " + item.ToString() + "\n");

		}

	}



	// Print out the results of the pipeline execution

	if (results != null && results.Count > 0)

	{

Trace.WriteLine(“MAILBOXES CREATED: Created the following mailboxes…\n”);

		foreach (PSObject ps in results)

		{

			if (ps.Members["UserPrincipalName"].Value != null)

			{

				Trace.WriteLine("UserPrincipalName: "

					+ ps.Members["UserPrincipalName"].Value + "\n");

			}

		}

	}

}



pipeLine = null;

myRunSpace.Close();

myRunSpace = null;

}[/codebox]

Le problème qui se trouve, c’est que lorsque j’appelle le webservice en debug, tout se passe sans problème, par contre dès que je le publie et malgré la configuration de l’impersonnalisation, je n’ai plus les droits.

Histoire d’essayer de trouver d’où peut provenir l’erreur, j’ai fait ce test dans le webservice :
J’ai d’abord testé la valeur de

System.Security.Principal.WindowsIdentity.GetCurrent().Name; dans le webservice, sans surprises il me renvoie bien l’utilisateur dont j’ai configuré l’impresonnalisation.

Par contre si je fais :

RunspaceInvoke invoker = new RunspaceInvoke(); Collection<PSObject> results = invoker.Invoke("[System.Security.Principal.WindowsIdentity]::GetCurrent().name")
La valeur de results[0] est un user différent, en l’occurrence : “NT AUTHORITY\NETWORK SERVICE” et ceci uniquement si le service est publié sur IIS, s’il est en mode debug les deux utilisateurs sont identiques.

Est-ce que quelqu’un a une piste? Personnellement je suis perdu, j’ai bien trouvé ceci mais je peut pas dire que ça m’aide vraiment.

Merci

(Edit : Modifié le tag code en codebox)

L’impersonnation ASP.Net permet de prendre le contexte de sécurité d’un utilisateur Windows, et d’effectuer des actions en son nom sur le FileSystem etc. dans le thread courrant. Pour ce qui est du lancement de processus externe, l’identité utilisée est celle du process courrant (et pas du thread) (et par défaut c’est NETWORK SERVICE).

La meilleur solution consiste à faire tourner ton WebService dans un AppPool dont le compte windows a les droits de créer une MailBox (attention à donner seulement les droits requis, et à faire tourner seulement le WebService qui en a besoin sous cet AppPool).