11using namespace System.Net
22
3- Function Invoke-AddUserBulk {
3+ function Invoke-AddUserBulk {
44 <#
55 . FUNCTIONALITY
66 Entrypoint
@@ -13,49 +13,138 @@ Function Invoke-AddUserBulk {
1313 $APIName = ' AddUserBulk'
1414 Write-LogMessage - headers $Request.Headers - API $APINAME - message ' Accessed this API' - Sev ' Debug'
1515 $TenantFilter = $Request.body.TenantFilter
16- $Body = foreach ($userobj in $request.body.BulkUser ) {
17- if ($userobj.usageLocation.value ) {
18- $userobj.usageLocation = $userobj.usageLocation.value
16+
17+ $BulkUsers = $Request.Body.BulkUser
18+
19+ if (! $BulkUsers ) {
20+ $Body = @ {
21+ Results = @ {
22+ resultText = ' No users specified to import'
23+ state = ' error'
24+ }
1925 }
20- try {
21- $password = if ($userobj.password ) { $userobj.password } else { New-passwordString }
22- $UserprincipalName = " $ ( $userobj.mailNickName ) @$ ( $userobj.domain ) "
23- $BodyToship = $userobj
24- # Remove domain from body to ship
25- $BodyToship = $BodyToship | Select-Object * - ExcludeProperty password, domain
26- $BodyToship | Add-Member - NotePropertyName accountEnabled - NotePropertyValue $true - Force
27- $BodyToship | Add-Member - NotePropertyName userPrincipalName - NotePropertyValue $UserprincipalName - Force
28- $BodyToship | Add-Member - NotePropertyName passwordProfile - NotePropertyValue @ {' password' = $password ; ' forceChangePasswordNextSignIn' = $true } - Force
29- Write-Host " body is now: $ ( $BodyToship | ConvertTo-Json - Depth 10 - Compress) "
30- if ($userobj.businessPhones ) { $bodytoShip.businessPhones = @ ($userobj.businessPhones ) }
31- $bodyToShip = ConvertTo-Json - Depth 10 - InputObject $BodyToship - Compress
32- Write-Host " Our body to ship is $bodyToShip "
33- $GraphRequest = New-GraphPostRequest - uri ' https://graph.microsoft.com/beta/users' - tenantid $TenantFilter - type POST - body $BodyToship
34- Write-Host " Graph request is $GraphRequest "
35- Write-LogMessage - headers $Request.Headers - API $APINAME - tenant $ ($TenantFilter ) - message " Created user $ ( $userobj.displayname ) with id $ ( $GraphRequest.id ) " - Sev ' Info'
36-
37- # PWPush
38- $PasswordLink = New-PwPushLink - Payload $password
39- if ($PasswordLink ) {
40- $password = $PasswordLink
26+ } else {
27+ $BulkRequests = [System.Collections.Generic.List [object ]]::new()
28+ $Results = [System.Collections.Generic.List [object ]]::new()
29+ $Messages = [System.Collections.Generic.List [object ]]::new()
30+ foreach ($User in $BulkUsers ) {
31+ # User input validation
32+ $missingFields = [System.Collections.Generic.List [string ]]::new()
33+ if (! $User.mailNickName ) { $missingFields.Add (' mailNickName' ) }
34+ if (! $User.domain ) { $missingFields.Add (' domain' ) }
35+ if (! $User.displayName -and ! $User.givenName -and ! $User.surname ) { $missingFields.Add (' displayName' ) }
36+
37+ $Name = if ([string ]::IsNullOrEmpty($User.displayName )) {
38+ ' {0} {1}' -f $User.givenName , $User.surname
39+ } else {
40+ $User.displayName
41+ }
42+
43+ # Check for missing required fields
44+ if ($missingFields.Count -gt 0 ) {
45+ $Results.Add (@ {
46+ resultText = " Required fields missing for $ ( $User ?? ' No name specified' ) : $ ( $missingFields -join ' , ' ) "
47+ state = ' error'
48+ })
49+ } else {
50+ # Create user body with required properties
51+ $Password = if ($User.password ) { $User.password } else { New-passwordString }
52+ $UserBody = @ {
53+ accountEnabled = $true
54+ displayName = $Name
55+ mailNickName = $User.mailNickName
56+ userPrincipalName = ' {0}@{1}' -f $User.mailNickName , $User.domain
57+ passwordProfile = @ {
58+ password = $Password
59+ forceChangePasswordNextSignIn = $true
60+ }
61+ }
62+
63+ # Add optional properties if not null or empty
64+ if (! [string ]::IsNullOrEmpty($User.usageLocation )) {
65+ $UserBody.usageLocation = $User.usageLocation.value ?? $User.usageLocation
66+ }
67+
68+ # Convert businessPhones to array if not null or empty
69+ if (! [string ]::IsNullOrEmpty($User.businessPhones )) {
70+ $UserBody.businessPhones = @ ($User.businessPhones )
71+ }
72+
73+ # loop through rest of post body and add to user body if not null or empty or not already set in the user body
74+ foreach ($key in $User.PSObject.Properties.Name ) {
75+ if ($key -notin @ (' displayName' , ' mailNickName' , ' domain' , ' password' , ' usageLocation' , ' businessPhones' )) {
76+ if (! [string ]::IsNullOrEmpty($User .$key ) -and $UserBody .$key -eq $null ) {
77+ $UserBody .$key = $User .$key
78+ }
79+ }
80+ }
81+
82+ # Build bulk request
83+ $BulkRequests.Add (@ {
84+ ' id' = $UserBody.userPrincipalName
85+ ' url' = ' users'
86+ ' method' = ' POST'
87+ ' body' = $UserBody
88+ ' headers' = @ {
89+ ' Content-Type' = ' application/json'
90+ }
91+ })
92+
93+ # Create password link
94+ $PasswordLink = New-PwPushLink - Payload $password
95+ if ($PasswordLink ) {
96+ $password = $PasswordLink
97+ }
98+
99+ # Set success messages
100+ $Messages.Add (@ {
101+ id = $UserBody.userPrincipalName
102+ resultText = " Created user for $ ( $Name ) with username $ ( $UserBody.userPrincipalName ) "
103+ copyField = $Password
104+ })
41105 }
42- $results = " Created user $ ( $UserprincipalName ) . Password is $password "
106+ }
43107
44- } catch {
45- Write-LogMessage - headers $Request.Headers - API $APINAME - tenant $ ($TenantFilter ) - message " Failed to create user. Error:$ ( $_.Exception.Message ) " - Sev ' Error'
46- $results = " Failed to create user $ ( $UserprincipalName ) . $ ( $_.Exception.Message ) "
108+ if ($BulkRequests.Count -gt 0 ) {
109+ Write-Warning " We have $ ( $BulkRequests.Count ) users to import"
110+ Write-Information ($BulkRequests | ConvertTo-Json - Depth 5 )
111+ $BulkResults = New-GraphBulkRequest - tenantid $TenantFilter - Requests $BulkRequests
112+ Write-Warning " We have $ ( $BulkResults.Count ) results"
113+ Write-Information ($BulkResults | ConvertTo-Json - Depth 10
114+ )
115+ foreach ($BulkResult in $BulkResults ) {
116+ if ($BulkResult.status -ne 201 ) {
117+ Write-LogMessage - headers $Request.Headers - API $APINAME - tenant $ ($TenantFilter ) - message " Failed to create user $ ( $BulkResult.id ) . Error:$ ( $BulkResult.body.error.message ) " - Sev ' Error'
118+ $Results.Add (@ {
119+ resultText = " Failed to create user $ ( $BulkResult.id ) . Error: $ ( $BulkResult.body.error.message ) "
120+ state = ' error'
121+ })
122+ } else {
123+ $Message = $Messages.Where ({ $_.id -eq $BulkResult.id })
124+ $Results.Add (@ {
125+ resultText = $Message.resultText
126+ state = ' success'
127+ copyField = $Message.copyField
128+ username = $BulkResult.body.userPrincipalName
129+ id = $BulkResult.id
130+ })
131+ }
132+ }
133+ } else {
134+ $Results.Add (@ {
135+ resultText = ' No users to import'
136+ state = ' error'
137+ })
47138 }
48- [PSCustomObject ]@ {
49- ' Results' = $results
50- ' Username' = $UserprincipalName
51- ' Password' = $password
139+ $Body = @ {
140+ Results = @ ($Results )
52141 }
53142 }
54143
55144 # Associate values to output bindings by calling 'Push-OutputBinding'.
56145 Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
57146 StatusCode = [HttpStatusCode ]::OK
58- Body = @ ( $Body )
147+ Body = $Body
59148 })
60149
61150}
0 commit comments