Skip to content

DeleteUserFromGroup (OP-06)

Request and response

Part Type Description
inUserId String The SamAccountName of the user to remove from the group.
inGroupName String The SamAccountName of the target group.
Part Type Description
<return> ADServiceResponse Response is Success (including on a swallowed exception) or GroupDoesNotExist. Message is always empty on this operation.

WebMethod attributes

<WebMethod()> — bare, no arguments supplied.

Steps

  1. CheckAccess(); on denial return AccessDenied() (BR-01).
  2. Initialize the response sentinel to Success.
  3. Open Try.
  4. Call H2 GetUserPrincipal for the external domain.
  5. If Nothing, fall through to step 8 leaving Response = Success.
  6. deUser = userPrin.GetUnderlyingObject.
  7. Call H3 GetGroupPrincipal for the external domain.
  8. If Nothing, set Response = GroupDoesNotExist.
  9. Else deGroup = groupPrin.GetUnderlyingObject; call deGroup.Invoke("Remove", New Object() {deUser.Path}) — the code drops to the underlying DirectoryEntry deliberately, per the authored comment "Need to go down to DirectoryEntry because the groupPrincipal Remove method fails on large groups" (BR-19); then deGroup.CommitChanges().
  10. Catch ex As Exception: the exception is swallowed — the authored comment reads "gobble - user is probably not in the group" (BR-20). This is tech debt TD-20 (HIGH — see Tech debt): a genuine directory failure is indistinguishable from a completed removal.
  11. Finally releases deGroup, deUser, groupPrin, and userPrin.
  12. Return the response sentinel.

Process flow

flowchart TD
    A["Call DeleteUserFromGroup"] --> B{"CheckAccess<br>HasAccess?"}
    B -->|"No"| C["Return AccessDenied"]
    B -->|"Yes"| D["GetUserPrincipal<br>external domain"]
    D -->|"Nothing"| E["Fall through<br>leave Success"]
    D -->|"Found"| F["GetGroupPrincipal<br>external domain"]
    F -->|"Nothing"| G["Set GroupDoesNotExist"]
    F -->|"Found"| H["DirectoryEntry.Invoke Remove<br>then CommitChanges"]
    H -.->|"Any exception"| I["Swallow exception<br>leave Success"]
    E --> J["Return response"]
    G --> J
    H --> J
    I --> J

Shared state effects

None — this operation touches no process-wide state; all locals are per-request.

Error handling

The operation always returns a sentinel ADServiceResponse; it never surfaces a framework SOAP fault. Because the Catch block is empty, it returns Success for a genuine removal, for "user was not a member", and for a directory failure alike (tech debt TD-20). See Faults for the service-wide fault model.

Authorization

Gated by BR-01: the caller must pass the IP allow-list check enforced by CheckAccess. See Authentication and authorization.

Sources

  • src\ADUserServices\clsADUserServices.asmx.vb (lines 297-340)