Skip to content

Commit 50087c4

Browse files
committed
fix(ninjaone): improve error handling and dedup logic
- Replace silent Write-Information bulk error messages with structured Write-LogMessage calls including normalized error details and batch counts - Handle duplicate document templates gracefully by selecting the oldest instead of throwing - Clear stale user/update cache entries from Azure Table Storage at sync start rather than reusing potentially stale data - Remove debug Write-Host from document template creation
1 parent 1393178 commit 50087c4

2 files changed

Lines changed: 26 additions & 26 deletions

File tree

Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneDocumentTemplate.ps1

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,20 @@ function Invoke-NinjaOneDocumentTemplate {
1818
} else {
1919
$DocumentTemplate = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/document-templates/$($ID)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -Depth 100
2020
}
21-
21+
2222
$MatchedCount = ($DocumentTemplate | Measure-Object).count
2323
if ($MatchedCount -eq 1) {
2424
# Matched a single document template
2525
$NinjaDocumentTemplate = $DocumentTemplate
2626
} elseif ($MatchedCount -eq 0) {
2727
# Create a new Document Template
2828
$Body = $Template | ConvertTo-Json -Depth 100
29-
Write-Host "Ninja Body: $body"
3029
$NinjaDocumentTemplate = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/document-templates/" -Method POST -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json' -Body $Body).content | ConvertFrom-Json -Depth 100
3130
} else {
32-
# Matched multiple templates. Should be impossible but lets check anyway :D
33-
Throw 'Multiple Documents Matched the Provided Criteria'
31+
$NinjaDocumentTemplate = $DocumentTemplate | Sort-Object { [int64]$_.id } | Select-Object -First 1
32+
Write-Warning "Multiple NinjaOne document templates named '$($Template.name)' found ($MatchedCount). Using the oldest (id $($NinjaDocumentTemplate.id)). Remove the duplicate template(s) in NinjaOne."
3433
}
3534

3635
return $NinjaDocumentTemplate
3736

38-
}
37+
}

