From 7b7d35da459f261a725a16d37689bf5c3f366fca Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL HE/HIM) (from Dev Box)" Date: Wed, 13 May 2026 15:45:55 -0700 Subject: [PATCH 1/6] Add explicit arg for enclosing resource path in quotes --- .../PowerShell_adapter.dsc.resource.json | 12 ++++++++---- dsc/tests/dsc_adapter.tests.ps1 | 8 ++++++++ lib/dsc-lib/src/dscresources/command_resource.rs | 16 ++++++++++++---- .../src/dscresources/resource_manifest.rs | 4 ++++ tools/dsctest/dsctest.dsc.manifests.json | 4 ++++ 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/adapters/powershell/PowerShell_adapter.dsc.resource.json b/adapters/powershell/PowerShell_adapter.dsc.resource.json index 954191224..dd36c2c8c 100644 --- a/adapters/powershell/PowerShell_adapter.dsc.resource.json +++ b/adapters/powershell/PowerShell_adapter.dsc.resource.json @@ -41,7 +41,8 @@ "resourceTypeArg": "-ResourceType" }, { - "resourcePathArg": "-ResourcePath" + "resourcePathArg": "-ResourcePath", + "includeQuotes": true } ], "input": "stdin" @@ -61,7 +62,8 @@ "resourceTypeArg": "-ResourceType" }, { - "resourcePathArg": "-ResourcePath" + "resourcePathArg": "-ResourcePath", + "includeQuotes": true } ], "input": "stdin", @@ -83,7 +85,8 @@ "resourceTypeArg": "-ResourceType" }, { - "resourcePathArg": "-ResourcePath" + "resourcePathArg": "-ResourcePath", + "includeQuotes": true } ], "input": "stdin", @@ -104,7 +107,8 @@ "resourceTypeArg": "-ResourceType" }, { - "resourcePathArg": "-ResourcePath" + "resourcePathArg": "-ResourcePath", + "includeQuotes": true } ], "input": "stdin", diff --git a/dsc/tests/dsc_adapter.tests.ps1 b/dsc/tests/dsc_adapter.tests.ps1 index 097e5a337..70b29b401 100644 --- a/dsc/tests/dsc_adapter.tests.ps1 +++ b/dsc/tests/dsc_adapter.tests.ps1 @@ -179,6 +179,14 @@ Describe 'Tests for adapter support' { $out.schema | Should -Not -BeNullOrEmpty } + It 'Specifying includeQuotes should include quotes for path' { + $out = dsc -l trace resource set -r Adapted/Two -i '{"two":"2"}' 2>$TestDrive/error.log | ConvertFrom-Json -Depth 10 + $errorLog = Get-Content $TestDrive/error.log -Raw + $LASTEXITCODE | Should -Be 0 -Because $errorLog + $errorLog | Should -BeLike '*Invoking command ''dsctest'' with args Some(`["adapter", "--operation", "set", "--input", "{\"two\":\"2\"}", "--resource-type", "Adapted/Two", "--resource-path", "\"*\\adaptedTest.dsc.adaptedResource.json\""`])*' -Because $errorLog + $out.afterState.two | Should -BeExactly 'value2' -Because $errorLog + } + It 'Adapted resource with condition false should not be returned' { $out = dsc -l debug resource list 'Adapted/Four' 2>$TestDrive/error.log $errorLog = Get-Content $TestDrive/error.log -Raw diff --git a/lib/dsc-lib/src/dscresources/command_resource.rs b/lib/dsc-lib/src/dscresources/command_resource.rs index 8a3b2e646..2943877e5 100644 --- a/lib/dsc-lib/src/dscresources/command_resource.rs +++ b/lib/dsc-lib/src/dscresources/command_resource.rs @@ -961,10 +961,14 @@ pub fn process_get_args(args: Option<&Vec>, input: &str, command_res processed_args.push(resource_type_arg.clone()); processed_args.push(command_resource_info.type_name.to_string()); }, - GetArgKind::ResourcePath { resource_path_arg } => { + GetArgKind::ResourcePath { resource_path_arg , include_quotes} => { if let Some(path) = &command_resource_info.path { processed_args.push(resource_path_arg.clone()); - processed_args.push(path.to_string_lossy().to_string()); + if include_quotes.unwrap_or(false) { + processed_args.push(format!("\"{}\"", path.to_string_lossy())); + } else { + processed_args.push(path.to_string_lossy().to_string()); + } } }, } @@ -1026,10 +1030,14 @@ fn process_set_delete_args(args: Option<&Vec>, input: &str, co processed_args.push(json_input_arg.clone()); processed_args.push(input.to_string()); }, - SetDeleteArgKind::ResourcePath { resource_path_arg } => { + SetDeleteArgKind::ResourcePath { resource_path_arg , include_quotes} => { if let Some(path) = &command_resource_info.path { processed_args.push(resource_path_arg.clone()); - processed_args.push(path.to_string_lossy().to_string()); + if include_quotes.unwrap_or(false) { + processed_args.push(format!("\"{}\"", path.to_string_lossy())); + } else { + processed_args.push(path.to_string_lossy().to_string()); + } } }, SetDeleteArgKind::ResourceType { resource_type_arg } => { diff --git a/lib/dsc-lib/src/dscresources/resource_manifest.rs b/lib/dsc-lib/src/dscresources/resource_manifest.rs index 96cbdcef2..dbf63671f 100644 --- a/lib/dsc-lib/src/dscresources/resource_manifest.rs +++ b/lib/dsc-lib/src/dscresources/resource_manifest.rs @@ -116,6 +116,8 @@ pub enum GetArgKind { /// The argument that accepts the resource path. #[serde(rename = "resourcePathArg")] resource_path_arg: String, + #[serde(rename = "includeQuotes")] + include_quotes: Option, }, ResourceType { /// The argument that accepts the resource type name. @@ -142,6 +144,8 @@ pub enum SetDeleteArgKind { /// The argument that accepts the resource path. #[serde(rename = "resourcePathArg")] resource_path_arg: String, + #[serde(rename = "includeQuotes")] + include_quotes: Option, }, ResourceType { /// The argument that accepts the resource type name. diff --git a/tools/dsctest/dsctest.dsc.manifests.json b/tools/dsctest/dsctest.dsc.manifests.json index aebd5a990..681dbbf4d 100644 --- a/tools/dsctest/dsctest.dsc.manifests.json +++ b/tools/dsctest/dsctest.dsc.manifests.json @@ -966,6 +966,10 @@ }, { "resourceTypeArg": "--resource-type" + }, + { + "resourcePathArg": "--resource-path", + "includeQuotes": true } ] }, From 15062683fc190dae6cf2f9c90e2d3b6cc783ea31 Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL HE/HIM) (from Dev Box)" Date: Wed, 13 May 2026 16:21:02 -0700 Subject: [PATCH 2/6] remove extra slash since it's not cross-platform compat --- dsc/tests/dsc_adapter.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsc/tests/dsc_adapter.tests.ps1 b/dsc/tests/dsc_adapter.tests.ps1 index 70b29b401..2b0f09673 100644 --- a/dsc/tests/dsc_adapter.tests.ps1 +++ b/dsc/tests/dsc_adapter.tests.ps1 @@ -183,7 +183,7 @@ Describe 'Tests for adapter support' { $out = dsc -l trace resource set -r Adapted/Two -i '{"two":"2"}' 2>$TestDrive/error.log | ConvertFrom-Json -Depth 10 $errorLog = Get-Content $TestDrive/error.log -Raw $LASTEXITCODE | Should -Be 0 -Because $errorLog - $errorLog | Should -BeLike '*Invoking command ''dsctest'' with args Some(`["adapter", "--operation", "set", "--input", "{\"two\":\"2\"}", "--resource-type", "Adapted/Two", "--resource-path", "\"*\\adaptedTest.dsc.adaptedResource.json\""`])*' -Because $errorLog + $errorLog | Should -BeLike '*Invoking command ''dsctest'' with args Some(`["adapter", "--operation", "set", "--input", "{\"two\":\"2\"}", "--resource-type", "Adapted/Two", "--resource-path", "\"*adaptedTest.dsc.adaptedResource.json\""`])*' -Because $errorLog $out.afterState.two | Should -BeExactly 'value2' -Because $errorLog } From b7d2e639953fe67467c0c8f5cf12db8b69319495 Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL HE/HIM) (from Dev Box)" Date: Wed, 13 May 2026 16:30:59 -0700 Subject: [PATCH 3/6] add powershell resource test --- adapters/powershell/Tests/PSAdapted.tests.ps1 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/adapters/powershell/Tests/PSAdapted.tests.ps1 b/adapters/powershell/Tests/PSAdapted.tests.ps1 index dd7eb953a..95abef00c 100644 --- a/adapters/powershell/Tests/PSAdapted.tests.ps1 +++ b/adapters/powershell/Tests/PSAdapted.tests.ps1 @@ -19,4 +19,19 @@ Describe 'Tests for PS adapted manifests' { $out.actualState.Name | Should -BeExactly 'hello' -Because ($out | ConvertTo-Json) $out.actualState.Value | Should -Be 42 } + + It 'Get operation works if adapted resource is in a path with spaces' { + $resourcePath = Join-Path -Path $TestDrive -ChildPath 'Path with spaces' + New-Item -Path $resourcePath -ItemType Directory | Out-Null + Copy-Item -Path (Join-Path -Path $PSScriptRoot -ChildPath 'PSAdaptedTestClassResource*') -Destination $resourcePath + $oldPath = $env:PATH + try { + $env:PATH = $resourcePath + [System.IO.Path]::PathSeparator + $env:PATH + $out = dsc resource get -r 'PSAdaptedTestClassResource/PSAdaptedTestClass' -i '{"name":"hello"}' | ConvertFrom-Json + $LASTEXITCODE | Should -Be 0 + $out.actualState.Name | Should -BeExactly 'hello' + } finally { + $env:PATH = $oldPath + } + } } From 656db044e07570b0f9e88ab1a587c6d44c7d13df Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL HE/HIM) (from Dev Box)" Date: Wed, 13 May 2026 16:34:25 -0700 Subject: [PATCH 4/6] fix copilot feedback --- lib/dsc-lib/src/dscresources/command_resource.rs | 4 ++-- lib/dsc-lib/src/dscresources/resource_manifest.rs | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/dsc-lib/src/dscresources/command_resource.rs b/lib/dsc-lib/src/dscresources/command_resource.rs index 2943877e5..afd539208 100644 --- a/lib/dsc-lib/src/dscresources/command_resource.rs +++ b/lib/dsc-lib/src/dscresources/command_resource.rs @@ -961,7 +961,7 @@ pub fn process_get_args(args: Option<&Vec>, input: &str, command_res processed_args.push(resource_type_arg.clone()); processed_args.push(command_resource_info.type_name.to_string()); }, - GetArgKind::ResourcePath { resource_path_arg , include_quotes} => { + GetArgKind::ResourcePath { resource_path_arg, include_quotes} => { if let Some(path) = &command_resource_info.path { processed_args.push(resource_path_arg.clone()); if include_quotes.unwrap_or(false) { @@ -1030,7 +1030,7 @@ fn process_set_delete_args(args: Option<&Vec>, input: &str, co processed_args.push(json_input_arg.clone()); processed_args.push(input.to_string()); }, - SetDeleteArgKind::ResourcePath { resource_path_arg , include_quotes} => { + SetDeleteArgKind::ResourcePath { resource_path_arg, include_quotes} => { if let Some(path) = &command_resource_info.path { processed_args.push(resource_path_arg.clone()); if include_quotes.unwrap_or(false) { diff --git a/lib/dsc-lib/src/dscresources/resource_manifest.rs b/lib/dsc-lib/src/dscresources/resource_manifest.rs index dbf63671f..910594de8 100644 --- a/lib/dsc-lib/src/dscresources/resource_manifest.rs +++ b/lib/dsc-lib/src/dscresources/resource_manifest.rs @@ -116,6 +116,7 @@ pub enum GetArgKind { /// The argument that accepts the resource path. #[serde(rename = "resourcePathArg")] resource_path_arg: String, + /// Indicates if the argument should be wrapped in quotes. Default is false. #[serde(rename = "includeQuotes")] include_quotes: Option, }, @@ -144,6 +145,7 @@ pub enum SetDeleteArgKind { /// The argument that accepts the resource path. #[serde(rename = "resourcePathArg")] resource_path_arg: String, + /// Indicates if the resource path should be passed with quotes. Default is false. #[serde(rename = "includeQuotes")] include_quotes: Option, }, From 6cb838adc4c2c10e907dbfe143a1886717b81fe0 Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL HE/HIM) (from Dev Box)" Date: Thu, 14 May 2026 09:50:12 -0700 Subject: [PATCH 5/6] address Mikey's comment to use serde default instead of option --- .../src/dscresources/command_resource.rs | 4 ++-- .../src/dscresources/resource_manifest.rs | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/dsc-lib/src/dscresources/command_resource.rs b/lib/dsc-lib/src/dscresources/command_resource.rs index afd539208..3508cff88 100644 --- a/lib/dsc-lib/src/dscresources/command_resource.rs +++ b/lib/dsc-lib/src/dscresources/command_resource.rs @@ -964,7 +964,7 @@ pub fn process_get_args(args: Option<&Vec>, input: &str, command_res GetArgKind::ResourcePath { resource_path_arg, include_quotes} => { if let Some(path) = &command_resource_info.path { processed_args.push(resource_path_arg.clone()); - if include_quotes.unwrap_or(false) { + if *include_quotes { processed_args.push(format!("\"{}\"", path.to_string_lossy())); } else { processed_args.push(path.to_string_lossy().to_string()); @@ -1033,7 +1033,7 @@ fn process_set_delete_args(args: Option<&Vec>, input: &str, co SetDeleteArgKind::ResourcePath { resource_path_arg, include_quotes} => { if let Some(path) = &command_resource_info.path { processed_args.push(resource_path_arg.clone()); - if include_quotes.unwrap_or(false) { + if *include_quotes { processed_args.push(format!("\"{}\"", path.to_string_lossy())); } else { processed_args.push(path.to_string_lossy().to_string()); diff --git a/lib/dsc-lib/src/dscresources/resource_manifest.rs b/lib/dsc-lib/src/dscresources/resource_manifest.rs index 910594de8..568e44f9b 100644 --- a/lib/dsc-lib/src/dscresources/resource_manifest.rs +++ b/lib/dsc-lib/src/dscresources/resource_manifest.rs @@ -112,17 +112,17 @@ pub enum GetArgKind { /// Indicates if argument is mandatory which will pass an empty string if no JSON input is provided. Default is false. mandatory: Option, }, + #[serde(rename_all = "camelCase")] ResourcePath { /// The argument that accepts the resource path. - #[serde(rename = "resourcePathArg")] resource_path_arg: String, /// Indicates if the argument should be wrapped in quotes. Default is false. - #[serde(rename = "includeQuotes")] - include_quotes: Option, + #[serde(default)] + include_quotes: bool, }, + #[serde(rename_all = "camelCase")] ResourceType { /// The argument that accepts the resource type name. - #[serde(rename = "resourceTypeArg")] resource_type_arg: String, }, } @@ -141,23 +141,23 @@ pub enum SetDeleteArgKind { /// Indicates if argument is mandatory which will pass an empty string if no JSON input is provided. Default is false. mandatory: Option, }, + #[serde(rename_all = "camelCase")] ResourcePath { /// The argument that accepts the resource path. - #[serde(rename = "resourcePathArg")] resource_path_arg: String, /// Indicates if the resource path should be passed with quotes. Default is false. - #[serde(rename = "includeQuotes")] - include_quotes: Option, + #[serde(default)] + include_quotes: bool, }, + #[serde(rename_all = "camelCase")] ResourceType { /// The argument that accepts the resource type name. - #[serde(rename = "resourceTypeArg")] resource_type_arg: String, }, /// The argument is passed when the resource is invoked in what-if mode. + #[serde(rename_all = "camelCase")] WhatIf { /// The argument to pass when in what-if mode. - #[serde(rename = "whatIfArg")] what_if_arg: String, } } From a8d806c4ce68d6ecb1d17c5334d7bff863d97946 Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL HE/HIM) (from Dev Box)" Date: Thu, 14 May 2026 12:58:20 -0700 Subject: [PATCH 6/6] Update version to 3.2.1 --- Cargo.lock | 2 +- dsc/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9a4a1814..eb571d7dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -719,7 +719,7 @@ dependencies = [ [[package]] name = "dsc" -version = "3.2.0" +version = "3.2.1" dependencies = [ "clap", "clap_complete", diff --git a/dsc/Cargo.toml b/dsc/Cargo.toml index 10b1f4ec5..6c6c0ce45 100644 --- a/dsc/Cargo.toml +++ b/dsc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dsc" -version = "3.2.0" +version = "3.2.1" edition = "2024" [dependencies]