Browse Source

fix: bind file and folder objects passed by position as their full path

Windows PowerShell binds an object that is passed by position to a string
parameter through ToString, which returns only the name of a child item, so
the cmdlets looked for it in the current location. The path parameters now
convert file and folder objects to their full path (#88).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
pull/105/head
Raimund Andree 7 days ago
parent
commit
3d75e784ae
  1. 4
      CHANGELOG.md
  2. 1
      NTFSSecurity/AccessCmdlets/AddAccess.cs
  3. 1
      NTFSSecurity/AccessCmdlets/ClearAccess.cs
  4. 1
      NTFSSecurity/AccessCmdlets/GetAccess.cs
  5. 1
      NTFSSecurity/AccessCmdlets/GetEffectiveAccess.cs
  6. 1
      NTFSSecurity/AccessCmdlets/RemoveAccess.cs
  7. 1
      NTFSSecurity/AuditCmdlets/AddAudit.cs
  8. 1
      NTFSSecurity/AuditCmdlets/ClearAudit.cs
  9. 1
      NTFSSecurity/AuditCmdlets/GetAudit.cs
  10. 1
      NTFSSecurity/AuditCmdlets/RemoveAudit.cs
  11. 53
      NTFSSecurity/BaseCmdlets.cs
  12. 1
      NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs
  13. 1
      NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs
  14. 1
      NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs
  15. 1
      NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs
  16. 1
      NTFSSecurity/InheritanceCmdlets/GetInheritance.cs
  17. 1
      NTFSSecurity/InheritanceCmdlets/SetInheritance.cs
  18. 2
      NTFSSecurity/ItemCmdlets/CopyItem2.cs
  19. 1
      NTFSSecurity/ItemCmdlets/GetChildItem2.cs
  20. 1
      NTFSSecurity/ItemCmdlets/GetItem2.cs
  21. 2
      NTFSSecurity/ItemCmdlets/MoveItem2.cs
  22. 1
      NTFSSecurity/ItemCmdlets/RemoveItem2.cs
  23. 1
      NTFSSecurity/LinkCmdlets/GetHardLink.cs
  24. 2
      NTFSSecurity/LinkCmdlets/NewHardLink.cs
  25. 2
      NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs
  26. 1
      NTFSSecurity/MiscCmdlets/GetFileHash2.cs
  27. 1
      NTFSSecurity/OwnerCmdlets/GetOwner.cs
  28. 1
      NTFSSecurity/OwnerCmdlets/SetOwner.cs
  29. 1
      NTFSSecurity/PathCmdlets/TestPath2.cs
  30. 1
      NTFSSecurity/SecurityDescriptorCmdlets/GetSecurityDescriptor.cs
  31. 24
      Tests/Owner.Tests.ps1

4
CHANGELOG.md

@ -177,5 +177,9 @@ The format is based on
automatic variable; the cmdlets now read the current location from the
session, and only for a relative path
([#86](https://github.com/raandree/NTFSSecurity/issues/86))
- Fix file and folder objects passed by position, such as
`Get-NTFSOwner $folder`, which Windows PowerShell bound as the name of the
item, so the cmdlets looked for it in the current location
([#88](https://github.com/raandree/NTFSSecurity/issues/88))
[Unreleased]: https://github.com/raandree/NTFSSecurity/compare/4.2.6...HEAD

1
NTFSSecurity/AccessCmdlets/AddAccess.cs

@ -23,6 +23,7 @@ namespace NTFSSecurity
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/AccessCmdlets/ClearAccess.cs

@ -13,6 +13,7 @@ namespace NTFSSecurity
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/AccessCmdlets/GetAccess.cs

@ -20,6 +20,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/AccessCmdlets/GetEffectiveAccess.cs

@ -20,6 +20,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/AccessCmdlets/RemoveAccess.cs

@ -24,6 +24,7 @@ namespace NTFSSecurity
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/AuditCmdlets/AddAudit.cs

@ -23,6 +23,7 @@ namespace NTFSSecurity
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/AuditCmdlets/ClearAudit.cs

@ -13,6 +13,7 @@ namespace NTFSSecurity
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/AuditCmdlets/GetAudit.cs

@ -20,6 +20,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/AuditCmdlets/RemoveAudit.cs

@ -24,6 +24,7 @@ namespace NTFSSecurity
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathComplex")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

53
NTFSSecurity/BaseCmdlets.cs

@ -335,4 +335,55 @@ namespace NTFSSecurity
base.WriteDebug(args == null || args.Length == 0 ? text : string.Format(text, args));
}
}
}
/// <summary>
/// Converts file and folder objects to their full path. Windows PowerShell binds an object that is passed by
/// position to a string parameter through ToString, which returns only the name of a child item, so the cmdlet
/// resolved it against the current location (#88).
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public sealed class FileSystemPathTransformationAttribute : ArgumentTransformationAttribute
{
/// <summary>
/// Returns the full path of a file or folder object, or of each one in a collection, and any other value
/// unchanged.
/// </summary>
/// <param name="engineIntrinsics">The engine APIs of the session.</param>
/// <param name="inputData">The argument to transform.</param>
/// <returns>The transformed argument.</returns>
public override object Transform(EngineIntrinsics engineIntrinsics, object inputData)
{
var input = inputData is PSObject ? ((PSObject)inputData).BaseObject : inputData;
if (input is string || !(input is IEnumerable))
{
return ToPath(inputData);
}
var result = new List<object>();
foreach (var item in (IEnumerable)input)
{
result.Add(ToPath(item));
}
return result.ToArray();
}
private static object ToPath(object value)
{
var baseObject = value is PSObject ? ((PSObject)value).BaseObject : value;
if (baseObject is System.IO.FileSystemInfo)
{
return ((System.IO.FileSystemInfo)baseObject).FullName;
}
if (baseObject is Alphaleonis.Win32.Filesystem.FileSystemInfo)
{
return ((Alphaleonis.Win32.Filesystem.FileSystemInfo)baseObject).FullName;
}
return value;
}
}
}

1
NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs

@ -15,6 +15,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs

@ -16,6 +16,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs

@ -15,6 +15,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs

@ -15,6 +15,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/InheritanceCmdlets/GetInheritance.cs

@ -13,6 +13,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/InheritanceCmdlets/SetInheritance.cs

@ -16,6 +16,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

2
NTFSSecurity/ItemCmdlets/CopyItem2.cs

@ -15,6 +15,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }
@ -26,6 +27,7 @@ namespace NTFSSecurity
}
[Parameter(Position = 2, Mandatory = true, ValueFromPipelineByPropertyName = true)]
[FileSystemPathTransformation]
public string Destination
{
get { return destination; }

1
NTFSSecurity/ItemCmdlets/GetChildItem2.cs

@ -33,6 +33,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/ItemCmdlets/GetItem2.cs

@ -13,6 +13,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

2
NTFSSecurity/ItemCmdlets/MoveItem2.cs

@ -15,6 +15,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }
@ -26,6 +27,7 @@ namespace NTFSSecurity
}
[Parameter(Position = 2, Mandatory = true, ValueFromPipelineByPropertyName = true)]
[FileSystemPathTransformation]
public string Destination
{
get { return destination; }

1
NTFSSecurity/ItemCmdlets/RemoveItem2.cs

@ -15,6 +15,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/LinkCmdlets/GetHardLink.cs

@ -14,6 +14,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

2
NTFSSecurity/LinkCmdlets/NewHardLink.cs

@ -15,6 +15,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string Path
{
get { return paths[0]; }
@ -27,6 +28,7 @@ namespace NTFSSecurity
[Parameter(Position = 2, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[FileSystemPathTransformation]
public string Target
{
get { return target; }

2
NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs

@ -15,6 +15,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string Path
{
get { return paths[0]; }
@ -27,6 +28,7 @@ namespace NTFSSecurity
[Parameter(Position = 2, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[FileSystemPathTransformation]
public string Target
{
get { return target; }

1
NTFSSecurity/MiscCmdlets/GetFileHash2.cs

@ -16,6 +16,7 @@ namespace NTFSSecurity
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/OwnerCmdlets/GetOwner.cs

@ -12,6 +12,7 @@ namespace NTFSSecurity.OwnerCmdlets
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/OwnerCmdlets/SetOwner.cs

@ -15,6 +15,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/PathCmdlets/TestPath2.cs

@ -13,6 +13,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

1
NTFSSecurity/SecurityDescriptorCmdlets/GetSecurityDescriptor.cs

@ -12,6 +12,7 @@ namespace NTFSSecurity
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("FullName")]
[FileSystemPathTransformation]
public string[] Path
{
get { return paths.ToArray(); }

24
Tests/Owner.Tests.ps1

@ -85,3 +85,27 @@ Describe 'Current location' {
$result.FullName | Should -Be $file
}
}
Describe 'File and folder objects as arguments' {
# Before 5.0.0, Windows PowerShell bound a folder object that was passed by position as its name, which the
# cmdlets resolved against the current location (#88).
It 'Should take a folder object by position' {
$parent = New-TestSandboxItem -Sandbox $sandbox -Name 'Parent' -Directory
$child = Join-Path -Path $parent -ChildPath 'Child'
Assert-TestSandboxPath -Sandbox $sandbox -Path $child
New-Item -ItemType Directory -Path $child | Out-Null
$folder = Get-ChildItem -LiteralPath $parent -Directory
$result = Get-NTFSOwner $folder -ErrorAction Stop
$result.FullName | Should -Be $child
}
It 'Should take file objects through the pipeline as before' {
$file = New-TestSandboxItem -Sandbox $sandbox -Name 'Piped'
$result = Get-Item -LiteralPath $file | Get-NTFSOwner
$result.FullName | Should -Be $file
}
}
Loading…
Cancel
Save