Sharepoint: Ausführen von stsadm über einen Zeitgeberjob + SHAREPOINT \ Systemrechte

Translate

Ich habe eine ungewöhnliche Situation, in der ich einen SharePoint-Zeitgeberauftrag benötige, um sowohl über lokale Administratorrechte als auch über Windows-Berechtigungen zu verfügenSHAREPOINT\SystemSharePoint-Berechtigungen.

Ich kann die Windows-Berechtigungen erhalten, indem ich einfach den Zeitgeberdienst so konfiguriere, dass ein Konto verwendet wird, das Mitglied lokaler Administratoren ist. Ich verstehe, dass dies keine gute Lösung ist, da der SharePoint-Zeitgeberdienst mehr Rechte erhält, als er haben sollte. Zumindest kann mein SharePoint-Timer-Job ausgeführt werdenstsadm.

Ein weiteres Problem beim Ausführen des Timer-Dienstes unter dem lokalen Administrator besteht darin, dass dieser Benutzer dies nicht unbedingt hatSHAREPOINT\SystemSharePoint-Berechtigungen, die ich auch für diesen SharePoint-Job benötige. Es stellt sich heraus, dassSPSecurity.RunWithElevatedPrivilegeswird in diesem Fall nicht funktionieren. Reflektor zeigt dasRunWithElevatedPrivilegesprüft, ob der aktuelle Prozess istowstimer(der Dienstprozess, der SharePoint-Jobs ausführt) und keine Erhöhung ausführt, ist dies der Fall (das Rationale hier ist wohl, dass der Timer-Dienst ausgeführt werden sollNT AUTHORITY\NetworkServiceWindows-Konto welches was hatSHAREPOINT\SystemSharePoint-Berechtigungen, und daher müssen die Berechtigungen für einen Zeitgeberauftrag nicht erhöht werden.

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

Es scheint, dass jetzt alles funktionieren sollte, aber hier ist ein weiteres Problem, an dem ich im Moment festhalte. 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 nur das Popup.

Der lokale Administrator ist mein Konto und wenn ich gerade laufestsadmInteraktiv unter diesem Konto ist alles in Ordnung. Es funktioniert auch gut, wenn ich den Timer-Dienst so konfiguriere, dass er unter diesem Konto ausgeführt wird.

Anregungen sind willkommen :)

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Ich bin nicht auf der Arbeit, daher ist mir das ein Rätsel, aber: Wenn Sie einen Verweis auf die Site erhalten, können Sie versuchen, mit dem SYSTEM-UserToken eine neue SPSite zu erstellen?

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

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

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

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

Quelle
axk
Translate

Andere Anwendungen, die auf diese Weise ausgeführt werden (z. B. von einem Zeitgeberjob mit expliziten Anmeldeinformationen), schlagen auf die gleiche Weise fehl wie "Die Anwendung konnte nicht ordnungsgemäß initialisiert werden". Ich habe gerade eine einfache App erstellt, die einen Pfad einer anderen ausführbaren Datei und ihrer Argumente als Parameter verwendet, und wenn sie von diesem Timer-Job ausgeführt wird, schlägt sie auf die gleiche Weise fehl.

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 Benutzername und Passwort

Quelle