Access is denied beim async Solution Import (ImportSolutionRequest & ExecuteAsyncRequest )

Der Versuch eine Solution “ImportSolutionRequest” mit dem “ExecuteAsyncRequest” zu importieren scheitert mit folgendem Fehler:

“Solution Import Failed: 31 Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Access is denied. Detail: <OrganizationServiceFault xmlns:i=”http://www.w3.org/2001/XMLSchema-instance” xmlns=”http://schemas.microsoft.com/xrm/2011/Contracts”> <ErrorCode>-2147187707</ErrorCode> <ErrorDetails xmlns:d2p1=”http://schemas.datacontract.org/2004/07/System.Coll
ections.Generic” /> <Message>Access is denied.</Message><Timestamp>2014-08-22T12:31:53.4691706Z</Timestamp>”.

Einführung

Seit CRM 2013 gibt es die Möglichkeit einen Aktion bzw. einen Request asynchron ausführen zu lassen.
Dafür muss der Request mit einem ExecuteAsyncRequest an das CRM gesendet werden. Aktuell wird nur der ImportSolutionRequest unterstützt. Das heisst aktuell ist die einzige asynchron ausführbare Operation der Solution Import.

Hier ein Beispiel:
Eine Solution wird importiert. Danach wird gewartet, bis die Operation abgeschlossen wurde. Im Fehlerfall wird eine Exception geworfen.

var solutionBytes = File.ReadAllBytes("mysolution.zip");
var importSolutionRequest = newImportSolutionRequest
{  
    CustomizationFile = solutionBytes
};

var asyncRequest = newExecuteAsyncRequest
{
    Request = importSolutionRequest
};

var asyncResponse = (ExecuteAsyncResponse)orgService.Execute(asyncRequest);
asyncJobId = asyncResponse.AsyncJobId;

while (true)
{
    Thread.Sleep(10000);
    var asyncOperation = OrgService.Retrieve("asyncoperation", 
        asyncJobId.Value, 
        newColumnSet(true));

    switch ((int)asyncOperation["StatusCode"])
    {
        //Succeeded
        case 30:
            return;
        //Pausing, Canceling, Failed, Canceled
        case 21:
        case 22:
        case 31:
        case 32:
            throw new Exception(string.Format("Solution Import Failed: {0} {1}",
                (int)asyncOperation["StatusCode"], 
                (string)asyncOperation["Message"]));
        default:
            return;
        break;
    }
}

Im aktuellen Fall wurde die Operation mit dem “Access is denied” Fehler beendet/abgebrochen.

Diagnose
Zuerst wird die Fehlermeldung genau studiert:
<Message>System.UnauthorizedAccessException: Microsoft Dynamics CRM has
experienced an error. Reference number for administrators or support:
#15DD85B3</Message>

Man findet die CorrelationId, wie praktisch.
Als nächstes wird der CRM Trace auf Verbose eingeschalten (http://crmdiagtool2011.codeplex.com/). Die Suche nach der CorrelationId enthüllt die Ursache der UnauthorizedAccessException. Und zwar scheitert der Zugriff auf das Verzeichnis “C:Program FilesMicrosoft Dynamics CRMCustomizationImport”.

Da sich das Event im Async Trace befindet ist die Sache eigentlich schon klar. Wir bestätigen unsere Vermutung mit dem Process Monitor der SysInternals Suite (gefiltert auf “C:Program FilesMicrosoft Dynamics CRM”).

ProcessMon

Der Requests wird im Hintergrund und somit vom CRM AsyncService ausgeführt. Dieser hat keine Berechtigungen auf dem Folder “C:Program FilesMicrosoft Dynamics CRMCustomizationImport”.

Lösung
Der Service Account unter dem der CrmAsyncService läuft, muss auf dem Verzeichnis “C:Program FilesMicrosoft Dynamics CRMCustomizationImport” lese und schreib Rechte besitzen.

Leave a Reply

Your email address will not be published. Required fields are marked *