From 39e12dc1f1d6fa7a7574615ab56c59336eaa7047 Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL HE/HIM) (from Dev Box)" Date: Fri, 6 Mar 2026 15:10:18 -0800 Subject: [PATCH 1/5] Enable resource manifest to specify requiredSecurityContext per operation --- .../dsc_resource_securitycontext.tests.ps1 | 89 ++++++ lib/dsc-lib/locales/en-us.toml | 1 + .../src/dscresources/command_resource.rs | 29 +- .../src/dscresources/resource_manifest.rs | 21 +- tools/dsctest/dsctest.dsc.manifests.json | 279 ++++++++++++++++++ 5 files changed, 416 insertions(+), 3 deletions(-) create mode 100644 dsc/tests/dsc_resource_securitycontext.tests.ps1 diff --git a/dsc/tests/dsc_resource_securitycontext.tests.ps1 b/dsc/tests/dsc_resource_securitycontext.tests.ps1 new file mode 100644 index 000000000..656ba1359 --- /dev/null +++ b/dsc/tests/dsc_resource_securitycontext.tests.ps1 @@ -0,0 +1,89 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +Describe 'Tests for resource manifest security context' { + BeforeAll { + $isAdmin = if ($IsWindows) { + $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() + [System.Security.Principal.WindowsPrincipal]::new($identity).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) + } + else { + [System.Environment]::UserName -eq 'root' + } + } + + It 'Resource with security context for operation ' -TestCases @( + # since `set` and `test` rely on `get` to retrieve the current state, we need to always allow that + # and have a separate resource to test the elevated and restricted contexts for get + @{ securityContext = 'Elevated'; operation = 'get'; property = 'actualState'; type = 'Test/SecurityContextElevatedGet' }, + @{ securityContext = 'Elevated'; operation = 'set'; property = 'afterState' }, + @{ securityContext = 'Elevated'; operation = 'delete' }, + @{ securityContext = 'Elevated'; operation = 'test'; property = 'actualState' }, + @{ securityContext = 'Elevated'; operation = 'export' }, + @{ securityContext = 'Restricted'; operation = 'get'; property = 'actualState'; type = 'Test/SecurityContextRestrictedGet' }, + @{ securityContext = 'Restricted'; operation = 'set'; property = 'afterState' }, + @{ securityContext = 'Restricted'; operation = 'delete' }, + @{ securityContext = 'Restricted'; operation = 'test'; property = 'actualState' }, + @{ securityContext = 'Restricted'; operation = 'export' }, + @{ securityContext = 'Current'; operation = 'get'; property = 'actualState' }, + @{ securityContext = 'Current'; operation = 'set'; property = 'afterState' }, + @{ securityContext = 'Current'; operation = 'delete' }, + @{ securityContext = 'Current'; operation = 'test'; property = 'actualState' }, + @{ securityContext = 'Current'; operation = 'export' } + ) { + param($securityContext, $operation, $property, $type) + + if ($null -eq $type) { + $type = "Test/SecurityContext$securityContext" + } + $inputObj = @{ + hello = "world" + action = $operation + } + $out = dsc resource $operation -r $type --input ($inputObj | ConvertTo-Json -Compress) 2>$testdrive/error.log + switch ($securityContext) { + 'Elevated' { + if ($isAdmin) { + $LASTEXITCODE | Should -Be 0 + if ($property) { + $result = $out | ConvertFrom-Json + $result.$property.action | Should -Be $operation + } elseif ($operation -eq 'export') { + $result = $out | ConvertFrom-Json + $result.resources.properties.action | Should -Be 'export' + } + } + else { + $LASTEXITCODE | Should -Be 2 + (Get-Content "$testdrive/error.log") | Should -BeLike "*ERROR*Operation '$operation' for resource '$type' requires security context '$securityContext'*" + } + } + 'Restricted' { + if ($isAdmin) { + $LASTEXITCODE | Should -Be 2 + (Get-Content "$testdrive/error.log") | Should -BeLike "*ERROR*Operation '$operation' for resource '$type' requires security context '$securityContext'*" + } + else { + $LASTEXITCODE | Should -Be 0 + if ($property) { + $result = $out | ConvertFrom-Json + $result.$property.action | Should -Be $operation + } elseif ($operation -eq 'export') { + $result = $out | ConvertFrom-Json + $result.resources.properties.action | Should -Be 'export' + } + } + } + 'Current' { + $LASTEXITCODE | Should -Be 0 + if ($property) { + $result = $out | ConvertFrom-Json + $result.$property.action | Should -Be $operation + } elseif ($operation -eq 'export') { + $result = $out | ConvertFrom-Json + $result.resources.properties.action | Should -Be 'export' + } + } + } + } +} \ No newline at end of file diff --git a/lib/dsc-lib/locales/en-us.toml b/lib/dsc-lib/locales/en-us.toml index 2ae1938ce..ed130823d 100644 --- a/lib/dsc-lib/locales/en-us.toml +++ b/lib/dsc-lib/locales/en-us.toml @@ -191,6 +191,7 @@ inDesiredStateNotBool = "'_inDesiredState' is not a boolean" exportNotSupportedUsingGet = "Export is not supported by resource '%{resource}' using get operation" runProcessError = "Failed to run process '%{executable}': %{error}" whatIfWarning = "Resource '%{resource}' uses deprecated 'whatIf' operation. See https://github.com/PowerShell/DSC/issues/1361 for migration information." +securityContextRequired = "Operation '%{operation}' for resource '%{resource}' requires security context '%{context}'" [dscresources.dscresource] invokeGet = "Invoking get for '%{resource}'" diff --git a/lib/dsc-lib/src/dscresources/command_resource.rs b/lib/dsc-lib/src/dscresources/command_resource.rs index 7dadc2ea8..ef58e1768 100644 --- a/lib/dsc-lib/src/dscresources/command_resource.rs +++ b/lib/dsc-lib/src/dscresources/command_resource.rs @@ -2,12 +2,13 @@ // Licensed under the MIT License. use clap::ValueEnum; +use dsc_lib_security_context::{SecurityContext, get_security_context}; use jsonschema::Validator; use rust_i18n::t; use serde::Deserialize; use serde_json::{Map, Value}; use std::{collections::HashMap, env, path::{Path, PathBuf}, process::Stdio}; -use crate::{configure::{config_doc::ExecutionKind, config_result::{ResourceGetResult, ResourceTestResult}}, dscresources::resource_manifest::SchemaArgKind, types::{ExitCodesMap, FullyQualifiedTypeName}, util::canonicalize_which}; +use crate::{configure::{config_doc::{ExecutionKind, SecurityContextKind}, config_result::{ResourceGetResult, ResourceTestResult}}, dscresources::resource_manifest::SchemaArgKind, types::{ExitCodesMap, FullyQualifiedTypeName}, util::canonicalize_which}; use crate::dscerror::DscError; use super::{ dscresource::{get_diff, redact, DscResource}, @@ -53,6 +54,7 @@ pub fn invoke_get(resource: &DscResource, filter: &str, target_resource: Option< Some(r) => r.type_name.clone(), None => resource.type_name.clone(), }; + validate_security_context(&get.require_security_context, &resource_type, "get")?; let path = if let Some(target_resource) = target_resource { Some(target_resource.path.clone()) } else { @@ -156,6 +158,7 @@ pub fn invoke_set(resource: &DscResource, desired: &str, skip_test: bool, execut let Some(set) = set_method.as_ref() else { return Err(DscError::NotImplemented("set".to_string())); }; + validate_security_context(&set.require_security_context, &resource_type, "set")?; verify_json_from_manifest(&resource, desired, target_resource)?; // if resource doesn't implement a pre-test, we execute test first to see if a set is needed @@ -200,6 +203,7 @@ pub fn invoke_set(resource: &DscResource, desired: &str, skip_test: bool, execut Some(r) => r.type_name.clone(), None => resource.type_name.clone(), }; + validate_security_context(&get.require_security_context, &resource_type, "get")?; let path = if let Some(target_resource) = target_resource { Some(target_resource.path.clone()) } else { @@ -357,6 +361,7 @@ pub fn invoke_test(resource: &DscResource, expected: &str, target_resource: Opti Some(r) => r.type_name.clone(), None => resource.type_name.clone(), }; + validate_security_context(&test.require_security_context, &resource_type, "test")?; let path = if let Some(target_resource) = target_resource { Some(target_resource.path.clone()) } else { @@ -517,6 +522,7 @@ pub fn invoke_delete(resource: &DscResource, filter: &str, target_resource: Opti Some(r) => r.type_name.clone(), None => resource.type_name.clone(), }; + validate_security_context(&delete.require_security_context, &resource_type, "delete")?; let path = if let Some(target_resource) = target_resource { Some(target_resource.path.clone()) } else { @@ -649,6 +655,7 @@ pub fn invoke_export(resource: &DscResource, input: Option<&str>, target_resourc // see if get is supported and use that instead if manifest.get.is_some() { info!("{}", t!("dscresources.commandResource.exportNotSupportedUsingGet", resource = &resource.type_name)); + validate_security_context(&manifest.get.as_ref().unwrap().require_security_context, &resource.type_name, "get")?; let get_result = invoke_get(resource, input.unwrap_or(""), target_resource)?; let mut instances: Vec = Vec::new(); match get_result { @@ -675,6 +682,7 @@ pub fn invoke_export(resource: &DscResource, input: Option<&str>, target_resourc Some(r) => r.type_name.clone(), None => resource.type_name.clone(), }; + validate_security_context(&export.require_security_context, &resource_type, "export")?; let path = if let Some(target_resource) = target_resource { Some(target_resource.path.clone()) } else { @@ -1245,6 +1253,25 @@ pub fn log_stderr_line<'a>(process_id: &u32, trace_line: &'a str) -> &'a str "" } +fn validate_security_context(required_security_context: &Option, resource_type: &str, operation: &str) -> Result<(), DscError> { + match required_security_context { + Some(SecurityContextKind::Elevated) => { + if get_security_context() != SecurityContext::Admin { + return Err(DscError::SecurityContext(t!("dscresources.commandResource.securityContextRequired", operation = operation, resource = resource_type, context = "elevated").to_string())); + } + }, + Some(SecurityContextKind::Restricted) => { + if get_security_context() != SecurityContext::User { + return Err(DscError::SecurityContext(t!("dscresources.commandResource.securityContextRequired", operation = operation, resource = resource_type, context = "restricted").to_string())); + } + }, + None | Some(SecurityContextKind::Current) => { + // no specific context required, so allow any context + }, + } + Ok(()) +} + #[derive(Clone, Debug, PartialEq, Eq, Deserialize, ValueEnum)] pub enum TraceLevel { #[serde(rename = "ERROR")] diff --git a/lib/dsc-lib/src/dscresources/resource_manifest.rs b/lib/dsc-lib/src/dscresources/resource_manifest.rs index 886c789f0..2d0e5b4c8 100644 --- a/lib/dsc-lib/src/dscresources/resource_manifest.rs +++ b/lib/dsc-lib/src/dscresources/resource_manifest.rs @@ -8,8 +8,7 @@ use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; use crate::{ - schemas::{dsc_repo::DscRepoSchema, transforms::idiomaticize_string_enum}, - types::{ExitCodesMap, FullyQualifiedTypeName, TagList}, + configure::config_doc::SecurityContextKind, schemas::{dsc_repo::DscRepoSchema, transforms::idiomaticize_string_enum}, types::{ExitCodesMap, FullyQualifiedTypeName, TagList} }; #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] @@ -221,6 +220,9 @@ pub struct GetMethod { /// How to pass optional input for a Get. #[serde(skip_serializing_if = "Option::is_none")] pub input: Option, + /// The security context required to run the Get method. Default if not specified is `current`. + #[serde(rename = "requireSecurityContext", skip_serializing_if = "Option::is_none")] + pub require_security_context: Option, } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] @@ -241,6 +243,9 @@ pub struct SetMethod { /// The type of return value expected from the Set method. #[serde(rename = "return", skip_serializing_if = "Option::is_none")] pub returns: Option, + /// The security context required to run the Set method. Default if not specified is `current`. + #[serde(rename = "requireSecurityContext", skip_serializing_if = "Option::is_none")] + pub require_security_context: Option, } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] @@ -255,6 +260,9 @@ pub struct TestMethod { /// The type of return value expected from the Test method. #[serde(rename = "return", skip_serializing_if = "Option::is_none")] pub returns: Option, + /// The security context required to run the Test method. Default if not specified is `current`. + #[serde(rename = "requireSecurityContext", skip_serializing_if = "Option::is_none")] + pub require_security_context: Option, } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] @@ -266,6 +274,9 @@ pub struct DeleteMethod { pub args: Option>, /// How to pass required input for a Delete. pub input: Option, + /// The security context required to run the Delete method. Default if not specified is `current`. + #[serde(rename = "requireSecurityContext", skip_serializing_if = "Option::is_none")] + pub require_security_context: Option, } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] @@ -277,6 +288,9 @@ pub struct ValidateMethod { // TODO: enable validation via schema or command pub args: Option>, /// How to pass required input for a Validate. pub input: Option, + /// The security context required to run the Validate method. Default if not specified is `current`. + #[serde(rename = "requireSecurityContext", skip_serializing_if = "Option::is_none")] + pub require_security_context: Option, } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] @@ -288,6 +302,9 @@ pub struct ExportMethod { pub args: Option>, /// How to pass input for a Export. pub input: Option, + /// The security context required to run the Export method. Default if not specified is `current`. + #[serde(rename = "requireSecurityContext", skip_serializing_if = "Option::is_none")] + pub require_security_context: Option, } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] diff --git a/tools/dsctest/dsctest.dsc.manifests.json b/tools/dsctest/dsctest.dsc.manifests.json index 1b02577a8..6b278e4bb 100644 --- a/tools/dsctest/dsctest.dsc.manifests.json +++ b/tools/dsctest/dsctest.dsc.manifests.json @@ -466,6 +466,285 @@ } } }, + { + "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", + "type": "Test/SecurityContextCurrent", + "version": "0.1.0", + "get": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "get", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "current" + }, + "set": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "set", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "current" + }, + "test": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "trace", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "current" + }, + "delete": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "delete", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "current" + }, + "export": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "export", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "current" + }, + "schema": { + "command": { + "executable": "dsctest", + "args": [ + "schema", + "-s", + "operation" + ] + } + } + }, + { + "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", + "type": "Test/SecurityContextElevated", + "version": "0.1.0", + "get": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "get", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "current" + }, + "set": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "set", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "elevated" + }, + "test": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "trace", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "elevated" + }, + "delete": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "delete", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "elevated" + }, + "export": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "export", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "elevated" + }, + "schema": { + "command": { + "executable": "dsctest", + "args": [ + "schema", + "-s", + "operation" + ] + } + } + }, + { + "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", + "type": "Test/SecurityContextElevatedGet", + "version": "0.1.0", + "get": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "get", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "elevated" + }, + "schema": { + "command": { + "executable": "dsctest", + "args": [ + "schema", + "-s", + "operation" + ] + } + } + }, + { + "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", + "type": "Test/SecurityContextRestricted", + "version": "0.1.0", + "get": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "get", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "current" + }, + "set": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "set", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "restricted" + }, + "test": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "trace", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "restricted" + }, + "delete": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "delete", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "restricted" + }, + "export": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "export", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "restricted" + }, + "schema": { + "command": { + "executable": "dsctest", + "args": [ + "schema", + "-s", + "operation" + ] + } + } + }, + { + "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", + "type": "Test/SecurityContextRestrictedGet", + "version": "0.1.0", + "get": { + "executable": "dsctest", + "args": [ + "operation", + "--operation", + "get", + { + "jsonInputArg": "--input" + } + ], + "requireSecurityContext": "restricted" + }, + "schema": { + "command": { + "executable": "dsctest", + "args": [ + "schema", + "-s", + "operation" + ] + } + } + }, { "$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json", "type": "Test/Sleep", From 07c60baa40e2dd9f8f9d7d588ece1f9c305178e9 Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL HE/HIM) (from Dev Box)" Date: Fri, 6 Mar 2026 17:32:02 -0800 Subject: [PATCH 2/5] remove from validate --- lib/dsc-lib/src/dscresources/resource_manifest.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/dsc-lib/src/dscresources/resource_manifest.rs b/lib/dsc-lib/src/dscresources/resource_manifest.rs index 2d0e5b4c8..83177288c 100644 --- a/lib/dsc-lib/src/dscresources/resource_manifest.rs +++ b/lib/dsc-lib/src/dscresources/resource_manifest.rs @@ -288,9 +288,6 @@ pub struct ValidateMethod { // TODO: enable validation via schema or command pub args: Option>, /// How to pass required input for a Validate. pub input: Option, - /// The security context required to run the Validate method. Default if not specified is `current`. - #[serde(rename = "requireSecurityContext", skip_serializing_if = "Option::is_none")] - pub require_security_context: Option, } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] From e2eb36bdfe1e7299f7dd0559468740848f759c76 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Fri, 6 Mar 2026 17:34:48 -0800 Subject: [PATCH 3/5] Update lib/dsc-lib/src/dscresources/resource_manifest.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- lib/dsc-lib/src/dscresources/resource_manifest.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/dsc-lib/src/dscresources/resource_manifest.rs b/lib/dsc-lib/src/dscresources/resource_manifest.rs index 83177288c..34497b67b 100644 --- a/lib/dsc-lib/src/dscresources/resource_manifest.rs +++ b/lib/dsc-lib/src/dscresources/resource_manifest.rs @@ -8,7 +8,9 @@ use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; use crate::{ - configure::config_doc::SecurityContextKind, schemas::{dsc_repo::DscRepoSchema, transforms::idiomaticize_string_enum}, types::{ExitCodesMap, FullyQualifiedTypeName, TagList} + configure::config_doc::SecurityContextKind, + schemas::{dsc_repo::DscRepoSchema, transforms::idiomaticize_string_enum}, + types::{ExitCodesMap, FullyQualifiedTypeName, TagList}, }; #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, DscRepoSchema)] From 2fce7ccd28331800545c53c13ef6237988704728 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Mon, 9 Mar 2026 09:20:47 -0700 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Tess Gauthier Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- dsc/tests/dsc_resource_securitycontext.tests.ps1 | 2 +- lib/dsc-lib/src/dscresources/command_resource.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dsc/tests/dsc_resource_securitycontext.tests.ps1 b/dsc/tests/dsc_resource_securitycontext.tests.ps1 index 656ba1359..cbbe3daa7 100644 --- a/dsc/tests/dsc_resource_securitycontext.tests.ps1 +++ b/dsc/tests/dsc_resource_securitycontext.tests.ps1 @@ -86,4 +86,4 @@ Describe 'Tests for resource manifest security context' { } } } -} \ No newline at end of file +} diff --git a/lib/dsc-lib/src/dscresources/command_resource.rs b/lib/dsc-lib/src/dscresources/command_resource.rs index ef58e1768..5e9228d14 100644 --- a/lib/dsc-lib/src/dscresources/command_resource.rs +++ b/lib/dsc-lib/src/dscresources/command_resource.rs @@ -655,9 +655,9 @@ pub fn invoke_export(resource: &DscResource, input: Option<&str>, target_resourc // see if get is supported and use that instead if manifest.get.is_some() { info!("{}", t!("dscresources.commandResource.exportNotSupportedUsingGet", resource = &resource.type_name)); - validate_security_context(&manifest.get.as_ref().unwrap().require_security_context, &resource.type_name, "get")?; let get_result = invoke_get(resource, input.unwrap_or(""), target_resource)?; let mut instances: Vec = Vec::new(); + match get_result { match get_result { GetResult::Group(group_response) => { for result in group_response { From 5a3cf952ffb9a080b14bac2dfb56605edd3e5efe Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL HE/HIM) (from Dev Box)" Date: Mon, 9 Mar 2026 09:29:14 -0700 Subject: [PATCH 5/5] fix badly applied suggestion --- lib/dsc-lib/src/dscresources/command_resource.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/dsc-lib/src/dscresources/command_resource.rs b/lib/dsc-lib/src/dscresources/command_resource.rs index 5e9228d14..634418caa 100644 --- a/lib/dsc-lib/src/dscresources/command_resource.rs +++ b/lib/dsc-lib/src/dscresources/command_resource.rs @@ -657,7 +657,6 @@ pub fn invoke_export(resource: &DscResource, input: Option<&str>, target_resourc info!("{}", t!("dscresources.commandResource.exportNotSupportedUsingGet", resource = &resource.type_name)); let get_result = invoke_get(resource, input.unwrap_or(""), target_resource)?; let mut instances: Vec = Vec::new(); - match get_result { match get_result { GetResult::Group(group_response) => { for result in group_response {