Frage

Ich habe eine ungewöhnliche Situation, in der ich einen SharePoint-Timer-Job benötige, um sowohl über lokale Windows-Administratorrechte zu verfügen als auch über Windows-Berechtigungen zu verfügen SHAREPOINT\System SharePoint-Berechtigungen.

Ich kann die Windows-Berechtigungen erhalten, indem ich einfach den Timer-Dienst so konfiguriere, dass er ein Konto verwendet, das Mitglied der lokalen Administratoren ist.Ich verstehe, dass dies keine gute Lösung ist, da sie dem SharePoint-Timer-Dienst mehr Rechte gibt, als er haben sollte.Aber es ermöglicht zumindest die Ausführung meines SharePoint-Timerjobs stsadm.

Ein weiteres Problem bei der Ausführung des Timer-Dienstes unter einem lokalen Administrator besteht darin, dass dieser Benutzer dies nicht unbedingt tun muss SHAREPOINT\System SharePoint-Berechtigungen, die ich auch für diesen SharePoint-Job benötige.Es stellt sich heraus, dass SPSecurity.RunWithElevatedPrivileges wird in diesem Fall nicht funktionieren.Reflektor zeigt das RunWithElevatedPrivileges prüft, ob der aktuelle Prozess vorhanden ist owstimer (der Dienstprozess, der SharePoint-Jobs ausführt) und keine Erhöhung durchführt, ist dies der Fall (der Grund hier ist wohl, dass der Timer-Dienst unter laufen soll NT AUTHORITY\NetworkService Windows-Konto welches welches hat SHAREPOINT\System SharePoint-Berechtigungen, daher besteht keine Notwendigkeit, die Berechtigungen für einen Zeitgeberauftrag zu erhöhen.

Die einzig mögliche Lösung scheint hier darin zu bestehen, den Timer-Dienst unter seinem üblichen NetworkService-Windows-Konto auszuführen und stsadm als lokalen Administrator auszuführen, indem die Administrator-Anmeldeinformationen irgendwo gespeichert und über den StarInfo-Benutzernamen an System.Diagnostics.Process.Run() übergeben werden , Domäne und Passwort.

Es scheint, dass jetzt alles funktionieren sollte, aber es gibt noch ein weiteres Problem, das mich im Moment beschäftigt.Stsamd schlägt mit dem folgenden Fehler-Popup fehl (!) (Winternals Filemon zeigt an, dass stsadm in diesem Fall unter dem Administrator ausgeführt wird):

The application failed to initialize properly (0x0c0000142).
Click OK to terminate the application.

Die Ereignisanzeige registriert nichts außer dem Popup.

Der lokale Administratorbenutzer ist mein Konto und wenn ich es gerade ausführe stsadm interaktiv unter diesem Account ist alles ok.Es funktioniert auch einwandfrei, wenn ich den Timer-Dienst so konfiguriere, dass er unter diesem Konto ausgeführt wird.

Alle Vorschläge sind willkommen :)

Keine korrekte Lösung

Andere Tipps

Da ich nicht auf der Arbeit bin, fällt mir das spontan ein, aber:Wenn Sie einen Verweis auf die Site erhalten, können Sie versuchen, eine neue SPSite mit dem SYSTEM-UserToken zu erstellen?

SPUserToken sut = thisSite.RootWeb.AllUsers["SHAREPOINT\SYSTEM"].UserToken;

using (SPSite syssite = new SPSite(thisSite.Url,sut)
{
    // Do what you have to do
}

Die SharePoint-Timer-Jobs werden mit den Anmeldeinformationen des SharePoint-Firmenadministrators ausgeführt, da die Informationen in die SharePoint-Konfigurationsdatenbank gelangen.Daher hat der Anwendungspool keinen Zugriff.

Zum Testen des Zeitgeberauftrags in der Entwicklungsumgebung können wir das Anwendungspoolkonto vorübergehend in das Anwendungspoolkonto ändern, das für die Zentraladministration verwendet wird.

Andere Anwendungen werden auf diese Weise ausgeführt (d. h.von einem Zeitgeberauftrag mit expliziten Anmeldeinformationen) schlagen auf die gleiche Weise fehl mit „Die Anwendung konnte nicht ordnungsgemäß initialisiert werden“.Ich habe gerade eine einfache App geschrieben, die den Pfad einer anderen ausführbaren Datei und deren Argumente als Parameter verwendet und bei der Ausführung über diesen Timer-Job auf die gleiche Weise fehlschlägt.

internal class ExternalProcess
{
    public static void run(String executablePath, String workingDirectory, String programArguments, String domain, String userName,
                           String password, out Int32 exitCode, out String output)
    {
        Process process = new Process();

        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardOutput = true;

        StringBuilder outputString = new StringBuilder();
        Object synchObj = new object();

        DataReceivedEventHandler outputAppender =
            delegate(Object sender, DataReceivedEventArgs args)
                {
                    lock (synchObj)
                    {
                        outputString.AppendLine(args.Data);
                    }
                };

        process.OutputDataReceived += outputAppender;
        process.ErrorDataReceived += outputAppender;

        process.StartInfo.FileName = @"C:\AppRunner.exe";
        process.StartInfo.WorkingDirectory = workingDirectory;
        process.StartInfo.Arguments = @"""" + executablePath + @""" " + programArguments;

        process.StartInfo.UserName = userName;
        process.StartInfo.Domain = domain; 
        SecureString passwordString = new SecureString();

        foreach (Char c in password)
        {
            passwordString.AppendChar(c);
        }

        process.StartInfo.Password = passwordString;

        process.Start();

        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        process.WaitForExit();

        exitCode = process.ExitCode;
        output = outputString.ToString();
    }
}

AppRunner macht im Grunde das Gleiche wie das obige Fragment, jedoch ohne Benutzernamen und Passwort

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top