This is a known issue with both ConvertFrom-JSON and Invoke-RestMethod for handling JSON data where the spelling is the same but the casing is different due to JSON being case sensitive and PowerShell being case insensitive.
As most circumstances that I can think of in SailPoint would be due to data issues, the remedy I'm suggesting/requesting here is to build in error checking with warning to the user that not all data was returned and to assist the user with finding such data issues.
The case I ran into was a source that had the schema originally defined in one casing, and then updated to a different casing, and some accounts retain both casings.
Example: The JSON returns two attributes with the same spelling but different casing
attributes: { "firstName": John, "lastName": Doe, "sampleAttribute" : "false", "SampleAttribute" : "false" }
In this, the Invoke-RestMethod will fail to translate the JSON to a proper Array. This will contain the default 250 returned users and this will continue to add this new data to the $accountsData array (declared in line 115) and will pull bad data until such time as the offset value is increased beyond the user with the bad data.
There are two issues with this:
- This pulls in a large data set that is essentially useless multiple times into the returned results
- This fails silently, which doesn't allow the end user to realize that the data set they compiled is incomplete.
Further troubleshooting:
In pulling the dataset containing the user with the problematic data with Invoke-WebRequest and manually converting the $response.content using ConvertFrom-JSON, I get the following error:
ConvertFrom-Json: Cannot convert the JSON string because it contains keys with different casing. Please use the -AsHashTable switch instead. The key that was attempted to be added to the existing key 'sampleAttribute' was 'SampleAttribute'.
Recommendation:
While it is possible to move from Invoke-RestMethod to Invoke-WebRequest and manually convert and use the -AsHashTable, I do not know the level of difficulty to process the data to allow it to be stored in an array. If we're operating on the assumption that any case like this within SailPoint would be a source error, we should just add checks and error handling to account for this.
- First would be to get the type of the $response data using GetType(). If you read $response.GetType().BaseType.Name and the value is not "Array" then do not import the data into $accountData and provide a warning that the data read has an error that prevented converting the JSON (maybe indicate that one known example is this example) and note the Offset and Limit values to provide a scope for the user to troubleshoot by other means.
- Second would be to change the method of incrementing the offset. For this I have two suggestions.
-
- First could be that you simply use a counter variable, start it at 0 and add the $limit value to it each time.
-
- Second would be that you could break down the script to move from the given limit to a smaller limit (or even down to 1) allowing you to pull all the data except for the problem data until you make it past the original limit where you would resume going by larger chunks. If you choose this, you'd hold off on the error warning text until you find the single user with the problem, and from there you can provide potentially specific information as to which account has the issue.
Overall I'd suggest going with the simple error at first, with a change to the counter, and then, if you think it's worth the time/effort, you can attempt to drill down to the specific user.
This is a known issue with both ConvertFrom-JSON and Invoke-RestMethod for handling JSON data where the spelling is the same but the casing is different due to JSON being case sensitive and PowerShell being case insensitive.
Invoke-RestMethodshould have an-AsHashTableswitch PowerShell/PowerShell#19378As most circumstances that I can think of in SailPoint would be due to data issues, the remedy I'm suggesting/requesting here is to build in error checking with warning to the user that not all data was returned and to assist the user with finding such data issues.
The case I ran into was a source that had the schema originally defined in one casing, and then updated to a different casing, and some accounts retain both casings.
Example: The JSON returns two attributes with the same spelling but different casing
attributes: { "firstName": John, "lastName": Doe, "sampleAttribute" : "false", "SampleAttribute" : "false" }In this, the Invoke-RestMethod will fail to translate the JSON to a proper Array. This will contain the default 250 returned users and this will continue to add this new data to the $accountsData array (declared in line 115) and will pull bad data until such time as the offset value is increased beyond the user with the bad data.
There are two issues with this:
Further troubleshooting:
In pulling the dataset containing the user with the problematic data with Invoke-WebRequest and manually converting the $response.content using ConvertFrom-JSON, I get the following error:
Recommendation:
While it is possible to move from Invoke-RestMethod to Invoke-WebRequest and manually convert and use the -AsHashTable, I do not know the level of difficulty to process the data to allow it to be stored in an array. If we're operating on the assumption that any case like this within SailPoint would be a source error, we should just add checks and error handling to account for this.
Overall I'd suggest going with the simple error at first, with a change to the counter, and then, if you think it's worth the time/effort, you can attempt to drill down to the specific user.