1+ function Invoke-PatchUser {
2+ <#
3+ . FUNCTIONALITY
4+ Entrypoint
5+ . ROLE
6+ Identity.User.ReadWrite
7+ #>
8+ [CmdletBinding ()]
9+ param ($Request , $TriggerMetadata )
10+
11+ $APIName = $Request.Params.CIPPEndpoint
12+ $Headers = $Request.Headers
13+ Write-LogMessage - headers $Headers - API $APIName - message ' Accessed this API' - Sev ' Debug'
14+
15+ $HttpResponse = [HttpResponseContext ]@ {
16+ StatusCode = [HttpStatusCode ]::OK
17+ Body = @ {' Results' = @ (" Default response, you should never see this." ) }
18+ }
19+
20+ try {
21+ # Handle array of user objects or single user object
22+ $Users = if ($Request.Body -is [array ]) {
23+ $Request.Body
24+ } else {
25+ @ ($Request.Body )
26+ }
27+
28+ # Validate that all users have required properties
29+ $InvalidUsers = $Users | Where-Object {
30+ [string ]::IsNullOrWhiteSpace($_.id ) -or [string ]::IsNullOrWhiteSpace($_.tenantFilter )
31+ }
32+ if ($InvalidUsers.Count -gt 0 ) {
33+ $HttpResponse.StatusCode = [HttpStatusCode ]::BadRequest
34+ $HttpResponse.Body = @ {' Results' = @ (' Failed to patch user(s). Some users are missing id or tenantFilter' ) }
35+ } else {
36+ # Group users by tenant filter
37+ $UsersByTenant = $Users | Group-Object - Property tenantFilter
38+
39+ $TotalSuccessCount = 0
40+ $AllErrorMessages = @ ()
41+
42+ # Process each tenant separately
43+ foreach ($TenantGroup in $UsersByTenant ) {
44+ $tenantFilter = $TenantGroup.Name
45+ $TenantUsers = $TenantGroup.Group
46+
47+ # Build bulk requests for this tenant
48+ $int = 0
49+ $BulkRequests = foreach ($User in $TenantUsers ) {
50+ # Remove the id and tenantFilter properties from the body since they're not user properties
51+ $PatchBody = $User | Select-Object - Property * - ExcludeProperty id, tenantFilter
52+
53+ @ {
54+ id = $int ++
55+ method = ' PATCH'
56+ url = " users/$ ( $User.id ) "
57+ body = $PatchBody
58+ ' headers' = @ {
59+ ' Content-Type' = ' application/json'
60+ }
61+ }
62+ }
63+
64+ # Execute bulk request for this tenant
65+ $BulkResults = New-GraphBulkRequest - tenantid $tenantFilter - Requests @ ($BulkRequests )
66+
67+ # Process results for this tenant
68+ for ($i = 0 ; $i -lt $BulkResults.Count ; $i ++ ) {
69+ $result = $BulkResults [$i ]
70+ $user = $TenantUsers [$i ]
71+
72+ if ($result.status -eq 200 -or $result.status -eq 204 ) {
73+ $TotalSuccessCount ++
74+ Write-LogMessage - headers $Headers - API $APIName - tenant $tenantFilter - message " Successfully patched user $ ( $user.id ) " - Sev ' Info'
75+ } else {
76+ $errorMsg = if ($result.body.error.message ) {
77+ $result.body.error.message
78+ } else {
79+ " Unknown error (Status: $ ( $result.status ) )"
80+ }
81+ $AllErrorMessages += " Failed to patch user $ ( $user.id ) in tenant $ ( $tenantFilter ) : $errorMsg "
82+ Write-LogMessage - headers $Headers - API $APIName - tenant $tenantFilter - message " Failed to patch user $ ( $user.id ) . Error: $errorMsg " - Sev ' Error'
83+ }
84+ }
85+ }
86+
87+ # Build final response
88+ if ($AllErrorMessages.Count -eq 0 ) {
89+ $TenantCount = ($Users | Select-Object - Property tenantFilter - Unique).Count
90+ $HttpResponse.Body = @ {' Results' = @ (" Successfully patched $TotalSuccessCount user$ ( if ($TotalSuccessCount -ne 1 ){' s' }) across $TenantCount tenant$ ( if ($TenantCount -ne 1 ){' s' }) " ) }
91+ } else {
92+ $HttpResponse.StatusCode = [HttpStatusCode ]::BadRequest
93+ $HttpResponse.Body = @ {' Results' = $AllErrorMessages + @ (" Successfully patched $TotalSuccessCount of $ ( $Users.Count ) users" ) }
94+ }
95+ }
96+
97+ } catch {
98+ $HttpResponse.StatusCode = [HttpStatusCode ]::InternalServerError
99+ $HttpResponse.Body = @ {' Results' = @ (" Failed to patch user(s). Error: $ ( $_.Exception.Message ) " ) }
100+ }
101+
102+ Push-OutputBinding - Name Response - Value $HttpResponse
103+ }
0 commit comments