Modules/CippExtensions/Public/NinjaOne/Invoke-NinjaOneTenantSync.ps1

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -746,30 +746,25 @@ function Invoke-NinjaOneTenantSync {
746746

747747

748748
$UsersFilter = "PartitionKey eq '$($Customer.CustomerId)'"
749-
[System.Collections.Generic.List[PSCustomObject]]$ParsedUsers = Get-CIPPAzDataTableEntity @UsersTable -Filter $UsersFilter
750-
if (($ParsedUsers | Measure-Object).count -eq 0) {
751-
[System.Collections.Generic.List[PSCustomObject]]$ParsedUsers = @()
749+
750+
[System.Collections.Generic.List[PSCustomObject]]$StaleParsedUsers = Get-CIPPAzDataTableEntity @UsersTable -Filter $UsersFilter
751+
if (($StaleParsedUsers | Measure-Object).count -gt 0) {
752+
Remove-AzDataTableEntity -Force @UsersTable -Entity ($StaleParsedUsers | Select-Object PartitionKey, RowKey)
752753
}
754+
[System.Collections.Generic.List[PSCustomObject]]$ParsedUsers = @()
753755

754-
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserCache = Get-CIPPAzDataTableEntity @UsersUpdateTable -Filter $UsersFilter
755-
if (($NinjaUserCache | Measure-Object).count -eq 0) {
756-
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserCache = @()
756+
[System.Collections.Generic.List[PSCustomObject]]$StaleUserUpdates = Get-CIPPAzDataTableEntity @UsersUpdateTable -Filter $UsersFilter
757+
if (($StaleUserUpdates | Measure-Object).count -gt 0) {
758+
Remove-AzDataTableEntity -Force @UsersUpdateTable -Entity ($StaleUserUpdates | Select-Object PartitionKey, RowKey)
757759
}
758760

759761
[System.Collections.Generic.List[PSCustomObject]]$UsersMap = Get-CIPPAzDataTableEntity @UsersMapTable -Filter $UsersFilter
760762
if (($UsersMap | Measure-Object).count -eq 0) {
761763
[System.Collections.Generic.List[PSCustomObject]]$UsersMap = @()
762764
}
763765

764-
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserUpdates = $NinjaUserCache | Where-Object { $_.action -eq 'Update' }
765-
if (($NinjaUserUpdates | Measure-Object).count -eq 0) {
766-
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserUpdates = @()
767-
}
768-
769-
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserCreation = $NinjaUserCache | Where-Object { $_.action -eq 'Create' }
770-
if (($NinjaUserCreation | Measure-Object).count -eq 0) {
771-
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserCreation = @()
772-
}
766+
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserUpdates = @()
767+
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserCreation = @()
773768

774769

775770
foreach ($user in $SyncUsers | Where-Object { $_.id -notin $ParsedUsers.RowKey }) {
@@ -1219,7 +1214,8 @@ function Invoke-NinjaOneTenantSync {
12191214
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserCreation = @()
12201215
}
12211216
} catch {
1222-
Write-Information "Bulk Creation Error, but may have been successful as only 1 record with an issue could have been the cause: $_"
1217+
$ErrorMessage = Get-CippException -Exception $_
1218+
Write-LogMessage -tenant $Customer.defaultDomainName -API 'NinjaOneSync' -message "NinjaOne user document creation failed for $($Customer.displayName). NinjaOne rejects the whole batch if any single document is invalid, so all $(($NinjaUserCreation | Measure-Object).count) user(s) in this batch were not written: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
12231219
}
12241220

12251221
try {
@@ -1231,7 +1227,8 @@ function Invoke-NinjaOneTenantSync {
12311227
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserUpdates = @()
12321228
}
12331229
} catch {
1234-
Write-Information "Bulk Update Errored, but may have been successful as only 1 record with an issue could have been the cause: $_"
1230+
$ErrorMessage = Get-CippException -Exception $_
1231+
Write-LogMessage -tenant $Customer.defaultDomainName -API 'NinjaOneSync' -message "NinjaOne user document update failed for $($Customer.displayName). NinjaOne rejects the whole batch if any single document is invalid, so all $(($NinjaUserUpdates | Measure-Object).count) user(s) in this batch were not written: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
12351232
}
12361233

12371234

@@ -1294,7 +1291,8 @@ function Invoke-NinjaOneTenantSync {
12941291

12951292
}
12961293
} catch {
1297-
Write-Information "Bulk Creation Error, but may have been successful as only 1 record with an issue could have been the cause: $_"
1294+
$ErrorMessage = Get-CippException -Exception $_
1295+
Write-LogMessage -tenant $Customer.defaultDomainName -API 'NinjaOneSync' -message "NinjaOne user document creation failed for $($Customer.displayName). NinjaOne rejects the whole batch if any single document is invalid, so all $(($NinjaUserCreation | Measure-Object).count) user(s) in this batch were not written: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
12981296
}
12991297

13001298
try {
@@ -1305,7 +1303,8 @@ function Invoke-NinjaOneTenantSync {
13051303
Remove-AzDataTableEntity -Force @UsersUpdateTable -Entity $NinjaUserUpdates
13061304
}
13071305
} catch {
1308-
Write-Information "Bulk Update Errored, but may have been successful as only 1 record with an issue could have been the cause: $_"
1306+
$ErrorMessage = Get-CippException -Exception $_
1307+
Write-LogMessage -tenant $Customer.defaultDomainName -API 'NinjaOneSync' -message "NinjaOne user document update failed for $($Customer.displayName). NinjaOne rejects the whole batch if any single document is invalid, so all $(($NinjaUserUpdates | Measure-Object).count) user(s) in this batch were not written: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
13091308
}
13101309

13111310
### Relationship Mapping
@@ -1483,7 +1482,8 @@ function Invoke-NinjaOneTenantSync {
14831482
[System.Collections.Generic.List[PSCustomObject]]$CreatedLicenses = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method POST -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ($NinjaLicenseCreation | ConvertTo-Json -Depth 100 -AsArray) -EA Stop).content | ConvertFrom-Json -Depth 100
14841483
}
14851484
} catch {
1486-
Write-Information "Bulk Creation Error, but may have been successful as only 1 record with an issue could have been the cause: $_"
1485+
$ErrorMessage = Get-CippException -Exception $_
1486+
Write-LogMessage -tenant $Customer.defaultDomainName -API 'NinjaOneSync' -message "NinjaOne license document creation failed for $($Customer.displayName). NinjaOne rejects the whole batch if any single document is invalid, so all $(($NinjaLicenseCreation | Measure-Object).count) license(s) in this batch were not written: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
14871487
}
14881488

14891489
try {
@@ -1494,7 +1494,8 @@ function Invoke-NinjaOneTenantSync {
14941494
Write-Information 'Completed Update'
14951495
}
14961496
} catch {
1497-
Write-Information "Bulk Update Errored, but may have been successful as only 1 record with an issue could have been the cause: $_"
1497+
$ErrorMessage = Get-CippException -Exception $_
1498+
Write-LogMessage -tenant $Customer.defaultDomainName -API 'NinjaOneSync' -message "NinjaOne license document update failed for $($Customer.displayName). NinjaOne rejects the whole batch if any single document is invalid, so all $(($NinjaLicenseUpdates | Measure-Object).count) license(s) in this batch were not written: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
14981499
}
14991500

15001501
[System.Collections.Generic.List[PSCustomObject]]$LicenseDocs = $CreatedLicenses + $UpdatedLicenses

0 commit comments

Comments
 (0)