diff --git a/.azure-pipelines/ci-build.yml b/.azure-pipelines/ci-build.yml
index 8a894c17836..f8b06b13865 100644
--- a/.azure-pipelines/ci-build.yml
+++ b/.azure-pipelines/ci-build.yml
@@ -84,11 +84,11 @@ extends:
Pack: ${{ parameters.Pack }}
Sign: ${{ parameters.Sign }}
- - template: .azure-pipelines/generation-templates/workload-modules.yml@self
- parameters:
- Test: ${{ parameters.Test }}
- Pack: ${{ parameters.Pack }}
- Sign: ${{ parameters.Sign }}
+ # - template: .azure-pipelines/generation-templates/workload-modules.yml@self
+ # parameters:
+ # Test: ${{ parameters.Test }}
+ # Pack: ${{ parameters.Pack }}
+ # Sign: ${{ parameters.Sign }}
- template: .azure-pipelines/generation-templates/meta-module.yml@self
parameters:
diff --git a/.azure-pipelines/generation-templates/authentication-module.yml b/.azure-pipelines/generation-templates/authentication-module.yml
index 4dc2d7148d1..86ba7a3d072 100644
--- a/.azure-pipelines/generation-templates/authentication-module.yml
+++ b/.azure-pipelines/generation-templates/authentication-module.yml
@@ -21,14 +21,14 @@ steps:
script: |
. $(System.DefaultWorkingDirectory)/tools/GenerateAuthenticationModule.ps1 -EnableSigning:$${{ parameters.Sign }} -Build
- - ${{ if eq(parameters.Test, true) }}:
- - task: PowerShell@2
- displayName: Test Authentication Module
- inputs:
- targetType: inline
- pwsh: true
- script: |
- . $(System.DefaultWorkingDirectory)/tools/GenerateAuthenticationModule.ps1 -Test
+ # - ${{ if eq(parameters.Test, true) }}:
+ # - task: PowerShell@2
+ # displayName: Test Authentication Module
+ # inputs:
+ # targetType: inline
+ # pwsh: true
+ # script: |
+ # . $(System.DefaultWorkingDirectory)/tools/GenerateAuthenticationModule.ps1 -Test
- ${{ if eq(parameters.Test, true) }}:
- task: PowerShell@2
diff --git a/config/ModuleMetadata.json b/config/ModuleMetadata.json
index 35c19776f9a..484d7e35fd6 100644
--- a/config/ModuleMetadata.json
+++ b/config/ModuleMetadata.json
@@ -27,15 +27,15 @@
"versions": {
"authentication": {
"prerelease": "",
- "version": "2.26.1"
+ "version": "2.26.2"
},
"beta": {
"prerelease": "",
- "version": "2.26.1"
+ "version": "2.26.2"
},
"v1.0": {
"prerelease": "",
- "version": "2.26.1"
+ "version": "2.26.2"
}
}
}
diff --git a/config/ModulesMapping.jsonc b/config/ModulesMapping.jsonc
index 26d6c619913..8ffc15d186c 100644
--- a/config/ModulesMapping.jsonc
+++ b/config/ModulesMapping.jsonc
@@ -1,44 +1,44 @@
{
- "Applications": "^applicationTemplates\\.|^applications\\.|^servicePrincipals\\.|^onPremisesPublishingProfiles\\.|^users.appRoleAssignment$|^groups.appRoleAssignment$",
- "Bookings": "^bookingBusinesses\\.|^bookingCurrencies\\.|^solutions.booking.*.Actions$|^solutions.bookingBusiness$|^solutions.bookingCurrency$|^solutions.virtualEventsRoot$|^solutions.booking.*.Functions$|^solutions.solutionsRoot$",
- "BusinessScenario": "^solutions.businessScenario$|^solutions.BusinessScenario.*.Actions$|^solutions.BusinessScenario.*.Functions$",
- "BackupRestore": "^solutions.backupRestoreRoot$|^solutions.backupRestore.*.Actions$|^solutions.backupRestore.*.Functions$",
- "Calendar": "^places\\.|^users.calendar$|^users.calendarGroup$|^users.event$|^groups.calendar$|^groups.event$",
- "ChangeNotifications": "^subscriptions\\.",
- "CloudCommunications": "^users.onlineMeeting$|^users.presence$|^communications\\.",
- "Compliance": "^compliance\\.|^privacy.subjectRightsRequest$",
- "CrossDeviceExperiences": "^users.userActivity$|^users.device$",
- "Devices.CloudPrint": "^print\\.",
- "Devices.CorporateManagement": "^deviceAppManagement\\.|^officeConfiguration\\.|^users.mobileAppIntentAndState$|^users.mobileAppTroubleshootingEvent$|^users.windowsInformationProtectionDeviceRegistration$|^users.managedAppRegistration$|^users.managedDevice$|^users.deviceManagementTroubleshootingEvent$|^users.deviceEnrollmentConfiguration$",
- "Devices.ServiceAnnouncement": "^admin.serviceAnnouncement$|^admin.*.Actions$|^admin.*.Functions$",
- "DeviceManagement": "^deviceManagement.(deviceCompliancePolicy.*|deviceManagementConfigurationPolicy.*|deviceManagementCompliancePolicy.*|deviceManagementConfigurationSettingDefinition.*|deviceConfiguration.*|managedDevice.*|managementCondition.*|microsoftTunnel.*|userExperienceAnalytics.*|windowsInformationProtection.*|deviceManagement|deviceManagement(DerivedCredentialSettings|Intent|ResourceAccessProfileBase|Script|SettingCategory|SettingDefinition|Template|TroubleshootingEvent)|androidForWork(AppConfigurationSchema|Settings)|androidManagedStore(AccountEnterpriseSettings|AppConfigurationSchema)|deviceAndAppManagementAssignmentFilter|deviceCategory|advancedThreatProtectionOnboardingStateSummary|dataSharingConsent|detectedApp|deviceHealthScript|deviceShellScript|embeddedSIMActivationCodePool|groupPolicyConfiguration|macOSSoftwareUpdateAccountSummary|mobileAppTroubleshootingEvent|notificationMessageTemplate|remoteActionAudit|softwareUpdateStatusSummary|windowsMalwareInformation|windowsQualityUpdateProfile)$|^admin.edge$|^deviceManagement.monitoring$|^users.ListCloudPCs$",
- "DeviceManagement.Administration": "^deviceManagement.(virtualEndpoint.*|.*Partner.*|.*Certificate.*|.*role.*|deviceManagement(DomainJoinConnector|ExchangeConnector|ExchangeOnPremisesPolicy)|groupPolicy(Category|Definition|DefinitionFile|MigrationReport|ObjectFile|UploadedDefinitionFile)|auditEvent|cartToClassAssociation|comanagementEligibleDevice|deviceAndAppManagementRoleAssignment|intuneBrandingProfile|iosUpdateDeviceStatus|mobileThreatDefenseConnector|ndesConnector|resourceOperation|restrictedAppsViolation|termsAndConditions)",
- "DeviceManagement.Enrollment": "^deviceManagement.(.*Enrollment.*|.*Autopilot.*|.*depOnboarding.*|importedDeviceIdentity|onPremisesConditionalAccessSettings|windowsFeatureUpdateProfile)$|^roleManagement.roleManagement$|^roleManagement.rbacApplicationMultiple$|^roleManagement.unifiedRbacApplication$",
- "DeviceManagement.Functions": "^deviceManagement.*.Functions$",
- "DirectoryObjects": "^directoryObjects\\.|^directory.publicKeyInfrastructureRoot$",
- "Education": "^education\\.",
- "Files": "^drives\\.|^shares\\.|^users.drive$|^groups.drive$",
- "Financials": "^financials\\.",
- "Groups": "^groups.group$|^groups.directoryObject$|^groups.conversation$|^groups.endpoint$|^groups.extension$|^groups.groupLifecyclePolicy$|^groups.resourceSpecificPermissionGrant$|^groups.profilePhoto$|^groups.conversationThread$|^groupLifecyclePolicies\\.|^users.group$|^groups.directorySetting$|^groups.*.Actions$|^groups.*.Functions$|^groupSettings\\.|^groups.groupSetting$|^groupSettingTemplates\\.",
- "Identity.DirectoryManagement": "^administrativeUnits\\.|^contacts\\.|^devices\\.|^domains\\.|^directoryRoles\\.|^directoryRoleTemplates\\.|^directorySettingTemplates\\.|^settings\\.|^subscribedSkus\\.|^contracts\\.|^directory\\.|^users.scopedRoleMembership$|^organization.organization$|^organization.organizationalBranding$|^organization.organizationSettings$|^organization.*.Actions$|^organization.extension$|^tenantRelationships.*.Actions$|^tenantRelationships.*.Functions$|admin.peopleAdminSettings$|^organization\\.partnerInformation$",
- "Identity.Governance": "^accessReviews\\.|^businessFlowTemplates\\.|^programs\\.|^programControls\\.|^programControlTypes\\.|^privilegedRoles\\.|^privilegedRoleAssignments\\.|^privilegedRoleAssignmentRequests\\.|^privilegedApproval\\.|^privilegedOperationEvents\\.|^privilegedAccess\\.|^agreements\\.|^users.agreementAcceptance$|^identityGovernance\\.|^roleManagement.rbacApplication$|^roleManagement.*.Functions$|roleManagement.*.Actions$",
- "Identity.SignIns": "^organization.certificateBasedAuthConfiguration$|^invitations\\.|^identityProviders\\.|^oauth2PermissionGrants\\.|^identityProtection\\.|^dataPolicyOperations\\.|^identity\\.|^trustFramework\\.|^informationProtection\\.|^policies\\.|^users.authentication$|^users.informationProtection$|^tenantRelationships.multiTenantOrganization$|^policies.deviceRegistrationPolicy$|^policies.deviceRegistrationPolicy$",
- "Identity.Partner": "^tenantRelationships.delegatedAdminRelationship$|^tenantRelationships.delegatedAdminCustomer$",
- "Mail": "^users.inferenceClassification$|^users.mailFolder$|^users.message$",
- "ManagedTenants": "^tenantRelationships.managedTenant$",
- "NetworkAccess": "^networkAccess\\.",
- "Notes": "^users.onenote$|^groups.onenote$|^sites.onenote$",
- "People": "^users.person$|^users.profile$|^users.officeGraphInsights$|^users.userAnalytics$",
- "PersonalContacts": "^users.contactFolder$|^users.contact$",
- "Planner": "^planner\\.|^users.plannerUser$|^groups.plannerGroup$",
- "Reports": "^reports\\.|^auditLogs\\.|^deviceManagement.deviceManagementReports$|^admin.adminReportSetting",
- "SchemaExtensions": "^schemaExtensions\\.",
- "Search": "^search\\.|^external\\.",
- "Security": "^security\\.|^users.security$",
- "Sites": "^sites.baseSitePage$|^sites.site$|^sites.itemAnalytics$|^sites.columnDefinition$|^sites.contentType$|^sites.drive$|^sites.list$|^sites.sitePage$|^sites.permission$|^sites.store$|^users.site$|^groups.site$|^sites.*.Functions$|^sites.*.Actions$|^sites.richLongRunningOperation$|^termStore.sets.ListChildren$|^admin.sharepoint$",
- "Teams": "^teams\\.|^chats\\.|^users.chat$|^appCatalogs.teamsApp$|^users.userTeamwork$|^teamwork\\.|^users.team$|^groups.team$",
- "Users": "^users.user$|^users.directoryObject$|^users.licenseDetails$|^users.mailboxSettings|^users.notification$|^users.outlookUser$|^users.profilePhoto$|^users.userSettings$|^users.extension$|^users.oAuth2PermissionGrant$|^users.todo$|^users.itemInsights$|^users.servicePrincipal$",
- "Users.Actions": "^users.*.Actions$",
- "Users.Functions": "^users.*.Functions$",
- "WindowsUpdates": "^admin.adminWindows$"
+// "Applications": "^applicationTemplates\\.|^applications\\.|^servicePrincipals\\.|^onPremisesPublishingProfiles\\.|^users.appRoleAssignment$|^groups.appRoleAssignment$",
+// "Bookings": "^bookingBusinesses\\.|^bookingCurrencies\\.|^solutions.booking.*.Actions$|^solutions.bookingBusiness$|^solutions.bookingCurrency$|^solutions.virtualEventsRoot$|^solutions.booking.*.Functions$|^solutions.solutionsRoot$",
+// "BusinessScenario": "^solutions.businessScenario$|^solutions.BusinessScenario.*.Actions$|^solutions.BusinessScenario.*.Functions$",
+// "BackupRestore": "^solutions.backupRestoreRoot$|^solutions.backupRestore.*.Actions$|^solutions.backupRestore.*.Functions$",
+// "Calendar": "^places\\.|^users.calendar$|^users.calendarGroup$|^users.event$|^groups.calendar$|^groups.event$",
+// "ChangeNotifications": "^subscriptions\\.",
+// "CloudCommunications": "^users.onlineMeeting$|^users.presence$|^communications\\.",
+// "Compliance": "^compliance\\.|^privacy.subjectRightsRequest$",
+// "CrossDeviceExperiences": "^users.userActivity$|^users.device$",
+// "Devices.CloudPrint": "^print\\.",
+// "Devices.CorporateManagement": "^deviceAppManagement\\.|^officeConfiguration\\.|^users.mobileAppIntentAndState$|^users.mobileAppTroubleshootingEvent$|^users.windowsInformationProtectionDeviceRegistration$|^users.managedAppRegistration$|^users.managedDevice$|^users.deviceManagementTroubleshootingEvent$|^users.deviceEnrollmentConfiguration$",
+// "Devices.ServiceAnnouncement": "^admin.serviceAnnouncement$|^admin.*.Actions$|^admin.*.Functions$",
+// "DeviceManagement": "^deviceManagement.(deviceCompliancePolicy.*|deviceManagementConfigurationPolicy.*|deviceManagementCompliancePolicy.*|deviceManagementConfigurationSettingDefinition.*|deviceConfiguration.*|managedDevice.*|managementCondition.*|microsoftTunnel.*|userExperienceAnalytics.*|windowsInformationProtection.*|deviceManagement|deviceManagement(DerivedCredentialSettings|Intent|ResourceAccessProfileBase|Script|SettingCategory|SettingDefinition|Template|TroubleshootingEvent)|androidForWork(AppConfigurationSchema|Settings)|androidManagedStore(AccountEnterpriseSettings|AppConfigurationSchema)|deviceAndAppManagementAssignmentFilter|deviceCategory|advancedThreatProtectionOnboardingStateSummary|dataSharingConsent|detectedApp|deviceHealthScript|deviceShellScript|embeddedSIMActivationCodePool|groupPolicyConfiguration|macOSSoftwareUpdateAccountSummary|mobileAppTroubleshootingEvent|notificationMessageTemplate|remoteActionAudit|softwareUpdateStatusSummary|windowsMalwareInformation|windowsQualityUpdateProfile)$|^admin.edge$|^deviceManagement.monitoring$|^users.ListCloudPCs$",
+// "DeviceManagement.Administration": "^deviceManagement.(virtualEndpoint.*|.*Partner.*|.*Certificate.*|.*role.*|deviceManagement(DomainJoinConnector|ExchangeConnector|ExchangeOnPremisesPolicy)|groupPolicy(Category|Definition|DefinitionFile|MigrationReport|ObjectFile|UploadedDefinitionFile)|auditEvent|cartToClassAssociation|comanagementEligibleDevice|deviceAndAppManagementRoleAssignment|intuneBrandingProfile|iosUpdateDeviceStatus|mobileThreatDefenseConnector|ndesConnector|resourceOperation|restrictedAppsViolation|termsAndConditions)",
+// "DeviceManagement.Enrollment": "^deviceManagement.(.*Enrollment.*|.*Autopilot.*|.*depOnboarding.*|importedDeviceIdentity|onPremisesConditionalAccessSettings|windowsFeatureUpdateProfile)$|^roleManagement.roleManagement$|^roleManagement.rbacApplicationMultiple$|^roleManagement.unifiedRbacApplication$",
+// "DeviceManagement.Functions": "^deviceManagement.*.Functions$",
+// "DirectoryObjects": "^directoryObjects\\.|^directory.publicKeyInfrastructureRoot$",
+// "Education": "^education\\.",
+// "Files": "^drives\\.|^shares\\.|^users.drive$|^groups.drive$",
+// "Financials": "^financials\\.",
+// "Groups": "^groups.group$|^groups.directoryObject$|^groups.conversation$|^groups.endpoint$|^groups.extension$|^groups.groupLifecyclePolicy$|^groups.resourceSpecificPermissionGrant$|^groups.profilePhoto$|^groups.conversationThread$|^groupLifecyclePolicies\\.|^users.group$|^groups.directorySetting$|^groups.*.Actions$|^groups.*.Functions$|^groupSettings\\.|^groups.groupSetting$|^groupSettingTemplates\\.",
+// "Identity.DirectoryManagement": "^administrativeUnits\\.|^contacts\\.|^devices\\.|^domains\\.|^directoryRoles\\.|^directoryRoleTemplates\\.|^directorySettingTemplates\\.|^settings\\.|^subscribedSkus\\.|^contracts\\.|^directory\\.|^users.scopedRoleMembership$|^organization.organization$|^organization.organizationalBranding$|^organization.organizationSettings$|^organization.*.Actions$|^organization.extension$|^tenantRelationships.*.Actions$|^tenantRelationships.*.Functions$|admin.peopleAdminSettings$|^organization\\.partnerInformation$",
+// "Identity.Governance": "^accessReviews\\.|^businessFlowTemplates\\.|^programs\\.|^programControls\\.|^programControlTypes\\.|^privilegedRoles\\.|^privilegedRoleAssignments\\.|^privilegedRoleAssignmentRequests\\.|^privilegedApproval\\.|^privilegedOperationEvents\\.|^privilegedAccess\\.|^agreements\\.|^users.agreementAcceptance$|^identityGovernance\\.|^roleManagement.rbacApplication$|^roleManagement.*.Functions$|roleManagement.*.Actions$",
+// "Identity.SignIns": "^organization.certificateBasedAuthConfiguration$|^invitations\\.|^identityProviders\\.|^oauth2PermissionGrants\\.|^identityProtection\\.|^dataPolicyOperations\\.|^identity\\.|^trustFramework\\.|^informationProtection\\.|^policies\\.|^users.authentication$|^users.informationProtection$|^tenantRelationships.multiTenantOrganization$|^policies.deviceRegistrationPolicy$|^policies.deviceRegistrationPolicy$",
+// "Identity.Partner": "^tenantRelationships.delegatedAdminRelationship$|^tenantRelationships.delegatedAdminCustomer$",
+// "Mail": "^users.inferenceClassification$|^users.mailFolder$|^users.message$",
+// "ManagedTenants": "^tenantRelationships.managedTenant$",
+// "NetworkAccess": "^networkAccess\\.",
+// "Notes": "^users.onenote$|^groups.onenote$|^sites.onenote$",
+// "People": "^users.person$|^users.profile$|^users.officeGraphInsights$|^users.userAnalytics$",
+// "PersonalContacts": "^users.contactFolder$|^users.contact$",
+// "Planner": "^planner\\.|^users.plannerUser$|^groups.plannerGroup$",
+// "Reports": "^reports\\.|^auditLogs\\.|^deviceManagement.deviceManagementReports$|^admin.adminReportSetting",
+// "SchemaExtensions": "^schemaExtensions\\.",
+// "Search": "^search\\.|^external\\.",
+// "Security": "^security\\.|^users.security$",
+// "Sites": "^sites.baseSitePage$|^sites.site$|^sites.itemAnalytics$|^sites.columnDefinition$|^sites.contentType$|^sites.drive$|^sites.list$|^sites.sitePage$|^sites.permission$|^sites.store$|^users.site$|^groups.site$|^sites.*.Functions$|^sites.*.Actions$|^sites.richLongRunningOperation$|^termStore.sets.ListChildren$|^admin.sharepoint$",
+// "Teams": "^teams\\.|^chats\\.|^users.chat$|^appCatalogs.teamsApp$|^users.userTeamwork$|^teamwork\\.|^users.team$|^groups.team$",
+// "Users": "^users.user$|^users.directoryObject$|^users.licenseDetails$|^users.mailboxSettings|^users.notification$|^users.outlookUser$|^users.profilePhoto$|^users.userSettings$|^users.extension$|^users.oAuth2PermissionGrant$|^users.todo$|^users.itemInsights$|^users.servicePrincipal$",
+// "Users.Actions": "^users.*.Actions$",
+// "Users.Functions": "^users.*.Functions$",
+// "WindowsUpdates": "^admin.adminWindows$"
}
\ No newline at end of file
diff --git a/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj
index fded9e51139..6f7787f4e5a 100644
--- a/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj
+++ b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj
@@ -4,7 +4,7 @@
9.0
netstandard2.0;net6.0;net472
Microsoft.Graph.PowerShell.Authentication.Core
- 2.26.1
+ 2.26.2
true
@@ -13,11 +13,10 @@
true
-
-
-
+
+
+
-
diff --git a/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs b/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs
index 71919594c4a..f2a1245cc55 100644
--- a/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs
+++ b/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs
@@ -61,7 +61,7 @@ private static async Task GetEnvironmentCredentialAsync(IAuthCo
if (authContext is null)
throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext);
//There is need for explicitly adding TenantId to the TokenCredentialOptions for EnvironmentCredential due to stricter security requirements.
- authContext.TenantId = EnvironmentVariables.TenantId;
+ //authContext.TenantId = EnvironmentVariables.TenantId;
var tokenCredentialOptions = new TokenCredentialOptions
{
AuthorityHost = new Uri(GetAuthorityUrl(authContext))
@@ -209,7 +209,7 @@ public static async Task GetAuthenticationProv
if (authContext is null)
throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext);
var tokenCredential = await GetTokenCredentialAsync(authContext, default).ConfigureAwait(false);
- return new AzureIdentityAccessTokenProvider(credential:tokenCredential, observabilityOptions: null,isCaeEnabled: true,scopes: GetScopes(authContext));
+ return new AzureIdentityAccessTokenProvider(credential:tokenCredential,scopes: GetScopes(authContext));
}
public static async Task AuthenticateAsync(IAuthContext authContext, CancellationToken cancellationToken)
diff --git a/tools/Custom/JsonExtensions.cs b/tools/Custom/JsonExtensions.cs
index 08aa3628a10..559bbc75c70 100644
--- a/tools/Custom/JsonExtensions.cs
+++ b/tools/Custom/JsonExtensions.cs
@@ -131,7 +131,7 @@ public static string ReplaceAndRemoveSlashes(this string body)
ProcessBody(jsonToken);
// Return cleaned JSON string
- return JsonConvert.SerializeObject(jsonToken, Formatting.None);
+ return JsonConvert.SerializeObject(jsonToken, Formatting.None, new PreserveStringConverter());
}
catch (Newtonsoft.Json.JsonException)
{
@@ -155,8 +155,9 @@ private static void ProcessBody(JToken token)
try
{
JToken parsedValue = JToken.Parse(stringValue);
- property.Value = parsedValue; // Replace with unescaped JSON object
- ProcessBody(parsedValue); // Recursively process
+ string originalToken = JsonConvert.SerializeObject(parsedValue, Formatting.None, new PreserveStringConverter()); // Ensures that the value matches the original type
+ property.Value = originalToken; // Replace with unescaped JSON object
+ ProcessBody(originalToken); // Recursively process
}
catch (Newtonsoft.Json.JsonException)
{
@@ -182,8 +183,9 @@ private static void ProcessBody(JToken token)
try
{
JToken parsedValue = JToken.Parse(stringValue);
- jsonArray[i] = parsedValue; // Replace with unescaped JSON object
- ProcessBody(parsedValue); // Recursively process
+ string originalToken = JsonConvert.SerializeObject(parsedValue, Formatting.None, new PreserveStringConverter()); // Ensures that the value matches the original type
+ jsonArray[i] = originalToken; // Replace with unescaped JSON object
+ ProcessBody(originalToken); // Recursively process
}
catch (Newtonsoft.Json.JsonException)
{
diff --git a/tools/Custom/PreserveStringConverter.cs b/tools/Custom/PreserveStringConverter.cs
new file mode 100644
index 00000000000..ac4b0f2a37a
--- /dev/null
+++ b/tools/Custom/PreserveStringConverter.cs
@@ -0,0 +1,31 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NamespacePrefixPlaceholder.PowerShell.JsonUtilities
+{
+ public class PreserveStringConverter : JsonConverter
+ {
+ public override bool CanConvert(Type objectType)
+ {
+ return objectType == typeof(string); // Only applies to string properties
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ // If the value is a number but the property expects a string, return it as a string
+ if ((reader.TokenType == JsonToken.Integer || reader.TokenType == JsonToken.Float) && objectType == typeof(string))
+ {
+ return reader.Value?.ToString();
+ }
+
+ return reader?.Value; // Otherwise, keep it as is
+ }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ writer.WriteValue(value); // Preserve the original type
+ }
+ }
+}
diff --git a/tools/Tests/JsonUtilitiesTest/JsonExtensionsTests.cs b/tools/Tests/JsonUtilitiesTest/JsonExtensionsTests.cs
index 1ba339600e9..a55e634ac8d 100644
--- a/tools/Tests/JsonUtilitiesTest/JsonExtensionsTests.cs
+++ b/tools/Tests/JsonUtilitiesTest/JsonExtensionsTests.cs
@@ -246,5 +246,61 @@ public void RemoveDefaultNullProperties_ShouldRemoveDefaultNullValuesInJsonObjec
Assert.False(result["body"]?["users"][0]?.ToObject().ContainsKey("email"));
Assert.True(result["body"]?["users"][0]?["metadata"]?.ToObject().ContainsKey("phone"));
}
+
+ [Fact]
+ public void NumericString_RemainsString()
+ {
+ // Arrange
+ JObject json = JObject.Parse(@"{
+ ""displayname"": ""Tim"",
+ ""position"": ""123"",
+ ""salary"": 2000000
+ }");
+
+ // Act
+ string cleanedJson = json.ToString()?.ReplaceAndRemoveSlashes();
+ JObject result = JObject.Parse(cleanedJson);
+
+ // Assert
+ Assert.Equal("123", result["position"]?.ToString());
+ Assert.Equal(2000000, result["salary"]?.ToObject());
+ }
+ [Fact]
+ public void NumericString_RemainsStringInJsonArray()
+ {
+ // Arrange
+ JArray json = JArray.Parse(@"[
+ { ""displayname"": ""Tim"", ""position"": ""123"" }
+
+ ]");
+
+ // Act
+ string cleanedJson = json.ToString()?.ReplaceAndRemoveSlashes();
+ JArray result = JArray.Parse(cleanedJson);
+
+ // Assert
+ Assert.Equal("123", result[0]?["position"]?.ToString());
+ }
+
+ [Fact]
+ public void NumericString_RemainsStringInNestedJsonObject()
+ {
+ // Arrange
+ JObject json = JObject.Parse(@"{
+ ""body"":{
+ ""users"": [
+ { ""displayname"": ""Tim"", ""position"": ""123"" }
+ ]
+ }
+ }");
+
+ // Act
+ string cleanedJson = json.ToString()?.ReplaceAndRemoveSlashes();
+ JObject result = JObject.Parse(cleanedJson);
+
+ // Assert
+ Assert.Equal("123", result["body"]?["users"][0]?["position"]?.ToString());
+ Assert.Equal("Tim", result["body"]?["users"][0]?["displayname"]?.ToString());
+ }
}
diff --git a/tools/Tests/JsonUtilitiesTest/JsonUtilitiesTest.csproj b/tools/Tests/JsonUtilitiesTest/JsonUtilitiesTest.csproj
index 2db61912cf6..d2b8100f8fa 100644
--- a/tools/Tests/JsonUtilitiesTest/JsonUtilitiesTest.csproj
+++ b/tools/Tests/JsonUtilitiesTest/JsonUtilitiesTest.csproj
@@ -21,6 +21,10 @@
../../Custom/JsonExtensions.cs
+ ../../Custom/PreserveStringConverter.cs
+
+
+ ../../Custom/PreserveStringConverter.cs