From 37bd42d2ddaeef72273f443f34fc5948894fb98f Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Wed, 21 Oct 2026 12:21:38 +0000 Subject: [PATCH] fix(securitydescriptor): make -SecurityDescriptor of Set-NTFSSecurityDescriptor the first positional parameter Set-NTFSSecurityDescriptor declared -SecurityDescriptor at Position = 2, its only positional parameter; every sibling that takes a security descriptor or a path takes its first positional parameter at 1. Moved to Position = 1 for consistency. A positional call with one argument already bound to it, because it was the only positional parameter in its only parameter set, so no script that calls the cmdlet positionally can notice a difference; this is cosmetic, as Decision 27 describes it. Tests\SecurityDescriptor.Tests.ps1 adds a characterization-turned-pin test: the declared Position is 1, and Set-NTFSSecurityDescriptor $sd still works positionally. RED before the change (Position was 2), GREEN after, in all four configurations. Docs\Cmdlets\Set-NTFSSecurityDescriptor.md: Position: 1 in the yaml block of -SecurityDescriptor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant --- Docs/Cmdlets/Set-NTFSSecurityDescriptor.md | 2 +- .../SetSecurityDescriptor.cs | 2 +- Tests/SecurityDescriptor.Tests.ps1 | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Docs/Cmdlets/Set-NTFSSecurityDescriptor.md b/Docs/Cmdlets/Set-NTFSSecurityDescriptor.md index 1251fb2..bd0ccfc 100644 --- a/Docs/Cmdlets/Set-NTFSSecurityDescriptor.md +++ b/Docs/Cmdlets/Set-NTFSSecurityDescriptor.md @@ -95,7 +95,7 @@ Parameter Sets: (All) Aliases: Required: True -Position: 2 +Position: 1 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False diff --git a/NTFSSecurity/SecurityDescriptorCmdlets/SetSecurityDescriptor.cs b/NTFSSecurity/SecurityDescriptorCmdlets/SetSecurityDescriptor.cs index 48bb106..3d1a456 100644 --- a/NTFSSecurity/SecurityDescriptorCmdlets/SetSecurityDescriptor.cs +++ b/NTFSSecurity/SecurityDescriptorCmdlets/SetSecurityDescriptor.cs @@ -11,7 +11,7 @@ namespace NTFSSecurity { private SwitchParameter passThru; - [Parameter(Mandatory = true, Position = 2, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] public FileSystemSecurity2[] SecurityDescriptor { get { return securityDescriptors.ToArray(); } diff --git a/Tests/SecurityDescriptor.Tests.ps1 b/Tests/SecurityDescriptor.Tests.ps1 index 32ad555..e2c1156 100644 --- a/Tests/SecurityDescriptor.Tests.ps1 +++ b/Tests/SecurityDescriptor.Tests.ps1 @@ -73,6 +73,24 @@ Describe 'Get-NTFSSecurityDescriptor' { } Describe 'Set-NTFSSecurityDescriptor' { + Context 'Parameter declaration' { + # Its siblings (Get-NTFSSecurityDescriptor and the cmdlets with a -SecurityDescriptor parameter set) take + # their first positional parameter at 1; -SecurityDescriptor was the only one at 2 (6c), cosmetic only: a + # positional call with one argument already bound to it, because it was the only positional parameter. + It 'Should declare -SecurityDescriptor at position 1, and still accept it positionally' { + (Get-Command -Name 'Set-NTFSSecurityDescriptor').Parameters['SecurityDescriptor'].Attributes.Position | Should -Be 1 + + $file = New-TestSandboxItem -Sandbox $sandbox -Name 'PositionalWrite' + Assert-TestSandboxPath -Sandbox $sandbox -Path $file + $sd = Get-NTFSSecurityDescriptor -Path $file + Add-NTFSAccess -SecurityDescriptor $sd -Account 'Everyone' -AccessRights ReadData + + Set-NTFSSecurityDescriptor $sd + + @(Get-EveryoneRule -Path $file) | Should -HaveCount 1 + } + } + Context 'When a cmdlet added an access entry to the descriptor' { It 'Should write the entry as the only explicit entry of the item' { $file = New-TestSandboxItem -Sandbox $sandbox -Name 'AddedEntry'