SharePoint-Gruppenbesitzer automatisiert setzen – eine praxisnahe Lösung mit ProcessQuery
beratung development microsoft365 power plattform sharepoint spfx

SharePoint-Gruppenbesitzer automatisiert setzen – eine praxisnahe Lösung mit ProcessQuery

Ein Fall aus der Praxis: Warum PnP JS an seine Grenzen stößt Im Rahmen eines Kundenprojekts entwickelte ich ein client-seitiges Provisioning-Tool auf Basis von SPFx. Dieses Tool sollte SharePoint-Sites inklusive zugehöriger Gruppen automatisiert anlegen, konfigurieren und mit Berechtigungen versehen. Teil der Aufgabenstellung war es, den Gruppen auch automatisch eine passende Besitzergruppe zuzuweisen. Die Herausforderung: Die…

28.07.2025

Ein Fall aus der Praxis: Warum PnP JS an seine Grenzen stößt

Im Rahmen eines Kundenprojekts entwickelte ich ein client-seitiges Provisioning-Tool auf Basis von SPFx. Dieses Tool sollte SharePoint-Sites inklusive zugehöriger Gruppen automatisiert anlegen, konfigurieren und mit Berechtigungen versehen. Teil der Aufgabenstellung war es, den Gruppen auch automatisch eine passende Besitzergruppe zuzuweisen.

Die Herausforderung: Die PnP JS-Bibliothek erlaubt mit folgendem Aufruf:

tsCopyEditsp.web.siteGroups.getById(<groupId>).setUserAsOwner(<userId>)


…nur das Setzen eines einzelnen Benutzers als Gruppenbesitzer. Eine native Möglichkeit, eine andere SharePoint-Gruppe als Besitzer zu definieren, gibt es nicht – doch genau das war in unserem Fall notwendig.

Die Lösung fanden wir über einen wenig dokumentierten Mechanismus: ProcessQuery.


Die Lösung im Detail: POST-Request an Client.svc/ProcessQuery

Die klassische SharePoint REST API bietet hierfür keine geeignete Option. Über den CSOM-Endpunkt
/_vti_bin/client.svc/ProcessQuery
lässt sich jedoch eine Gruppe als Besitzer einer anderen setzen – mittels eines XML-basierten Requests.

Beispielhafter Aufruf:

tsCopyEditspHttpClient.post(`${webUrl}/_vti_bin/client.svc/ProcessQuery`, ...)

Was ist ProcessQuery?

ProcessQuery ist Teil des Client Side Object Model (CSOM) von SharePoint. Diese Schnittstelle verarbeitet XML-basierte Clientanfragen und liefert JSON-Antworten zurück. Sie wird hauptsächlich intern genutzt und ist nicht breit dokumentiert.

Ein Request beschreibt:

  • Welche Objekte betroffen sind (z. B. Gruppen, Listen)
  • Welche Aktionen ausgeführt werden sollen (z. B. SetProperty, Update)

Der XML-Aufbau: Actions und ObjectPaths

Ein typischer Payload sieht so aus:

xmlCopyEdit<Request ...>
  <Actions>
    <SetProperty Id="1" ObjectPathId="2" Name="Owner">
      <Parameter ObjectPathId="3" />
    </SetProperty>
    <Method Name="Update" Id="4" ObjectPathId="2" />
  </Actions>
  <ObjectPaths>
    <Identity Id="2" Name="GUID:site:SITEID:g:GROUPID" />
    <Identity Id="3" Name="GUID:site:SITEID:g:OWNERGROUPID" />
  </ObjectPaths>
</Request>

Die Stolperfalle: Das „Name“-Attribut im Identity-Tag

Besonders verwirrend war für uns der Aufbau des Name-Attributs:

xmlCopyEditName="740c6a0b-85e2-48a0-a494-e0f1759d4aa7:site:<siteId>:g:<groupId>"

Dabei gilt:

  • 740c6a0b-85e2-48a0-a494-e0f1759d4aa7 ist die Standard-ClientContext-GUID von SharePoint Online.
  • Sie ist nicht mandantenspezifisch, sondern in SharePoint Online universell gültig.

Codebeispiel: TypeScript-Methode zur Besitzübertragung

Hier die Methode, die wir erfolgreich eingesetzt haben:

tsCopyEditpublic async setOwnerOfGroup(
  siteId: string,
  newGroupId: number,
  ownerGroupId: number,
  spHttpClient: SPHttpClient,
  targetWebInfo: IWebInfo,
  digest: string
): Promise<void> {
  const contextGuid = "740c6a0b-85e2-48a0-a494-e0f1759d4aa7";

const setOwnerPayload = &lt;Request xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="SPFx Custom"&gt; &lt;Actions&gt; &lt;SetProperty Id="1" ObjectPathId="2" Name="Owner"&gt; &lt;Parameter ObjectPathId="3" /&gt; &lt;/SetProperty&gt; &lt;Method Name="Update" Id="4" ObjectPathId="2" /&gt; &lt;/Actions&gt; &lt;ObjectPaths&gt; &lt;Identity Id="2" Name="${contextGuid}:site:${siteId}:g:${newGroupId}" /&gt; &lt;Identity Id="3" Name="${contextGuid}:site:${siteId}:g:${ownerGroupId}" /&gt; &lt;/ObjectPaths&gt; &lt;/Request&gt;;

const response = await spHttpClient.post( ${targetWebInfo.Url}/_vti_bin/client.svc/ProcessQuery, SPHttpClient.configurations.v1, { headers: { “Content-Type”: “text/xml”, Accept: “application/json”, “X-RequestDigest”: digest, }, body: setOwnerPayload.trim(), } );

const responseText = await response.text(); const responseJson = JSON.parse(responseText); const hasError = responseJson.some((item: any) => item.ErrorInfo);

if (!response.ok || hasError) { throw new Error(“Setting SharePoint group owner failed.”); } }


Fazit: ProcessQuery – nicht offiziell, aber wirkungsvoll

Auch wenn ProcessQuery nicht zu den offiziell unterstützten Methoden zählt, bietet es in der Praxis eine effiziente Möglichkeit, bestimmte SharePoint-Konfigurationen vorzunehmen – insbesondere dann, wenn REST oder PnP JS an Grenzen stoßen.

Wir planen, diese Methode künftig gezielt in SPFx-Projekten und Power Platform-Lösungen zu nutzen.

Tipp: Sie stehen vor einer ähnlichen Herausforderung? Wir beraten Sie gern – schreiben Sie uns!

Zeig uns eure M365-Umgebung – wir zeigen euch das Potenzial.

In einem 30-minütigen Erstgespräch schauen wir gemeinsam auf eure aktuelle M365-Umgebung, klären das Zielbild und zeigen, wo der schnellste Weg zu messbaren Ergebnissen liegt – kostenlos und unverbindlich.