diff --git a/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1 b/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1
index 7a8044bc1c5f..88fb8492350e 100644
--- a/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1
+++ b/Modules/CIPPCore/Public/GraphHelper/Get-NormalizedError.ps1
@@ -7,13 +7,42 @@ function Get-NormalizedError {
param (
[string]$message
)
+
+ #Check if the message is valid JSON.
+ try {
+ $JSONMsg = $message | ConvertFrom-Json
+ } catch {
+ }
+ #if the message is valid JSON, there can be multiple fields in which the error resides. These are:
+ # $message.error.Innererror.Message
+ # $message.error.Message
+ # $message.error.details.message
+ # $message.error.innererror.internalException.message
+
+ #We need to check if the message is in one of these fields, and if so, return it.
+ if ($JSONMsg.error.innererror.message) {
+ Write-Host 'innererror.message found'
+ $message = $JSONMsg.error.innererror.message
+ } elseif ($JSONMsg.error.message) {
+ Write-Host 'error.message found'
+ $message = $JSONMsg.error.message
+ } elseif ($JSONMsg.error.details.message) {
+ Write-Host 'error.details.message found'
+ $message = $JSONMsg.error.details.message
+ } elseif ($JSONMsg.error.innererror.internalException.message) {
+ Write-Host 'error.innererror.internalException.message found'
+ $message = $JSONMsg.error.innererror.internalException.message
+ }
+
+
+ #finally, put the message through the translator. If it's not in the list, just return the original message
switch -Wildcard ($message) {
'Request not applicable to target tenant.' { 'Required license not available for this tenant' }
"Neither tenant is B2C or tenant doesn't have premium license" { 'This feature requires a P1 license or higher' }
'Response status code does not indicate success: 400 (Bad Request).' { 'Error 400 occured. There is an issue with the token configuration for this tenant. Please perform an access check' }
'*Microsoft.Skype.Sync.Pstn.Tnm.Common.Http.HttpResponseException*' { 'Could not connect to Teams Admin center - Tenant might be missing a Teams license' }
'*Provide valid credential.*' { 'Error 400: There is an issue with your Exchange Token configuration. Please perform an access check for this tenant' }
- '*This indicate that a subscription within the tenant has lapsed*' { 'There is no exchange subscription available, or it has lapsed. Check licensing information.' }
+ '*This indicate that a subscription within the tenant has lapsed*' { 'There is subscription for this service available, Check licensing information.' }
'*User was not found.*' { 'The relationship between this tenant and the partner has been dissolved from the tenant side.' }
'*The user or administrator has not consented to use the application*' { 'CIPP cannot access this tenant. Perform a CPV Refresh and Access Check via the settings menu' }
'*AADSTS50020*' { 'AADSTS50020: The user you have used for your Secure Application Model is a guest in this tenant, or your are using GDAP and have not added the user to the correct group. Please delete the guest user to gain access to this tenant' }
diff --git a/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1 b/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1
index 6bf8bcf280f2..9236b7559fcf 100644
--- a/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1
+++ b/Modules/CIPPCore/Public/GraphHelper/New-GraphPOSTRequest.ps1
@@ -22,20 +22,15 @@ function New-GraphPOSTRequest ($uri, $tenantid, $body, $type, $scope, $AsApp, $N
try {
$ReturnedData = (Invoke-RestMethod -Uri $($uri) -Method $TYPE -Body $body -Headers $headers -ContentType $contentType)
} catch {
- $Message = ($_.ErrorDetails.Message | ConvertFrom-Json -ErrorAction SilentlyContinue).error
- if ($Message.innerError) { $Message = $Message.Innererror.Message } else { $Message = $Message.Message.Error }
- if ($Message -eq $null) {
- try {
- $Message = ($_.ErrorDetails.Message | ConvertFrom-Json -ErrorAction SilentlyContinue).message
- } catch {
- $Message = $($_.Exception.Message)
- }
+ $Message = if ($_.ErrorDetails.Message) {
+ Get-NormalizedError -Message $_.ErrorDetails.Message
+ } else {
+ $_.Exception.message
}
throw $Message
}
return $ReturnedData
} else {
Write-Error 'Not allowed. You cannot manage your own tenant or tenants not under your scope'
-
}
}
\ No newline at end of file
diff --git a/Modules/CippExtensions/NinjaOne/Get-NinjaOneOrgMapping.ps1 b/Modules/CippExtensions/NinjaOne/Get-NinjaOneOrgMapping.ps1
index 822ed28b42b4..8f9e3d89936b 100644
--- a/Modules/CippExtensions/NinjaOne/Get-NinjaOneOrgMapping.ps1
+++ b/Modules/CippExtensions/NinjaOne/Get-NinjaOneOrgMapping.ps1
@@ -24,7 +24,7 @@ function Get-NinjaOneOrgMapping {
$After = 0
$PageSize = 1000
$NinjaOrgs = do {
- $Result = (Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/organizations?pageSize=$PageSize&after=$After" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -depth 100
+ $Result = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organizations?pageSize=$PageSize&after=$After" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -Depth 100
$Result | Select-Object name, @{n = 'value'; e = { $_.id } }
$ResultCount = ($Result.id | Measure-Object -Maximum)
$After = $ResultCount.maximum
@@ -32,7 +32,13 @@ function Get-NinjaOneOrgMapping {
} while ($ResultCount.count -eq $PageSize)
} catch {
- $NinjaOrgs = @()
+ $Message = if ($_.ErrorDetails.Message) {
+ Get-NormalizedError -Message $_.ErrorDetails.Message
+ } else {
+ $_.Exception.message
+ }
+
+ $NinjaOrgs = @(@{ name = $Message })
}
$MappingObj = [PSCustomObject]@{
diff --git a/Modules/CippExtensions/NinjaOne/Get-NinjaOneToken.ps1 b/Modules/CippExtensions/NinjaOne/Get-NinjaOneToken.ps1
index 17ebad207a2d..0b1692148531 100644
--- a/Modules/CippExtensions/NinjaOne/Get-NinjaOneToken.ps1
+++ b/Modules/CippExtensions/NinjaOne/Get-NinjaOneToken.ps1
@@ -7,7 +7,7 @@ function Get-NinjaOneToken {
if (!$ENV:NinjaClientSecret) {
$null = Connect-AzAccount -Identity
- $ClientSecret = (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name "NinjaOne" -AsPlainText)
+ $ClientSecret = (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name 'NinjaOne' -AsPlainText)
} else {
$ClientSecret = $ENV:NinjaClientSecret
}
@@ -20,7 +20,17 @@ function Get-NinjaOneToken {
scope = 'monitoring management'
}
- $token = Invoke-RestMethod -Uri "https://$($Configuration.Instance -replace '/ws','')/ws/oauth/token" -Method Post -Body $body -ContentType 'application/x-www-form-urlencoded'
+ try {
+
+ $token = Invoke-RestMethod -Uri "https://$($Configuration.Instance -replace '/ws','')/ws/oauth/token" -Method Post -Body $body -ContentType 'application/x-www-form-urlencoded'
+ } catch {
+ $Message = if ($_.ErrorDetails.Message) {
+ Get-NormalizedError -Message $_.ErrorDetails.Message
+ } else {
+ $_.Exception.message
+ }
+ Write-LogMessage -Message $Message -sev error -API 'NinjaOne'
+ }
return $token
}
\ No newline at end of file
diff --git a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneDeviceWebhook.ps1 b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneDeviceWebhook.ps1
index 903cee63234c..a8363917efcc 100644
--- a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneDeviceWebhook.ps1
+++ b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneDeviceWebhook.ps1
@@ -5,7 +5,7 @@ function Invoke-NinjaOneDeviceWebhook {
$Configuration
)
try {
- Write-LogMessage -user $ExecutingUser -API $APIName -message "Webhook Recieved - Updating NinjaOne Device compliance for $($Data.resourceData.id) in $($Data.tenantId)" -Sev "Info" -tenant $TenantFilter
+ Write-LogMessage -user $ExecutingUser -API $APIName -message "Webhook Recieved - Updating NinjaOne Device compliance for $($Data.resourceData.id) in $($Data.tenantId)" -Sev 'Info' -tenant $TenantFilter
$MappedFields = [pscustomobject]@{}
$CIPPMapping = Get-CIPPTable -TableName CippMapping
$Filter = "PartitionKey eq 'NinjaFieldMapping'"
@@ -36,9 +36,9 @@ function Invoke-NinjaOneDeviceWebhook {
"$($MappedFields.DeviceCompliance)" = $Compliant
} | ConvertTo-Json
- $Null = Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/device/$($Device.NinjaOneID)/custom-fields" -Method PATCH -Body $ComplianceBody -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json'
+ $Null = Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/device/$($Device.NinjaOneID)/custom-fields" -Method PATCH -Body $ComplianceBody -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json'
- Write-Host "Updated NinjaOne Device Compliance"
+ Write-Host 'Updated NinjaOne Device Compliance'
} else {
@@ -48,8 +48,13 @@ function Invoke-NinjaOneDeviceWebhook {
}
} catch {
- Write-Error "Failed NinjaOne Device Webhook for: $($Data | ConvertTo-Json -depth 100) Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $($_.Exception.message)"
- Write-LogMessage -API 'NinjaOneSync' -user 'CIPP' -message "Failed NinjaOne Device Webhook Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $($_.Exception.message)" -Sev 'Error'
+ $Message = if ($_.ErrorDetails.Message) {
+ Get-NormalizedError -Message $_.ErrorDetails.Message
+ } else {
+ $_.Exception.message
+ }
+ Write-Error "Failed NinjaOne Device Webhook for: $($Data | ConvertTo-Json -Depth 100) Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $Message"
+ Write-LogMessage -API 'NinjaOneSync' -user 'CIPP' -message "Failed NinjaOne Device Webhook Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $Message" -Sev 'Error'
}
diff --git a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1 b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1
index 63e10c8043e9..05b4ecbcaaac 100644
--- a/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1
+++ b/Modules/CippExtensions/NinjaOne/Invoke-NinjaOneTenantSync.ps1
@@ -19,7 +19,7 @@ function Invoke-NinjaOneTenantSync {
$MappedTenant = $QueueItem.MappedTenant
# Check for active instances for this tenant
- $CurrentItem = $CurrentMap | where-object { $_.RowKey -eq $MappedTenant.RowKey }
+ $CurrentItem = $CurrentMap | Where-Object { $_.RowKey -eq $MappedTenant.RowKey }
$StartDate = try { Get-Date($CurrentItem.lastStartTime) } catch { $Null }
$EndDate = try { Get-Date($CurrentItem.lastEndTime) } catch { $Null }
@@ -30,10 +30,10 @@ function Invoke-NinjaOneTenantSync {
# Set Last Start Time
$MappingTable = Get-CIPPTable -TableName CippMapping
- $CurrentItem | Add-Member -NotePropertyName lastStartTime -NotePropertyValue ([string]$(($StartQueueTime).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"))) -Force
+ $CurrentItem | Add-Member -NotePropertyName lastStartTime -NotePropertyValue ([string]$(($StartQueueTime).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ'))) -Force
$CurrentItem | Add-Member -NotePropertyName lastStatus -NotePropertyValue 'Running' -Force
if ($Null -ne $CurrentItem.lastEndTime -and $CurrentItem.lastEndTime -ne '' ) {
- $CurrentItem.lastEndTime = ([string]$(($CurrentItem.lastEndTime).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ")))
+ $CurrentItem.lastEndTime = ([string]$(($CurrentItem.lastEndTime).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ')))
}
Add-CIPPAzDataTableEntity @MappingTable -Entity $CurrentItem -Force
@@ -44,7 +44,7 @@ function Invoke-NinjaOneTenantSync {
$CIPPUrl = ($NinjaSettings | Where-Object { $_.RowKey -eq 'CIPPURL' }).SettingValue
- $Customer = Get-Tenants | where-object { $_.customerId -eq $MappedTenant.RowKey }
+ $Customer = Get-Tenants | Where-Object { $_.customerId -eq $MappedTenant.RowKey }
Write-Host "Processing: $($Customer.displayName) - Queued for $((New-TimeSpan -Start $StartQueueTime -End $StartTime).TotalSeconds)"
Write-LogMessage -API 'NinjaOneSync' -user 'NinjaOneSync' -message "Processing NinjaOne Synchronization for $($Customer.displayName) - Queued for $((New-TimeSpan -Start $StartQueueTime -End $StartTime).TotalSeconds)" -Sev 'Info'
@@ -74,14 +74,14 @@ function Invoke-NinjaOneTenantSync {
$After = 0
$PageSize = 1000
$NinjaDevices = do {
- $Result = (Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/devices-detailed?pageSize=$PageSize&after=$After&df=org = $($NinjaOneOrg)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -depth 100
+ $Result = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/devices-detailed?pageSize=$PageSize&after=$After&df=org = $($NinjaOneOrg)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -Depth 100
$Result
$ResultCount = ($Result.id | Measure-Object -Maximum)
$After = $ResultCount.maximum
} while ($ResultCount.count -eq $PageSize)
- Write-Host "Fetched NinjaOne Devices"
+ Write-Host 'Fetched NinjaOne Devices'
[System.Collections.Generic.List[PSCustomObject]]$NinjaOneUserDocs = @()
@@ -170,7 +170,7 @@ function Invoke-NinjaOneTenantSync {
# Get NinjaOne Users
- [System.Collections.Generic.List[PSCustomObject]]$NinjaOneUserDocs = ((Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/organization/documents?organizationIds=$($NinjaOneOrg)&templateIds=$($NinjaOneUsersTemplate.id)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -depth 100)
+ [System.Collections.Generic.List[PSCustomObject]]$NinjaOneUserDocs = ((Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/documents?organizationIds=$($NinjaOneOrg)&templateIds=$($NinjaOneUsersTemplate.id)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -Depth 100)
foreach ($NinjaDoc in $NinjaOneUserDocs) {
$ParsedFields = [pscustomobject]@{}
@@ -185,7 +185,7 @@ function Invoke-NinjaOneTenantSync {
$NinjaDoc | Add-Member -NotePropertyName 'ParsedFields' -NotePropertyValue $ParsedFields -Force
}
- Write-Host "Fetched NinjaOne User Docs"
+ Write-Host 'Fetched NinjaOne User Docs'
}
[System.Collections.Generic.List[PSCustomObject]]$NinjaOneLicenseDocs = @()
@@ -240,7 +240,7 @@ function Invoke-NinjaOneTenantSync {
$NinjaOneLicenseTemplate = Invoke-NinjaOneDocumentTemplate -Template $LicenseDocTemplate -Token $Token
# Get NinjaOne Licenses
- [System.Collections.Generic.List[PSCustomObject]]$NinjaOneLicenseDocs = ((Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/organization/documents?organizationIds=$($NinjaOneOrg)&templateIds=$($NinjaOneLicenseTemplate.id)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -depth 100)
+ [System.Collections.Generic.List[PSCustomObject]]$NinjaOneLicenseDocs = ((Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/documents?organizationIds=$($NinjaOneOrg)&templateIds=$($NinjaOneLicenseTemplate.id)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -Depth 100)
foreach ($NinjaLic in $NinjaOneLicenseDocs) {
$ParsedFields = [pscustomobject]@{}
@@ -255,7 +255,7 @@ function Invoke-NinjaOneTenantSync {
$NinjaLic | Add-Member -NotePropertyName 'ParsedFields' -NotePropertyValue $ParsedFields -Force
}
- Write-Host "Fetched NinjaOne License Docs"
+ Write-Host 'Fetched NinjaOne License Docs'
}
@@ -334,14 +334,14 @@ function Invoke-NinjaOneTenantSync {
)
- write-verbose "$(Get-Date) - Fetching Bulk Data"
+ Write-Verbose "$(Get-Date) - Fetching Bulk Data"
try {
$TenantResults = New-GraphBulkRequest -Requests $TenantRequests -tenantid $TenantFilter -NoAuthCheck $True
} catch {
Throw "Failed to fetch bulk company data: $_"
}
- Write-Host "Fetched Bulk M365 Data"
+ Write-Host 'Fetched Bulk M365 Data'
$Users = Get-GraphBulkResultByID -value -Results $TenantResults -ID 'Users'
@@ -376,11 +376,11 @@ function Invoke-NinjaOneTenantSync {
$TenantDetails = Get-GraphBulkResultByID -value -Results $TenantResults -ID 'TenantDetails'
- write-verbose "$(Get-Date) - Parsing Users"
+ Write-Verbose "$(Get-Date) - Parsing Users"
# Grab licensed users
- $licensedUsers = $Users | where-object { $null -ne $_.AssignedLicenses.SkuId } | Sort-Object UserPrincipalName
+ $licensedUsers = $Users | Where-Object { $null -ne $_.AssignedLicenses.SkuId } | Sort-Object UserPrincipalName
- write-verbose "$(Get-Date) - Parsing Roles"
+ Write-Verbose "$(Get-Date) - Parsing Roles"
# Get All Roles
$AllRoles = Get-GraphBulkResultByID -value -Results $TenantResults -ID 'AllRoles'
@@ -401,13 +401,13 @@ function Invoke-NinjaOneTenantSync {
$MemberReturn = $null
}
- Write-Host "Fetched M365 Roles"
+ Write-Host 'Fetched M365 Roles'
$Roles = foreach ($Result in $MemberReturn) {
[PSCustomObject]@{
ID = $Result.id
- DisplayName = ($AllRoles | where-object { $_.id -eq $Result.id }).displayName
- Description = ($AllRoles | where-object { $_.id -eq $Result.id }).description
+ DisplayName = ($AllRoles | Where-Object { $_.id -eq $Result.id }).displayName
+ Description = ($AllRoles | Where-Object { $_.id -eq $Result.id }).description
Members = $Result.body.value
ParsedMembers = $Result.body.value.Displayname -join ', '
}
@@ -415,9 +415,9 @@ function Invoke-NinjaOneTenantSync {
- $AdminUsers = (($Roles | Where-Object { $_.Displayname -match "Administrator" }).Members | where-object { $null -ne $_.displayName })
+ $AdminUsers = (($Roles | Where-Object { $_.Displayname -match 'Administrator' }).Members | Where-Object { $null -ne $_.displayName })
- write-verbose "$(Get-Date) - Fetching Domains"
+ Write-Verbose "$(Get-Date) - Fetching Domains"
try {
$RawDomains = Get-GraphBulkResultByID -value -Results $TenantResults -ID 'RawDomains'
} catch {
@@ -426,20 +426,20 @@ function Invoke-NinjaOneTenantSync {
$customerDomains = ($RawDomains | Where-Object { $_.IsVerified -eq $True }).id -join ', ' | Out-String
- write-verbose "$(Get-Date) - Parsing Licenses"
+ Write-Verbose "$(Get-Date) - Parsing Licenses"
# Get Licenses
$Licenses = Get-GraphBulkResultByID -value -Results $TenantResults -ID 'Licenses'
# Get the license overview for the tenant
if ($Licenses) {
- $LicensesParsed = $Licenses | where-object { $_.PrepaidUnits.Enabled -gt 0 } | Select-Object @{N = 'License Name'; E = { (Get-Culture).TextInfo.ToTitleCase((convert-skuname -skuname $_.SkuPartNumber).Tolower()) } }, @{N = 'Active'; E = { $_.PrepaidUnits.Enabled } }, @{N = 'Consumed'; E = { $_.ConsumedUnits } }, @{N = 'Unused'; E = { $_.PrepaidUnits.Enabled - $_.ConsumedUnits } }
+ $LicensesParsed = $Licenses | Where-Object { $_.PrepaidUnits.Enabled -gt 0 } | Select-Object @{N = 'License Name'; E = { (Get-Culture).TextInfo.ToTitleCase((convert-skuname -skuname $_.SkuPartNumber).Tolower()) } }, @{N = 'Active'; E = { $_.PrepaidUnits.Enabled } }, @{N = 'Consumed'; E = { $_.ConsumedUnits } }, @{N = 'Unused'; E = { $_.PrepaidUnits.Enabled - $_.ConsumedUnits } }
}
- write-verbose "$(Get-Date) - Parsing Devices"
+ Write-Verbose "$(Get-Date) - Parsing Devices"
# Get all devices from Intune
$devices = Get-GraphBulkResultByID -value -Results $TenantResults -ID 'Devices'
- write-verbose "$(Get-Date) - Parsing Device Compliance Polcies"
+ Write-Verbose "$(Get-Date) - Parsing Device Compliance Polcies"
# Fetch Compliance Policy Status
$DeviceCompliancePolicies = Get-GraphBulkResultByID -value -Results $TenantResults -ID 'DeviceCompliancePolicies'
@@ -459,17 +459,17 @@ function Invoke-NinjaOneTenantSync {
$PolicyReturn = $null
}
- Write-Host "Fetched M365 Device Compliance"
+ Write-Host 'Fetched M365 Device Compliance'
$DeviceComplianceDetails = foreach ($Result in $PolicyReturn) {
[pscustomobject]@{
- ID = ($DeviceCompliancePolicies | where-object { $_.id -eq $Result.id }).id
- DisplayName = ($DeviceCompliancePolicies | where-object { $_.id -eq $Result.id }).DisplayName
+ ID = ($DeviceCompliancePolicies | Where-Object { $_.id -eq $Result.id }).id
+ DisplayName = ($DeviceCompliancePolicies | Where-Object { $_.id -eq $Result.id }).DisplayName
DeviceStatuses = $Result.body.value
}
}
- write-verbose "$(Get-Date) - Parsing Groups"
+ Write-Verbose "$(Get-Date) - Parsing Groups"
# Fetch Groups
$AllGroups = Get-GraphBulkResultByID -value -Results $TenantResults -ID 'Groups'
@@ -489,17 +489,17 @@ function Invoke-NinjaOneTenantSync {
$GroupMembersReturn = $null
}
- Write-Host "Fetched M365 Group Membership"
+ Write-Host 'Fetched M365 Group Membership'
$Groups = foreach ($Result in $GroupMembersReturn) {
[pscustomobject]@{
ID = $Result.id
- DisplayName = ($AllGroups | where-object { $_.id -eq $Result.id }).DisplayName
+ DisplayName = ($AllGroups | Where-Object { $_.id -eq $Result.id }).DisplayName
Members = $result.body.value
}
}
- write-verbose "$(Get-Date) - Parsing Conditional Access Polcies"
+ Write-Verbose "$(Get-Date) - Parsing Conditional Access Polcies"
# Fetch and parse conditional access polcies
$AllConditionalAccessPolcies = Get-GraphBulkResultByID -value -Results $TenantResults -ID 'ConditionalAccess'
@@ -509,43 +509,43 @@ function Invoke-NinjaOneTenantSync {
# Check for All Include
if ($CAPolicy.conditions.users.includeUsers -contains 'All') {
- $Users | foreach-object { $null = $CAMembers.add($_.id) }
+ $Users | ForEach-Object { $null = $CAMembers.add($_.id) }
} else {
# Add any specific all users to the array
- $CAPolicy.conditions.users.includeUsers | foreach-object { $null = $CAMembers.add($_) }
+ $CAPolicy.conditions.users.includeUsers | ForEach-Object { $null = $CAMembers.add($_) }
}
# Now all members of groups
foreach ($CAIGroup in $CAPolicy.conditions.users.includeGroups) {
- foreach ($Member in ($Groups | where-object { $_.id -eq $CAIGroup }).Members) {
+ foreach ($Member in ($Groups | Where-Object { $_.id -eq $CAIGroup }).Members) {
$null = $CAMembers.add($Member.id)
}
}
# Now all members of roles
foreach ($CAIRole in $CAPolicy.conditions.users.includeRoles) {
- foreach ($Member in ($Roles | where-object { $_.id -eq $CAIRole }).Members) {
+ foreach ($Member in ($Roles | Where-Object { $_.id -eq $CAIRole }).Members) {
$null = $CAMembers.add($Member.id)
}
}
# Parse to Unique members
- $CAMembers = $CAMembers | select-object -unique
+ $CAMembers = $CAMembers | Select-Object -Unique
if ($CAMembers) {
# Now remove excluded users
- $CAPolicy.conditions.users.excludeUsers | foreach-object { $null = $CAMembers.remove($_) }
+ $CAPolicy.conditions.users.excludeUsers | ForEach-Object { $null = $CAMembers.remove($_) }
# Excluded Groups
foreach ($CAEGroup in $CAPolicy.conditions.users.excludeGroups) {
- foreach ($Member in ($Groups | where-object { $_.id -eq $CAEGroup }).Members) {
+ foreach ($Member in ($Groups | Where-Object { $_.id -eq $CAEGroup }).Members) {
$null = $CAMembers.remove($Member.id)
}
}
# Excluded Roles
foreach ($CAIRole in $CAPolicy.conditions.users.excludeRoles) {
- foreach ($Member in ($Roles | where-object { $_.id -eq $CAERole }).Members) {
+ foreach ($Member in ($Roles | Where-Object { $_.id -eq $CAERole }).Members) {
$null = $CAMembers.remove($Member.id)
}
}
@@ -558,15 +558,15 @@ function Invoke-NinjaOneTenantSync {
}
}
- write-verbose "$(Get-Date) - Fetching One Drive Details"
+ Write-Verbose "$(Get-Date) - Fetching One Drive Details"
try {
- $OneDriveDetails = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/reports/getOneDriveUsageAccountDetail(period='D7')" -tenantid $TenantFilter | convertfrom-csv
+ $OneDriveDetails = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/reports/getOneDriveUsageAccountDetail(period='D7')" -tenantid $TenantFilter | ConvertFrom-Csv
} catch {
Write-Error "Failed to fetch Onedrive Details: $_"
$OneDriveDetails = $null
}
- write-verbose "$(Get-Date) - Fetching CAS Mailbox Details"
+ Write-Verbose "$(Get-Date) - Fetching CAS Mailbox Details"
try {
$CASFull = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($tenantfilter)/CasMailbox" -Tenantid $Customer.defaultDomainName -scope ExchangeOnline -noPagination $true
} catch {
@@ -574,7 +574,7 @@ function Invoke-NinjaOneTenantSync {
$CASFull = $null
}
- write-verbose "$(Get-Date) - Fetching Mailbox Details"
+ Write-Verbose "$(Get-Date) - Fetching Mailbox Details"
try {
$MailboxDetailedFull = New-ExoRequest -TenantID $Customer.defaultDomainName -cmdlet 'Get-Mailbox'
} catch {
@@ -582,7 +582,7 @@ function Invoke-NinjaOneTenantSync {
$MailboxDetailedFull = $null
}
- write-verbose "$(Get-Date) - Fetching Blocked Mailbox Details"
+ Write-Verbose "$(Get-Date) - Fetching Blocked Mailbox Details"
try {
$BlockedSenders = New-ExoRequest -TenantID $Customer.defaultDomainName -cmdlet 'Get-BlockedSenderAddress'
} catch {
@@ -590,15 +590,15 @@ function Invoke-NinjaOneTenantSync {
$BlockedSenders = $null
}
- write-verbose "$(Get-Date) - Fetching Mailbox Stats"
+ Write-Verbose "$(Get-Date) - Fetching Mailbox Stats"
try {
- $MailboxStatsFull = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/reports/getMailboxUsageDetail(period='D7')" -tenantid $TenantFilter | convertfrom-csv
+ $MailboxStatsFull = New-GraphGetRequest -uri "https://graph.microsoft.com/v1.0/reports/getMailboxUsageDetail(period='D7')" -tenantid $TenantFilter | ConvertFrom-Csv
} catch {
Write-Error "Failed to fetch Mailbox Stats: $_"
$MailboxStatsFull = $null
}
- Write-Host "Fetched M365 Additional Data"
+ Write-Host 'Fetched M365 Additional Data'
$FetchEnd = Get-Date
@@ -671,7 +671,7 @@ function Invoke-NinjaOneTenantSync {
id = $FoundUser.Id
name = $FoundUser.displayName
upn = $FoundUser.userPrincipalName
- lastlogin = ($DeviceUser.lastLogOnDateTime).ToString("yyyy-MM-dd")
+ lastlogin = ($DeviceUser.lastLogOnDateTime).ToString('yyyy-MM-dd')
}
)
}
@@ -741,7 +741,7 @@ function Invoke-NinjaOneTenantSync {
Add-CIPPAzDataTableEntity @DeviceTable -Entity @{
PartitionKey = $Customer.CustomerId
RowKey = $device.AzureADDeviceId
- RawDevice = "$($ParsedDevice | ConvertTo-Json -Depth 100 -compress)"
+ RawDevice = "$($ParsedDevice | ConvertTo-Json -Depth 100 -Compress)"
}
$ParsedDevices.add($ParsedDevice)
@@ -770,7 +770,7 @@ function Invoke-NinjaOneTenantSync {
- $DeviceLinksHTML = Get-NinjaOneLinks -Data $DeviceLinksData -SmallCols 2 -MedCols 3 -LargeCols 3 -XLCols 3
+ $DeviceLinksHTML = Get-NinjaOneLinks -Data $DeviceLinksData -SmallCols 2 -MedCols 3 -LargeCols 3 -XLCols 3
$DeviceLinksHtml = '
'
@@ -800,7 +800,7 @@ function Invoke-NinjaOneTenantSync {
'Management Type' = $Device.managementAgent
}
- $DeviceDetailsCard = Get-NinjaOneInfoCard -Title "Device Details" -Data $DeviceDetailsData -Icon 'fas fa-laptop'
+ $DeviceDetailsCard = Get-NinjaOneInfoCard -Title 'Device Details' -Data $DeviceDetailsData -Icon 'fas fa-laptop'
# Device Hardware
$DeviceHardwareData = [PSCustomObject]@{
@@ -812,7 +812,7 @@ function Invoke-NinjaOneTenantSync {
'Manufacturer' = $Device.manufacturer
}
- $DeviceHardwareCard = Get-NinjaOneInfoCard -Title "Device Details" -Data $DeviceHardwareData -Icon 'fas fa-microchip'
+ $DeviceHardwareCard = Get-NinjaOneInfoCard -Title 'Device Details' -Data $DeviceHardwareData -Icon 'fas fa-microchip'
# Device Enrollment
$DeviceEnrollmentData = [PSCustomObject]@{
@@ -825,7 +825,7 @@ function Invoke-NinjaOneTenantSync {
'Credential Guard' = $Device.hardwareinformation.deviceGuardLocalSystemAuthorityCredentialGuardState
}
- $DeviceEnrollmentCard = Get-NinjaOneInfoCard -Title "Device Enrollment" -Data $DeviceEnrollmentData -Icon 'fas fa-table-list'
+ $DeviceEnrollmentCard = Get-NinjaOneInfoCard -Title 'Device Enrollment' -Data $DeviceEnrollmentData -Icon 'fas fa-table-list'
# Compliance Policies
@@ -870,7 +870,7 @@ function Invoke-NinjaOneTenantSync {
# Update Device
if ($MappedFields.DeviceSummary -or $MappedFields.DeviceLinks -or $MappedFields.DeviceCompliance) {
- $Result = Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/device/$($MatchedNinjaDevice.id)/custom-fields" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ($NinjaDeviceUpdate | ConvertTo-Json -Depth 100)
+ $Result = Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/device/$($MatchedNinjaDevice.id)/custom-fields" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ($NinjaDeviceUpdate | ConvertTo-Json -Depth 100)
}
}
@@ -879,7 +879,7 @@ function Invoke-NinjaOneTenantSync {
New-CIPPGraphSubscription -TenantFilter $TenantFilter -TypeofSubscription 'updated' -BaseURL $CIPPUrl -Resource 'devices' -EventType 'DeviceUpdate' -ExecutingUser 'NinjaOneSync'
}
- Write-Host "Processed Devices"
+ Write-Host 'Processed Devices'
########## Create / Update User Objects
@@ -923,12 +923,12 @@ function Invoke-NinjaOneTenantSync {
}
- foreach ($user in $SyncUsers | where-object { $_.id -notin $ParsedUsers.RowKey }) {
+ foreach ($user in $SyncUsers | Where-Object { $_.id -notin $ParsedUsers.RowKey }) {
try {
$NinjaOneUser = $NinjaOneUserDocs | Where-Object { $_.ParsedFields.cippUserID -eq $User.ID }
- if (($NinjaOneUser | Measure-Object).count -gt 1) {
- Throw "Multiple Users with the same ID found"
+ if (($NinjaOneUser | Measure-Object).count -gt 1) {
+ Throw 'Multiple Users with the same ID found'
}
@@ -1005,16 +1005,16 @@ function Invoke-NinjaOneTenantSync {
}
- $UserDevicesDetailsRaw = $ParsedDevices | where-object { $User.id -in $_.UserIDS }
+ $UserDevicesDetailsRaw = $ParsedDevices | Where-Object { $User.id -in $_.UserIDS }
- $UserDevices = foreach ($UserDevice in $ParsedDevices | where-object { $User.id -in $_.UserIDS }) {
+ $UserDevices = foreach ($UserDevice in $ParsedDevices | Where-Object { $User.id -in $_.UserIDS }) {
$MatchedNinjaDevice = $UserDevice.NinjaDevice
$ParsedDeviceName = $UserDevice.DeviceLink
# Set Last Login Time
- $LastLoginTime = ($UserDevice.UserDetails | where-object { $_.id -eq $User.id }).lastLogin
+ $LastLoginTime = ($UserDevice.UserDetails | Where-Object { $_.id -eq $User.id }).lastLogin
if (!$LastLoginTime) {
$LastLoginTime = 'Unknown'
}
@@ -1052,7 +1052,7 @@ function Invoke-NinjaOneTenantSync {
- $UserOneDriveStats = $OneDriveDetails | where-object { $_.'Owner Principal Name' -eq $User.userPrincipalName } | Select-Object -First 1
+ $UserOneDriveStats = $OneDriveDetails | Where-Object { $_.'Owner Principal Name' -eq $User.userPrincipalName } | Select-Object -First 1
$UserOneDriveUse = $UserOneDriveStats.'Storage Used (Byte)' / 1GB
$UserOneDriveTotal = $UserOneDriveStats.'Storage Allocated (Byte)' / 1GB
@@ -1105,7 +1105,7 @@ function Invoke-NinjaOneTenantSync {
}
- $UserMailboxStats = $MailboxStatsFull | where-object { $_.'User Principal Name' -eq $User.userPrincipalName } | Select-Object -First 1
+ $UserMailboxStats = $MailboxStatsFull | Where-Object { $_.'User Principal Name' -eq $User.userPrincipalName } | Select-Object -First 1
$UserMailUse = $UserMailboxStats.'Storage Used (Byte)' / 1GB
$UserMailTotal = $UserMailboxStats.'Prohibit Send/Receive Quota (Byte)' / 1GB
@@ -1278,11 +1278,11 @@ function Invoke-NinjaOneTenantSync {
# UsersSummaryCards:
- $UserOverviewCardHTML = Get-NinjaOneInfoCard -Title "User Details" -Data $UserOverviewCard -Icon 'fas fa-user'
- $MailboxDetailsCardHTML = Get-NinjaOneInfoCard -Title "Mailbox Details" -Data $MailboxDetailsCardData -Icon 'fas fa-envelope'
- $MailboxSettingsCardHTML = Get-NinjaOneInfoCard -Title "Mailbox Settings" -Data $MailboxSettingsCard -Icon 'fas fa-envelope'
- $OneDriveCardHTML = Get-NinjaOneInfoCard -Title "OneDrive Details" -Data $OneDriveCardData -Icon 'fas fa-envelope'
- $UserPolciesCard = Get-NinjaOneCard -Title "Assigned Conditional Access Policies" -Body $UserPoliciesFormatted
+ $UserOverviewCardHTML = Get-NinjaOneInfoCard -Title 'User Details' -Data $UserOverviewCard -Icon 'fas fa-user'
+ $MailboxDetailsCardHTML = Get-NinjaOneInfoCard -Title 'Mailbox Details' -Data $MailboxDetailsCardData -Icon 'fas fa-envelope'
+ $MailboxSettingsCardHTML = Get-NinjaOneInfoCard -Title 'Mailbox Settings' -Data $MailboxSettingsCard -Icon 'fas fa-envelope'
+ $OneDriveCardHTML = Get-NinjaOneInfoCard -Title 'OneDrive Details' -Data $OneDriveCardData -Icon 'fas fa-envelope'
+ $UserPolciesCard = Get-NinjaOneCard -Title 'Assigned Conditional Access Policies' -Body $UserPoliciesFormatted
$UserSummaryHTML = '' +
@@ -1311,7 +1311,7 @@ function Invoke-NinjaOneTenantSync {
$UserFields = @{
cippUserLinks = @{'html' = $UserLinksHTML }
cippUserSummary = @{'html' = $UserSummaryHTML }
- cippUserGroups = @{'html' = "$($UserGroups | ConvertTo-HTML -As Table -Fragment)" }
+ cippUserGroups = @{'html' = "$($UserGroups | ConvertTo-Html -As Table -Fragment)" }
cippUserDevices = @{'html' = $UserDeviceDetailHTML }
cippUserID = $User.id
cippUserUPN = $User.userPrincipalName
@@ -1355,8 +1355,8 @@ function Invoke-NinjaOneTenantSync {
try {
# Create New Users
if (($NinjaUserCreation | Measure-Object).count -ge 100) {
- Write-Host "Creating NinjaOne Users"
- [System.Collections.Generic.List[PSCustomObject]]$CreatedUsers = (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 ("[$($NinjaUserCreation.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100
+ Write-Host 'Creating NinjaOne Users'
+ [System.Collections.Generic.List[PSCustomObject]]$CreatedUsers = (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 ("[$($NinjaUserCreation.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100
Remove-AzDataTableEntity @UsersUpdateTable -Entity $NinjaUserCreation
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserCreation = @()
}
@@ -1367,8 +1367,8 @@ function Invoke-NinjaOneTenantSync {
try {
# Update Users
if (($NinjaUserUpdates | Measure-Object).count -ge 100) {
- Write-Host "Updating NinjaOne Users"
- [System.Collections.Generic.List[PSCustomObject]]$UpdatedUsers = (Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ("[$($NinjaUserUpdates.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100
+ Write-Host 'Updating NinjaOne Users'
+ [System.Collections.Generic.List[PSCustomObject]]$UpdatedUsers = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ("[$($NinjaUserUpdates.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100
Remove-AzDataTableEntity @UsersUpdateTable -Entity $NinjaUserUpdates
[System.Collections.Generic.List[PSCustomObject]]$NinjaUserUpdates = @()
}
@@ -1406,7 +1406,7 @@ function Invoke-NinjaOneTenantSync {
Add-CIPPAzDataTableEntity @UsersMapTable -Entity $MappedUser -Force
}
} else {
- Write-Error "Unmatched Doc: $($UserDoc | convertto-json -depth 100)"
+ Write-Error "Unmatched Doc: $($UserDoc | ConvertTo-Json -Depth 100)"
}
}
@@ -1430,8 +1430,8 @@ function Invoke-NinjaOneTenantSync {
try {
# Create New Users
if (($NinjaUserCreation | Measure-Object).count -ge 1) {
- Write-Host "Creating NinjaOne Users"
- [System.Collections.Generic.List[PSCustomObject]]$CreatedUsers = (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 ("[$($NinjaUserCreation.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100
+ Write-Host 'Creating NinjaOne Users'
+ [System.Collections.Generic.List[PSCustomObject]]$CreatedUsers = (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 ("[$($NinjaUserCreation.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100
Remove-AzDataTableEntity @UsersUpdateTable -Entity $NinjaUserCreation
}
@@ -1442,8 +1442,8 @@ function Invoke-NinjaOneTenantSync {
try {
# Update Users
if (($NinjaUserUpdates | Measure-Object).count -ge 1) {
- Write-Host "Updating NinjaOne Users"
- [System.Collections.Generic.List[PSCustomObject]]$UpdatedUsers = (Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ("[$($NinjaUserUpdates.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100
+ Write-Host 'Updating NinjaOne Users'
+ [System.Collections.Generic.List[PSCustomObject]]$UpdatedUsers = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ("[$($NinjaUserUpdates.body -join ',')]") -EA Stop).content | ConvertFrom-Json -Depth 100
Remove-AzDataTableEntity @UsersUpdateTable -Entity $NinjaUserUpdates
}
} Catch {
@@ -1483,7 +1483,7 @@ function Invoke-NinjaOneTenantSync {
Add-CIPPAzDataTableEntity @UsersMapTable -Entity $MappedUser -Force
}
} else {
- Write-Error "Unmatched Doc: $($UserDoc | convertto-json -depth 100)"
+ Write-Error "Unmatched Doc: $($UserDoc | ConvertTo-Json -Depth 100)"
}
}
@@ -1492,7 +1492,7 @@ function Invoke-NinjaOneTenantSync {
# Relate Users to Devices
Foreach ($LinkDevice in $ParsedDevices | Where-Object { $null -ne $_.NinjaDevice }) {
- $RelatedItems = (Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/related-items/with-entity/NODE/$($LinkDevice.NinjaDevice.id)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -depth 100
+ $RelatedItems = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/related-items/with-entity/NODE/$($LinkDevice.NinjaDevice.id)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -Depth 100
[System.Collections.Generic.List[PSCustomObject]]$Relations = @()
Foreach ($LinkUser in $LinkDevice.UserIDs) {
$MatchedUser = $UsersMap | Where-Object { $_.M365ID -eq $LinkUser }
@@ -1501,7 +1501,7 @@ function Invoke-NinjaOneTenantSync {
if (!$ExistingRelation) {
$Relations.Add(
[PSCustomObject]@{
- relEntityType = "DOCUMENT"
+ relEntityType = 'DOCUMENT'
relEntityId = $MatchedUser.NinjaOneID
}
)
@@ -1514,9 +1514,9 @@ function Invoke-NinjaOneTenantSync {
try {
# Update Relations
if (($Relations | Measure-Object).count -ge 1) {
- Write-Host "Updating Relations"
- $Null = Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/related-items/entity/NODE/$($LinkDevice.NinjaDevice.id)/relations" -Method POST -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json' -Body ($Relations | ConvertTo-Json -Depth 100 -AsArray) -EA Stop
- Write-Host "Completed Update"
+ Write-Host 'Updating Relations'
+ $Null = Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/related-items/entity/NODE/$($LinkDevice.NinjaDevice.id)/relations" -Method POST -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json' -Body ($Relations | ConvertTo-Json -Depth 100 -AsArray) -EA Stop
+ Write-Host 'Completed Update'
}
} Catch {
Write-Host "Creating Relations Failed: $_"
@@ -1565,7 +1565,7 @@ function Invoke-NinjaOneTenantSync {
'Tenant Total' = $License.prepaidUnits.enabled
'SKU ID' = $License.skuId
}
- $LicenseOverviewCardHTML = Get-NinjaOneInfoCard -Title "License Details" -Data $LicenseSummary -Icon 'fas fa-file-invoice'
+ $LicenseOverviewCardHTML = Get-NinjaOneInfoCard -Title 'License Details' -Data $LicenseSummary -Icon 'fas fa-file-invoice'
$SubscriptionsHTML = $MatchedSubscriptions | Select-Object @{'n' = 'Subscription Licenses'; 'e' = { $_.totalLicenses } },
@{'n' = 'Created'; 'e' = { $_.createdDateTime } },
@@ -1574,7 +1574,7 @@ function Invoke-NinjaOneTenantSync {
@{'n' = 'Status'; 'e' = { $_.Status } } | ConvertTo-Html -As Table -Fragment
$SubscriptionsHTML = ([System.Web.HttpUtility]::HtmlDecode($SubscriptionsHTML) -replace '
', ' | ') -replace ' | ', ' | '
- $SubscriptionCardHTML = Get-NinjaOneCard -Title "Subscriptions" -Body $SubscriptionsHTML -Icon 'fas fa-file-invoice'
+ $SubscriptionCardHTML = Get-NinjaOneCard -Title 'Subscriptions' -Body $SubscriptionsHTML -Icon 'fas fa-file-invoice'
$LicenseItemsTable = $License.servicePlans | Select-Object @{n = 'Plan Name'; e = { convert-skuname -skuname $_.servicePlanName } }, @{n = 'Applies To'; e = { $_.appliesTo } }, @{n = 'Provisioning Status'; e = { $_.provisioningStatus } }
@@ -1626,8 +1626,8 @@ function Invoke-NinjaOneTenantSync {
try {
# Create New Subscriptions
if (($NinjaLicenseCreation | Measure-Object).count -ge 1) {
- Write-Host "Creating NinjaOne Licenses"
- [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
+ Write-Host 'Creating NinjaOne Licenses'
+ [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
}
} Catch {
Write-Host "Bulk Creation Error, but may have been successful as only 1 record with an issue could have been the cause: $_"
@@ -1636,9 +1636,9 @@ function Invoke-NinjaOneTenantSync {
try {
# Update Subscriptions
if (($NinjaLicenseUpdates | Measure-Object).count -ge 1) {
- Write-Host "Updating NinjaOne Licenses"
- [System.Collections.Generic.List[PSCustomObject]]$UpdatedLicenses = (Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ($NinjaLicenseUpdates | ConvertTo-Json -Depth 100 -AsArray) -EA Stop).content | ConvertFrom-Json -Depth 100
- Write-Host "Completed Update"
+ Write-Host 'Updating NinjaOne Licenses'
+ [System.Collections.Generic.List[PSCustomObject]]$UpdatedLicenses = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/documents" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ($NinjaLicenseUpdates | ConvertTo-Json -Depth 100 -AsArray) -EA Stop).content | ConvertFrom-Json -Depth 100
+ Write-Host 'Completed Update'
}
} Catch {
Write-Host "Bulk Update Errored, but may have been successful as only 1 record with an issue could have been the cause: $_"
@@ -1652,14 +1652,14 @@ function Invoke-NinjaOneTenantSync {
$MatchedLicDoc = $LicenseDocs | Where-Object { $_.documentName -eq $LinkLic.name }
if (($MatchedLicDoc | Measure-Object).count -eq 1) {
# Remove existing relations
- $RelatedItems = (Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/related-items/with-entity/DOCUMENT/$($MatchedLicDoc.documentId)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -depth 100
+ $RelatedItems = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/related-items/with-entity/DOCUMENT/$($MatchedLicDoc.documentId)" -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -Depth 100
[System.Collections.Generic.List[PSCustomObject]]$Relations = @()
Foreach ($LinkUser in $LinkLic.Users) {
$ExistingRelation = $RelatedItems | Where-Object { $_.relEntityType -eq 'DOCUMENT' -and $_.relEntityId -eq $LinkUser }
if (!$ExistingRelation) {
$Relations.Add(
[PSCustomObject]@{
- relEntityType = "DOCUMENT"
+ relEntityType = 'DOCUMENT'
relEntityId = $LinkUser
}
)
@@ -1670,9 +1670,9 @@ function Invoke-NinjaOneTenantSync {
try {
# Update Relations
if (($Relations | Measure-Object).count -ge 1) {
- Write-Host "Updating Relations"
- $Null = Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/related-items/entity/DOCUMENT/$($($MatchedLicDoc.documentId))/relations" -Method POST -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json' -Body ($Relations | ConvertTo-Json -Depth 100 -AsArray) -EA Stop
- Write-Host "Completed Update"
+ Write-Host 'Updating Relations'
+ $Null = Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/related-items/entity/DOCUMENT/$($($MatchedLicDoc.documentId))/relations" -Method POST -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json' -Body ($Relations | ConvertTo-Json -Depth 100 -AsArray) -EA Stop
+ Write-Host 'Completed Update'
}
} Catch {
Write-Host "Creating Relations Failed: $_"
@@ -1681,7 +1681,7 @@ function Invoke-NinjaOneTenantSync {
#Remove relations
foreach ($DelUser in $RelatedItems | Where-Object { $_.relEntityType -eq 'DOCUMENT' -and $_.relEntityId -notin $LinkLic.Users }) {
try {
- $RelatedItems = (Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/related-items/$($DelUser.id)" -Method Delete -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -depth 100
+ $RelatedItems = (Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/related-items/$($DelUser.id)" -Method Delete -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json').content | ConvertFrom-Json -Depth 100
} catch {
Write-Host "Failed to remove relation $($DelUser.id) from $($LinkLic.name)"
}
@@ -1698,7 +1698,7 @@ function Invoke-NinjaOneTenantSync {
### M365 Links Section
if ($MappedFields.TenantLinks) {
- Write-Host "Tenant Links"
+ Write-Host 'Tenant Links'
$ManagementLinksData = @(
@{
@@ -1800,12 +1800,12 @@ function Invoke-NinjaOneTenantSync {
if ($MappedFields.TenantSummary) {
- Write-Host "Tenant Summary"
+ Write-Host 'Tenant Summary'
### Tenant Overview Card
$ParsedAdmins = [PSCustomObject]@{}
- $AdminUsers | Select-Object displayname, userPrincipalName -unique | ForEach-Object {
+ $AdminUsers | Select-Object displayname, userPrincipalName -Unique | ForEach-Object {
$ParsedAdmins | Add-Member -NotePropertyName $_.displayname -NotePropertyValue $_.userPrincipalName
}
@@ -1819,15 +1819,15 @@ function Invoke-NinjaOneTenantSync {
}
- $TenantSummaryCard = Get-NinjaOneInfoCard -Title "Tenant Details" -Data $TenantDetailsItems -Icon 'fas fa-building'
+ $TenantSummaryCard = Get-NinjaOneInfoCard -Title 'Tenant Details' -Data $TenantDetailsItems -Icon 'fas fa-building'
### Users details card
- Write-Host "User Details"
- $TotalUsersCount = ($Users | measure-object).count
- $GuestUsersCount = ($Users | where-object { $_.UserType -eq 'Guest' } | measure-object).count
- $LicensedUsersCount = ($licensedUsers | measure-object).count
+ Write-Host 'User Details'
+ $TotalUsersCount = ($Users | Measure-Object).count
+ $GuestUsersCount = ($Users | Where-Object { $_.UserType -eq 'Guest' } | Measure-Object).count
+ $LicensedUsersCount = ($licensedUsers | Measure-Object).count
$UnlicensedUsersCount = $TotalUsersCount - $GuestUsersCount - $LicensedUsersCount
- $UsersEnabledCount = ($Users | where-object { $_.accountEnabled -eq $True } | Measure-Object).count
+ $UsersEnabledCount = ($Users | Where-Object { $_.accountEnabled -eq $True } | Measure-Object).count
# Enabled Users
@@ -1845,7 +1845,7 @@ function Invoke-NinjaOneTenantSync {
)
- $UsersEnabledChartHTML = Get-NinjaInLineBarGraph -Title "User Status" -Data $Data -KeyInLine
+ $UsersEnabledChartHTML = Get-NinjaInLineBarGraph -Title 'User Status' -Data $Data -KeyInLine
# User Types
@@ -1867,7 +1867,7 @@ function Invoke-NinjaOneTenantSync {
}
)
- $UsersTypesChartHTML = Get-NinjaInLineBarGraph -Title "User Types" -Data $Data -KeyInLine
+ $UsersTypesChartHTML = Get-NinjaInLineBarGraph -Title 'User Types' -Data $Data -KeyInLine
# Create the Users Card
@@ -1880,7 +1880,7 @@ function Invoke-NinjaOneTenantSync {
### Device Details Card
- Write-Host "Device Details"
+ Write-Host 'Device Details'
$TotalDeviceswCount = ($Devices | Measure-Object).count
$ComplianceDevicesCount = ($Devices | Where-Object { $_.complianceState -eq 'compliant' } | Measure-Object).count
$WindowsCount = ($Devices | Where-Object { $_.operatingSystem -eq 'Windows' } | Measure-Object).count
@@ -1905,7 +1905,7 @@ function Invoke-NinjaOneTenantSync {
)
- $DeviceComplianceChartHTML = Get-NinjaInLineBarGraph -Title "Device Compliance" -Data $Data -KeyInLine
+ $DeviceComplianceChartHTML = Get-NinjaInLineBarGraph -Title 'Device Compliance' -Data $Data -KeyInLine
# Device OS Types
@@ -1932,7 +1932,7 @@ function Invoke-NinjaOneTenantSync {
}
)
- $DeviceOsChartHTML = Get-NinjaInLineBarGraph -Title "Device Operating Systems" -Data $Data -KeyInLine
+ $DeviceOsChartHTML = Get-NinjaInLineBarGraph -Title 'Device Operating Systems' -Data $Data -KeyInLine
# Last online time
@@ -1949,7 +1949,7 @@ function Invoke-NinjaOneTenantSync {
}
)
- $DeviceOnlineChartHTML = Get-NinjaInLineBarGraph -Title "Devices Online in the last 30 days" -Data $Data -KeyInLine
+ $DeviceOnlineChartHTML = Get-NinjaInLineBarGraph -Title 'Devices Online in the last 30 days' -Data $Data -KeyInLine
# Create the Devices Card
@@ -1960,7 +1960,7 @@ function Invoke-NinjaOneTenantSync {
$DeviceSummaryCardHTML = Get-NinjaOneCard -Title 'Device Details' -Body $DeviceCardBodyHTML -Icon 'fas fa-network-wired' -TitleLink $TitleLink
#### Secure Score Card
- Write-Host "Secure Score Details"
+ Write-Host 'Secure Score Details'
$Top5Actions = ($SecureScoreParsed | Where-Object { $_.scoreInPercentage -ne 100 } | Sort-Object 'Score Impact', adjustedRank -Descending) | Select-Object -First 5
# Score Chart
@@ -1991,7 +1991,7 @@ function Invoke-NinjaOneTenantSync {
### CIPP Applied Standards Cards
- Write-Host "Applied Standards"
+ Write-Host 'Applied Standards'
Set-Location (Get-Item $PSScriptRoot).Parent.Parent.Parent.FullName
$StandardsDefinitions = Get-Content 'config/standards.json' | ConvertFrom-Json -Depth 100
@@ -2005,10 +2005,10 @@ function Invoke-NinjaOneTenantSync {
$ParsedStandards = foreach ($Standard in $AppliedStandards) {
[PSCustomObject]$Standards = $Standard.Standards
- $Standards.PSObject.Properties | foreach-object {
+ $Standards.PSObject.Properties | ForEach-Object {
$CheckValue = $_
if ($CheckValue.value) {
- $MatchedStandard = $StandardsDefinitions | where-object { ($_.name -split 'standards.')[1] -eq $CheckValue.name }
+ $MatchedStandard = $StandardsDefinitions | Where-Object { ($_.name -split 'standards.')[1] -eq $CheckValue.name }
if (($MatchedStandard | Measure-Object).count -eq 1) {
'' + $($MatchedStandard.label) + ' (' + ($($Standard.Tenant)) + ')'
}
@@ -2024,8 +2024,8 @@ function Invoke-NinjaOneTenantSync {
$CIPPStandardsSummaryCardHTML = Get-NinjaOneCard -Title 'CIPP Applied Standards' -Body $CIPPStandardsBodyHTML -Icon 'fas fa-shield-halved' -TitleLink $TitleLink
### License Card
- Write-Host "License Details"
- $LicenseTableHTML = $LicensesParsed | Sort-Object 'License Name' | ConvertTo-HTML -As Table -Fragment
+ Write-Host 'License Details'
+ $LicenseTableHTML = $LicensesParsed | Sort-Object 'License Name' | ConvertTo-Html -As Table -Fragment
$LicenseTableHTML = '' + (([System.Web.HttpUtility]::HtmlDecode($LicenseTableHTML) -replace ' ', ' | ') -replace ' | ', ' | ') + ''
$TitleLink = "https://$CIPPUrl/tenant/administration/list-licenses?customerId=$($Customer.customerId)"
@@ -2033,7 +2033,7 @@ function Invoke-NinjaOneTenantSync {
### Summary Stats
- Write-Host "Widget Details"
+ Write-Host 'Widget Details'
[System.Collections.Generic.List[PSCustomObject]]$WidgetData = @()
@@ -2062,7 +2062,7 @@ function Invoke-NinjaOneTenantSync {
# Unused Licenses
$WidgetData.add([PSCustomObject]@{
Value = $(
- $BPAUnusedLicenses = (($BpaData.Unusedlicenses | ConvertFrom-Json).availableUnits | Measure-Object -sum).sum
+ $BPAUnusedLicenses = (($BpaData.Unusedlicenses | ConvertFrom-Json).availableUnits | Measure-Object -Sum).sum
if ($BPAUnusedLicenses -ne 0) {
$ResultColour = '#D53948'
} else {
@@ -2219,7 +2219,7 @@ function Invoke-NinjaOneTenantSync {
# Create the Tenant Summary Field
- Write-Host "Complete Tenant Summary"
+ Write-Host 'Complete Tenant Summary'
$TenantSummaryHTML = ' ' + $SummaryDetailsCardHTML + ' ' +
'' +
' ' + $TenantSummaryCard +
@@ -2237,9 +2237,9 @@ function Invoke-NinjaOneTenantSync {
}
if ($MappedFields.UsersSummary) {
- Write-Host "User Details Section"
+ Write-Host 'User Details Section'
- $UsersTableFornatted = $ParsedUsers | sort-object name | Select-Object -First 100 Name,
+ $UsersTableFornatted = $ParsedUsers | Sort-Object name | Select-Object -First 100 Name,
@{n = 'User Principal Name'; e = { $_.UPN } },
#Aliases,
Licenses,
@@ -2249,7 +2249,7 @@ function Invoke-NinjaOneTenantSync {
Actions
- $UsersTableHTML = $UsersTableFornatted | ConvertTo-HTML -As Table -Fragment
+ $UsersTableHTML = $UsersTableFornatted | ConvertTo-Html -As Table -Fragment
$UsersTableHTML = ([System.Web.HttpUtility]::HtmlDecode($UsersTableHTML) -replace ' ', ' | ') -replace ' | ', ' | '
@@ -2275,20 +2275,20 @@ function Invoke-NinjaOneTenantSync {
- Write-Host "Posting Details"
+ Write-Host 'Posting Details'
$Token = Get-NinjaOneToken -configuration $Configuration
Write-Host "Ninja Body: $($NinjaOrgUpdate | ConvertTo-Json -Depth 100)"
- $Result = Invoke-WebRequest -uri "https://$($Configuration.Instance)/api/v2/organization/$($MappedTenant.NinjaOne)/custom-fields" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ($NinjaOrgUpdate | ConvertTo-Json -Depth 100)
+ $Result = Invoke-WebRequest -Uri "https://$($Configuration.Instance)/api/v2/organization/$($MappedTenant.NinjaOne)/custom-fields" -Method PATCH -Headers @{Authorization = "Bearer $($token.access_token)" } -ContentType 'application/json; charset=utf-8' -Body ($NinjaOrgUpdate | ConvertTo-Json -Depth 100)
- Write-Host "Cleaning Users Cache"
+ Write-Host 'Cleaning Users Cache'
if (($ParsedUsers | Measure-Object).count -gt 0) {
Remove-AzDataTableEntity @UsersTable -Entity ($ParsedUsers | Select-Object PartitionKey, RowKey)
}
- Write-Host "Cleaning Device Cache"
+ Write-Host 'Cleaning Device Cache'
if (($ParsedDevices | Measure-Object).count -gt 0) {
Remove-AzDataTableEntity @DeviceTable -Entity ($ParsedDevices | Select-Object PartitionKey, RowKey)
}
@@ -2297,16 +2297,20 @@ function Invoke-NinjaOneTenantSync {
Write-Host "Completed Total Time: $((New-TimeSpan -Start $StartTime -End (Get-Date)).TotalSeconds)"
# Set Last End Time
- $CurrentItem | Add-Member -NotePropertyName lastEndTime -NotePropertyValue ([string]$((Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"))) -Force
+ $CurrentItem | Add-Member -NotePropertyName lastEndTime -NotePropertyValue ([string]$((Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ'))) -Force
$CurrentItem | Add-Member -NotePropertyName lastStatus -NotePropertyValue 'Completed' -Force
Add-CIPPAzDataTableEntity @MappingTable -Entity $CurrentItem -Force
Write-LogMessage -API 'NinjaOneSync' -user 'NinjaOneSync' -message "Completed NinjaOne Sync for $($Customer.displayName). Queued for $((New-TimeSpan -Start $StartQueueTime -End $StartTime).TotalSeconds) seconds. Data fetched in $((New-TimeSpan -Start $StartTime -End $FetchEnd).TotalSeconds) seconds. Total processing time $((New-TimeSpan -Start $StartTime -End (Get-Date)).TotalSeconds) seconds" -Sev 'info'
} catch {
- Write-Error "Failed NinjaOne Processing for $($Customer.displayName) Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $($_.Exception.message)"
- Write-LogMessage -API 'NinjaOneSync' -user 'NinjaOneSync' -message "Failed NinjaOne Processing for $($Customer.displayName) Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $($_.Exception.message)" -Sev 'Error'
- $CurrentItem | Add-Member -NotePropertyName lastEndTime -NotePropertyValue ([string]$((Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"))) -Force
+ $Message = if ($_.ErrorDetails.Message) {
+ Get-NormalizedError -Message $_.ErrorDetails.Message
+ } else {
+ $_.Exception.message
+ } Write-Error "Failed NinjaOne Processing for $($Customer.displayName) Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $Message"
+ Write-LogMessage -API 'NinjaOneSync' -user 'NinjaOneSync' -message "Failed NinjaOne Processing for $($Customer.displayName) Linenumber: $($_.InvocationInfo.ScriptLineNumber) Error: $Message" -Sev 'Error'
+ $CurrentItem | Add-Member -NotePropertyName lastEndTime -NotePropertyValue ([string]$((Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ'))) -Force
$CurrentItem | Add-Member -NotePropertyName lastStatus -NotePropertyValue 'Failed' -Force
Add-CIPPAzDataTableEntity @MappingTable -Entity $CurrentItem -Force
}
diff --git a/Modules/CippExtensions/Private/Get-HaloMapping.ps1 b/Modules/CippExtensions/Private/Get-HaloMapping.ps1
index adfdd8e72102..ad4fc1e88111 100644
--- a/Modules/CippExtensions/Private/Get-HaloMapping.ps1
+++ b/Modules/CippExtensions/Private/Get-HaloMapping.ps1
@@ -25,8 +25,14 @@ function Get-HaloMapping {
$pagecount = [Math]::Ceiling($Result.record_count / 999)
} while ($i -le $pagecount)
} catch {
- Write-LogMessage -Message "Could not get HaloPSA Clients, error: $($_.Exception.Message)" -Level Error -tenant 'CIPP' -API 'HaloMapping'
- $RawHaloClients = @(@{name = "Could not get HaloPSA Clients, error: $($_.Exception.Message)" })
+ $Message = if ($_.ErrorDetails.Message) {
+ Get-NormalizedError -Message $_.ErrorDetails.Message
+ } else {
+ $_.Exception.message
+ }
+
+ Write-LogMessage -Message "Could not get HaloPSA Clients, error: $Message " -Level Error -tenant 'CIPP' -API 'HaloMapping'
+ $RawHaloClients = @(@{name = "Could not get HaloPSA Clients, error: $Message" })
}
$HaloClients = $RawHaloClients | ForEach-Object {
[PSCustomObject]@{
diff --git a/Modules/CippExtensions/Private/New-HaloPSATicket.ps1 b/Modules/CippExtensions/Private/New-HaloPSATicket.ps1
index 35b754fa6dfd..5e14f3e1e80d 100644
--- a/Modules/CippExtensions/Private/New-HaloPSATicket.ps1
+++ b/Modules/CippExtensions/Private/New-HaloPSATicket.ps1
@@ -39,8 +39,13 @@ function New-HaloPSATicket {
try {
$Ticket = Invoke-RestMethod -Uri "$($Configuration.ResourceURL)/Tickets" -ContentType 'application/json; charset=utf-8' -Method Post -Body $body -Headers @{Authorization = "Bearer $($token.access_token)" }
} catch {
- Write-LogMessage -message "Failed to send ticket to HaloPSA: $($_.Exception.Message)" -API 'HaloPSATicket' -sev Error
- Write-Host "Failed to send ticket to HaloPSA: $($_.Exception.Message)"
+ $Message = if ($_.ErrorDetails.Message) {
+ Get-NormalizedError -Message $_.ErrorDetails.Message
+ } else {
+ $_.Exception.message
+ }
+ Write-LogMessage -message "Failed to send ticket to HaloPSA: $Message" -API 'HaloPSATicket' -sev Error
+ Write-Host "Failed to send ticket to HaloPSA: $Message"
}
}
\ No newline at end of file
diff --git a/version_latest.txt b/version_latest.txt
index 26611488b0a0..553fe87a05ea 100644
--- a/version_latest.txt
+++ b/version_latest.txt
@@ -1 +1 @@
-5.0.3
\ No newline at end of file
+5.0.4
\ No newline at end of file
| | |