@@ -30,12 +30,24 @@ function Search-CIPPDbData {
3030 . PARAMETER Limit
3131 Maximum total number of results to return across all types. Default is unlimited (0)
3232
33+ . PARAMETER UserProperties
34+ Array of property names to return for Users type. If not specified, all properties are returned.
35+ Only applies when Types includes 'Users'. Valid properties include: id, accountEnabled, businessPhones,
36+ city, createdDateTime, companyName, country, department, displayName, faxNumber, givenName,
37+ isResourceAccount, jobTitle, mail, mailNickname, mobilePhone, onPremisesDistinguishedName,
38+ officeLocation, onPremisesLastSyncDateTime, otherMails, postalCode, preferredDataLocation,
39+ preferredLanguage, proxyAddresses, showInAddressList, state, streetAddress, surname,
40+ usageLocation, userPrincipalName, userType, assignedLicenses, onPremisesSyncEnabled, signInActivity
41+
3342 . EXAMPLE
3443 Search-CIPPDbData -TenantFilter 'contoso.onmicrosoft.com' -SearchTerms 'john.doe' -Types 'Users', 'Groups'
3544
3645 . EXAMPLE
3746 Search-CIPPDbData -SearchTerms 'admin' -Types 'Users'
3847
48+ . EXAMPLE
49+ Search-CIPPDbData -SearchTerms 'admin' -Types 'Users' -UserProperties 'id', 'displayName', 'userPrincipalName', 'mail'
50+
3951 . EXAMPLE
4052 Search-CIPPDbData -SearchTerms 'SecurityDefaults', 'ConditionalAccess' -Types 'ConditionalAccessPolicies', 'Organization'
4153
@@ -69,7 +81,10 @@ function Search-CIPPDbData {
6981 [int ]$MaxResultsPerType = 0 ,
7082
7183 [Parameter (Mandatory = $false )]
72- [int ]$Limit = 0
84+ [int ]$Limit = 0 ,
85+
86+ [Parameter (Mandatory = $false )]
87+ [string []]$UserProperties
7388 )
7489
7590 try {
@@ -143,26 +158,82 @@ function Search-CIPPDbData {
143158 if ($IsMatch ) {
144159 try {
145160 $Data = $Item.Data | ConvertFrom-Json
146- $ResultItem = [PSCustomObject ]@ {
147- Tenant = $Item.PartitionKey
148- Type = $Type
149- RowKey = $Item.RowKey
150- Data = $Data
151- Timestamp = $Item.Timestamp
152- }
153- $Results.Add ($ResultItem )
154- $TypeResultCount ++
155161
156- # Check total limit first
157- if ($Limit -gt 0 -and $Results.Count -ge $Limit ) {
158- Write-Verbose " Reached total limit of $Limit results"
159- break typeLoop
162+ # For Users type with UserProperties, verify match is in target properties
163+ $IsVerifiedMatch = $true
164+ if ($Type -eq ' Users' -and $UserProperties -and $UserProperties.Count -gt 0 ) {
165+ $IsVerifiedMatch = $false
166+
167+ if ($MatchAll ) {
168+ # All search terms must match in target properties
169+ $IsVerifiedMatch = $true
170+ foreach ($SearchTerm in $SearchTerms ) {
171+ $SearchPattern = [regex ]::Escape($SearchTerm )
172+ $TermMatches = $false
173+ foreach ($Property in $UserProperties ) {
174+ if ($Data.PSObject.Properties.Name -contains $Property -and
175+ $null -ne $Data .$Property -and
176+ $Data .$Property.ToString () -match $SearchPattern ) {
177+ $TermMatches = $true
178+ break
179+ }
180+ }
181+ if (-not $TermMatches ) {
182+ $IsVerifiedMatch = $false
183+ break
184+ }
185+ }
186+ } else {
187+ # Any search term can match in target properties
188+ foreach ($SearchTerm in $SearchTerms ) {
189+ $SearchPattern = [regex ]::Escape($SearchTerm )
190+ foreach ($Property in $UserProperties ) {
191+ if ($Data.PSObject.Properties.Name -contains $Property -and
192+ $null -ne $Data .$Property -and
193+ $Data .$Property.ToString () -match $SearchPattern ) {
194+ $IsVerifiedMatch = $true
195+ break
196+ }
197+ }
198+ if ($IsVerifiedMatch ) { break }
199+ }
200+ }
160201 }
161202
162- # Check max results per type
163- if ($MaxResultsPerType -gt 0 -and $TypeResultCount -ge $MaxResultsPerType ) {
164- Write-Verbose " Reached max results per type ($MaxResultsPerType ) for type '$Type '"
165- continue typeLoop
203+ # Only add to results if verified (or not Users/UserProperties)
204+ if ($IsVerifiedMatch ) {
205+ # Filter user properties if specified and type is Users
206+ if ($Type -eq ' Users' -and $UserProperties -and $UserProperties.Count -gt 0 ) {
207+ $FilteredData = [PSCustomObject ]@ {}
208+ foreach ($Property in $UserProperties ) {
209+ if ($Data.PSObject.Properties.Name -contains $Property ) {
210+ $FilteredData | Add-Member - MemberType NoteProperty - Name $Property - Value $Data .$Property - Force
211+ }
212+ }
213+ $Data = $FilteredData
214+ }
215+
216+ $ResultItem = [PSCustomObject ]@ {
217+ Tenant = $Item.PartitionKey
218+ Type = $Type
219+ RowKey = $Item.RowKey
220+ Data = $Data
221+ Timestamp = $Item.Timestamp
222+ }
223+ $Results.Add ($ResultItem )
224+ $TypeResultCount ++
225+
226+ # Check total limit first (only for verified matches)
227+ if ($Limit -gt 0 -and $Results.Count -ge $Limit ) {
228+ Write-Verbose " Reached total limit of $Limit results"
229+ break typeLoop
230+ }
231+
232+ # Check max results per type (only for verified matches)
233+ if ($MaxResultsPerType -gt 0 -and $TypeResultCount -ge $MaxResultsPerType ) {
234+ Write-Verbose " Reached max results per type ($MaxResultsPerType ) for type '$Type '"
235+ continue typeLoop
236+ }
166237 }
167238 } catch {
168239 Write-Verbose " Failed to parse JSON for $ ( $Item.RowKey ) : $ ( $_.Exception.Message ) "
0 commit comments