{"id":42289,"date":"2025-09-12T16:22:10","date_gmt":"2025-09-12T10:52:10","guid":{"rendered":"https:\/\/www.inogic.com\/blog\/?p=42289"},"modified":"2025-09-12T17:18:15","modified_gmt":"2025-09-12T11:48:15","slug":"how-to-automatically-detect-and-remove-unwanted-solution-components-in-dynamics-365","status":"publish","type":"post","link":"https:\/\/www.inogic.com\/blog\/2025\/09\/how-to-automatically-detect-and-remove-unwanted-solution-components-in-dynamics-365\/","title":{"rendered":"How to Automatically Detect and Remove Unwanted Solution Components in Dynamics 365"},"content":{"rendered":"<p><img decoding=\"async\" class=\"alignnone size-full wp-image-42304\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/How-to-Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365.png\" alt=\"Automatically Detect and Remove Unwanted Solution Components in Dynamics 365\" width=\"2100\" height=\"1200\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/How-to-Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365.png 2100w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/How-to-Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-300x171.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/How-to-Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1024x585.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/How-to-Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-768x439.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/How-to-Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1536x878.png 1536w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/How-to-Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-2048x1170.png 2048w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/How-to-Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-660x377.png 660w\" sizes=\"(max-width: 2100px) 100vw, 2100px\" \/><\/p>\n<p>Imagine yourself managing a sprawling Dynamics 365 solution, bloated with thousands of components, including web resources, entities, and plugins, many of which are unused web resources with no dependencies. Cleaning them up via the Power Apps maker portal (<a href=\"https:\/\/make.powerapps.com\/\">https:\/\/make.powerapps.com\/<\/a>) means scrolling through endless lists and manually deleting each one, a tedious and error-prone task. One wrong move could break dependencies, crashing your solution. This common headache for Dynamics 365\/Dataverse developers and admins boils down to two challenges:<\/p>\n<ul>\n<li>Manually reviewing and deleting thousands of components through the UI is time-consuming and error-prone.<\/li>\n<li>Identifying unreferenced components to avoid breaking dependencies (e.g., linked to forms or processes) is risky and disruptive.<\/li>\n<\/ul>\n<p>Here comes our tech-saviors, the powerful duo of <strong>RemoveSolutionComponentRequest <\/strong>and <strong>RetrieveDependenciesForDeleteRequest <\/strong>from<strong> Microsoft.Crm.Sdk.Messages<\/strong>, your cleanup superheroes.<\/p>\n<p>These SDK classes work together to programmatically target and remove unreferenced components from an unmanaged solution, with dependency checks to ensure safety. In this blog, you\u2019ll learn how to streamline solution cleanup with key code snippets, components, and benefits for efficient maintenance.<\/p>\n<p><strong>Approach<\/strong><\/p>\n<p>The aim is to replace manual UI deletions with an automated script that identifies solution components in SampleSolution <em>(e.g., web resources with no dependencies<\/em>) and removes them safely.<\/p>\n<p>The process uses a QueryExpression to target web resources (<em>ComponentType=61<\/em>) and checks dependencies to ensure only idle components are deleted.<\/p>\n<p>The steps include:<\/p>\n<ul>\n<li>Connecting to Dataverse using <strong>CrmServiceClient<\/strong>.<\/li>\n<li>Querying <strong>solutioncomponent <\/strong>and linked <strong>webresource <\/strong>entities to find components.<\/li>\n<li>Validating dependencies with <strong>RetrieveDependenciesForDeleteRequest<\/strong>.<\/li>\n<li>Removing unreferenced components with <strong>RemoveSolutionComponentRequest<\/strong>.<\/li>\n<li>Logging actions and pausing the console for debugging.<\/li>\n<\/ul>\n<p>This approach eliminates manual effort, ensures safety, and scales for large solutions.<\/p>\n<p><strong>Step-by-Step Guide<\/strong><\/p>\n<p>This guide provides a practical walkthrough to set up a console script that cleans up unreferenced web resources in Dynamics 365\/Dataverse. We\u2019ll focus on web resources with no dependencies, ensuring only those with no dependencies are removed. Set up an Azure AD app registration for authentication (ClientId, ClientSecret, org URL)<\/p>\n<p><strong>Step 1: Query Web Resources<\/strong><\/p>\n<p>Query solutioncomponent for web resources (<em>ComponentType=61<\/em>) in SampleSolution.<\/p>\n<pre class=\"lang:css gutter:true start:1\">string solutionUniqueName = \"SampleSolution\";\r\nint componentType = 61; \/\/ Web Resource\r\n\r\nQueryExpression query = new QueryExpression(\"solutioncomponent\")\r\n{\r\nColumnSet = new ColumnSet(\"objectid\", \"componenttype\"),\r\nCriteria = new FilterExpression\r\n{\r\nConditions =\r\n{\r\nnew ConditionExpression(\"solutionid\", ConditionOperator.Equal, GetSolutionId(service, solutionUniqueName)),\r\nnew ConditionExpression(\"componenttype\", ConditionOperator.Equal, componentType)\r\n}\r\n},\r\nLinkEntities =\r\n{\r\nnew LinkEntity\r\n{\r\nLinkFromEntityName = \"solutioncomponent\",\r\nLinkToEntityName = \"webresource\",\r\nLinkFromAttributeName = \"objectid\",\r\nLinkToAttributeName = \"webresourceid\",\r\nColumns = new ColumnSet(\"name\"),\r\nEntityAlias = \"wr\",\r\n}\r\n}\r\n};\r\n\r\n\u00a0\r\n\r\nvar results = service.RetrieveMultiple(query);\r\nLogMessage($\"Found {results.Entities.Count} components matching query.\");<\/pre>\n<p><strong>Step 2: Check Dependencies<\/strong><\/p>\n<p>For each component, use <em>RetrieveDependenciesForDeleteRequest <\/em>to confirm no dependencies exist.<\/p>\n<pre class=\"lang:css gutter:true start:1\">foreach (var component in results.Entities)\r\n{\r\nstring componentName = component.GetAttributeValue&lt;AliasedValue&gt;(\"wr.name\")?.Value?.ToString();\r\nif (componentName == null) continue;\r\n\r\nLogMessage($\"Processing component: {componentName} ({component.Id})\");\r\n\r\n\/\/ Check dependencies\r\nvar dependencyRequest = new RetrieveDependenciesForDeleteRequest\r\n{\r\nComponentType = componentType,\r\nObjectId = component.GetAttributeValue&lt;Guid&gt;(\"objectid\")\r\n};\r\nvar dependencyResponse = (RetrieveDependenciesForDeleteResponse)service.Execute(dependencyRequest);\r\nif (dependencyResponse.EntityCollection.Entities.Count == 0)\r\n{\r\nLogMessage($\"{componentName} has no dependencies. Attempting removal...\");\r\n\r\n}\r\n\r\nelse\r\n\r\n{\r\nLogMessage($\"Skipped {componentName}: Has {dependencyResponse.EntityCollection.Entities.Count} dependencies.\");\r\n}\r\n\r\n}<\/pre>\n<p><strong>Step 3: Remove Idle Components<\/strong><br \/>\nRemove components with no dependencies using <em>RemoveSolutionComponentRequest<\/em>.<\/p>\n<pre class=\"lang:css gutter:true start:1\">if (dependencyResponse.EntityCollection.Entities.Count == 0)\r\n{\r\n    var removeRequest = new RemoveSolutionComponentRequest\r\n    {\r\n      ComponentId = component.GetAttributeValue(\"objectid\"),\r\n      ComponentType = componentType,\r\n      SolutionUniqueName = solutionUniqueName\r\n    };\r\n    try\r\n    {\r\n      service.Execute(removeRequest);\r\n      LogMessage($\"Successfully removed: {componentName} ({component.Id})\");\r\n    }\r\n    catch (Exception ex)\r\n    {\r\n      LogMessage($\"Error removing {componentName}: {ex.Message}\");\r\n    }\r\n}<\/pre>\n<p><strong>Key Components<\/strong><\/p>\n<ul>\n<li><strong>RemoveSolutionComponentRequest<\/strong>:\n<ul>\n<li><strong><em>ComponentId<\/em><\/strong><strong>:<\/strong> Guid of the component (e.g., a3912691-378e-f011-b4cc-6045bda590e0).<\/li>\n<li><strong><em>ComponentType<\/em><\/strong><strong>:<\/strong> Integer code (e.g., 61 for web resources).<\/li>\n<li><strong><em>SolutionUniqueName<\/em><\/strong><strong>:<\/strong> Name of the unmanaged solution (e.g., SampleSolution).<\/li>\n<\/ul>\n<\/li>\n<li><strong>RetrieveDependenciesForDeleteRequest<\/strong>:\n<ul>\n<li><strong><em>ComponentType<\/em><\/strong><strong>:<\/strong> Matches the type above.<\/li>\n<li><strong><em>ObjectId<\/em><\/strong><strong>:<\/strong> Guid of the component to check.<\/li>\n<\/ul>\n<\/li>\n<li><strong>RetrieveDependenciesForDeleteResponse<\/strong>:\n<ul>\n<li><strong><em>EntityCollection<\/em><\/strong><strong>:<\/strong> Lists dependencies; empty means the component is unreferenced and safe to remove<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><strong>Output<\/strong><\/p>\n<p>The script logs actions to <strong>debug_log.txt<\/strong> and the console, detailing processed and removed components.<\/p>\n<p>For example, consider two web resources in SampleSolution: onLoadofAccount (attached to the Account form\u2019s onLoad event, dependent on the Account entity) and Test Account Script (an idle script with no dependencies). The script identifies Test Account Script as unreferenced and removes it, while skipping onLoadofAccount due to its dependency.<\/p>\n<p><strong><em>Before Cleanup:<\/em><\/strong> SampleSolution in make.powerapps.com, showing onLoadofAccount with its dependency and Test Account Script under Web Resources.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-42294\" style=\"border: 1px solid #000000; padding: 1px; margin: 1px;\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/1Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1.png\" alt=\"Automatically Detect and Remove Unwanted Solution Components in Dynamics 365\" width=\"1594\" height=\"313\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/1Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1.png 1594w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/1Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1-300x59.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/1Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1-1024x201.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/1Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1-768x151.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/1Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1-1536x302.png 1536w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/1Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1-660x130.png 660w\" sizes=\"(max-width: 1594px) 100vw, 1594px\" \/><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-42293\" style=\"border: 1px solid #000000; padding: 1px; margin: 1px;\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/2Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365.png\" alt=\"Automatically Detect and Remove Unwanted Solution Components in Dynamics 365\" width=\"1715\" height=\"413\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/2Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365.png 1715w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/2Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-300x72.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/2Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1024x247.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/2Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-768x185.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/2Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1536x370.png 1536w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/2Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-660x159.png 660w\" sizes=\"(max-width: 1715px) 100vw, 1715px\" \/><\/p>\n<p><strong><em>After Cleanup:<\/em><\/strong> SampleSolution with only onLoadofAccount remaining, as Test Account Script was removed.<\/p>\n<p><strong><img decoding=\"async\" class=\"alignnone size-full wp-image-42291\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/3Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365.png\" alt=\"Automatically Detect and Remove Unwanted Solution Components in Dynamics 365\" width=\"1471\" height=\"423\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/3Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365.png 1471w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/3Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-300x86.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/3Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1024x294.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/3Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-768x221.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/3Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-660x190.png 660w\" sizes=\"(max-width: 1471px) 100vw, 1471px\" \/><\/strong><\/p>\n<p><strong><img decoding=\"async\" class=\"alignnone size-full wp-image-42292\" style=\"border: 1px solid #000000; padding: 1px; margin: 1px;\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/4Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365.png\" alt=\"Automatically Detect and Remove Unwanted Solution Components in Dynamics 365\" width=\"1589\" height=\"263\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/4Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365.png 1589w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/4Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-300x50.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/4Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1024x169.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/4Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-768x127.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/4Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-1536x254.png 1536w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/09\/4Automatically-Detect-and-Remove-Unwanted-Solution-Components-in-Dynamics-365-660x109.png 660w\" sizes=\"(max-width: 1589px) 100vw, 1589px\" \/><br \/>\nConclusion<\/strong><\/p>\n<p>Automating solution cleanup with <strong>RemoveSolutionComponentRequest <\/strong>and <strong>RetrieveDependenciesForDeleteRequest <\/strong>transforms a tedious and error-prone process into an efficient and safe workflow. By specifically targeting unreferenced web resources with a QueryExpression and ensuring dependency checks, this approach:<\/p>\n<ul>\n<li>Saves hours by eliminating manual deletions in large solutions.<\/li>\n<li>Prevents errors by only removing idle components with no dependencies.<\/li>\n<li>Adapts easily to other component types (e.g., ComponentType=1 for entities)<\/li>\n<\/ul>\n<p>Give this approach a try in your Dynamics 365 solution and feel free to share your experience or insights in the comments!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Imagine yourself managing a sprawling Dynamics 365 solution, bloated with thousands of components, including web resources, entities, and plugins, many of which are unused web resources with no dependencies. Cleaning them up via the Power Apps maker portal (https:\/\/make.powerapps.com\/) means scrolling through endless lists and manually deleting each one, a tedious and error-prone task. One\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.inogic.com\/blog\/2025\/09\/how-to-automatically-detect-and-remove-unwanted-solution-components-in-dynamics-365\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":15,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[16,2361],"tags":[3225],"class_list":["post-42289","post","type-post","status-publish","format-standard","hentry","category-dynamics-365","category-technical","tag-detect-and-remove-unwanted-solution-components-in-dynamics-365"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/42289","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/comments?post=42289"}],"version-history":[{"count":0,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/42289\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/media?parent=42289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/categories?post=42289"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/tags?post=42289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}