diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a1891b..ab9003a 100644 --- a/CHANGELOG.md +++ b/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 diff --git a/NTFSSecurity/AccessCmdlets/AddAccess.cs b/NTFSSecurity/AccessCmdlets/AddAccess.cs index 4770aa9..f503aaa 100644 --- a/NTFSSecurity/AccessCmdlets/AddAccess.cs +++ b/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(); } diff --git a/NTFSSecurity/AccessCmdlets/ClearAccess.cs b/NTFSSecurity/AccessCmdlets/ClearAccess.cs index 9e96a39..1e4a1c6 100644 --- a/NTFSSecurity/AccessCmdlets/ClearAccess.cs +++ b/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(); } diff --git a/NTFSSecurity/AccessCmdlets/GetAccess.cs b/NTFSSecurity/AccessCmdlets/GetAccess.cs index f010e18..1239306 100644 --- a/NTFSSecurity/AccessCmdlets/GetAccess.cs +++ b/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(); } diff --git a/NTFSSecurity/AccessCmdlets/GetEffectiveAccess.cs b/NTFSSecurity/AccessCmdlets/GetEffectiveAccess.cs index bf1334c..96eb1db 100644 --- a/NTFSSecurity/AccessCmdlets/GetEffectiveAccess.cs +++ b/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(); } diff --git a/NTFSSecurity/AccessCmdlets/RemoveAccess.cs b/NTFSSecurity/AccessCmdlets/RemoveAccess.cs index bd4c04d..a1c566b 100644 --- a/NTFSSecurity/AccessCmdlets/RemoveAccess.cs +++ b/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(); } diff --git a/NTFSSecurity/AuditCmdlets/AddAudit.cs b/NTFSSecurity/AuditCmdlets/AddAudit.cs index d5a11f2..f8b8584 100644 --- a/NTFSSecurity/AuditCmdlets/AddAudit.cs +++ b/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(); } diff --git a/NTFSSecurity/AuditCmdlets/ClearAudit.cs b/NTFSSecurity/AuditCmdlets/ClearAudit.cs index 622e5d4..a6f7614 100644 --- a/NTFSSecurity/AuditCmdlets/ClearAudit.cs +++ b/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(); } diff --git a/NTFSSecurity/AuditCmdlets/GetAudit.cs b/NTFSSecurity/AuditCmdlets/GetAudit.cs index c569212..3c6c58c 100644 --- a/NTFSSecurity/AuditCmdlets/GetAudit.cs +++ b/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(); } diff --git a/NTFSSecurity/AuditCmdlets/RemoveAudit.cs b/NTFSSecurity/AuditCmdlets/RemoveAudit.cs index c9b618b..9d88c2b 100644 --- a/NTFSSecurity/AuditCmdlets/RemoveAudit.cs +++ b/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(); } diff --git a/NTFSSecurity/BaseCmdlets.cs b/NTFSSecurity/BaseCmdlets.cs index 36aad2f..3ccf04f 100644 --- a/NTFSSecurity/BaseCmdlets.cs +++ b/NTFSSecurity/BaseCmdlets.cs @@ -335,4 +335,55 @@ namespace NTFSSecurity base.WriteDebug(args == null || args.Length == 0 ? text : string.Format(text, args)); } } -} + + /// + /// 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). + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] + public sealed class FileSystemPathTransformationAttribute : ArgumentTransformationAttribute + { + /// + /// Returns the full path of a file or folder object, or of each one in a collection, and any other value + /// unchanged. + /// + /// The engine APIs of the session. + /// The argument to transform. + /// The transformed argument. + 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(); + 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; + } + } +} \ No newline at end of file diff --git a/NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs b/NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs index 8204ba6..bdb964d 100644 --- a/NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs +++ b/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(); } diff --git a/NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs b/NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs index 610acb3..6505e1c 100644 --- a/NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs +++ b/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(); } diff --git a/NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs b/NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs index 8db7bc6..16ea497 100644 --- a/NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs +++ b/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(); } diff --git a/NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs b/NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs index a5f23cc..0c1a362 100644 --- a/NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs +++ b/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(); } diff --git a/NTFSSecurity/InheritanceCmdlets/GetInheritance.cs b/NTFSSecurity/InheritanceCmdlets/GetInheritance.cs index 07d510c..fe44035 100644 --- a/NTFSSecurity/InheritanceCmdlets/GetInheritance.cs +++ b/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(); } diff --git a/NTFSSecurity/InheritanceCmdlets/SetInheritance.cs b/NTFSSecurity/InheritanceCmdlets/SetInheritance.cs index ecc4459..16ef6e6 100644 --- a/NTFSSecurity/InheritanceCmdlets/SetInheritance.cs +++ b/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(); } diff --git a/NTFSSecurity/ItemCmdlets/CopyItem2.cs b/NTFSSecurity/ItemCmdlets/CopyItem2.cs index e0434c2..8481cc1 100644 --- a/NTFSSecurity/ItemCmdlets/CopyItem2.cs +++ b/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; } diff --git a/NTFSSecurity/ItemCmdlets/GetChildItem2.cs b/NTFSSecurity/ItemCmdlets/GetChildItem2.cs index 96f08f1..9394b15 100644 --- a/NTFSSecurity/ItemCmdlets/GetChildItem2.cs +++ b/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(); } diff --git a/NTFSSecurity/ItemCmdlets/GetItem2.cs b/NTFSSecurity/ItemCmdlets/GetItem2.cs index f45d82c..4b3c662 100644 --- a/NTFSSecurity/ItemCmdlets/GetItem2.cs +++ b/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(); } diff --git a/NTFSSecurity/ItemCmdlets/MoveItem2.cs b/NTFSSecurity/ItemCmdlets/MoveItem2.cs index 4594d2f..c83c9e2 100644 --- a/NTFSSecurity/ItemCmdlets/MoveItem2.cs +++ b/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; } diff --git a/NTFSSecurity/ItemCmdlets/RemoveItem2.cs b/NTFSSecurity/ItemCmdlets/RemoveItem2.cs index b3caa91..59db095 100644 --- a/NTFSSecurity/ItemCmdlets/RemoveItem2.cs +++ b/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(); } diff --git a/NTFSSecurity/LinkCmdlets/GetHardLink.cs b/NTFSSecurity/LinkCmdlets/GetHardLink.cs index fab966e..37f0d33 100644 --- a/NTFSSecurity/LinkCmdlets/GetHardLink.cs +++ b/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(); } diff --git a/NTFSSecurity/LinkCmdlets/NewHardLink.cs b/NTFSSecurity/LinkCmdlets/NewHardLink.cs index cec9d5b..3ce89c6 100644 --- a/NTFSSecurity/LinkCmdlets/NewHardLink.cs +++ b/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; } diff --git a/NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs b/NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs index 64ee2a1..091ae09 100644 --- a/NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs +++ b/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; } diff --git a/NTFSSecurity/MiscCmdlets/GetFileHash2.cs b/NTFSSecurity/MiscCmdlets/GetFileHash2.cs index 113d8f0..9a9acb7 100644 --- a/NTFSSecurity/MiscCmdlets/GetFileHash2.cs +++ b/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(); } diff --git a/NTFSSecurity/OwnerCmdlets/GetOwner.cs b/NTFSSecurity/OwnerCmdlets/GetOwner.cs index 3c7b524..e2c41f3 100644 --- a/NTFSSecurity/OwnerCmdlets/GetOwner.cs +++ b/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(); } diff --git a/NTFSSecurity/OwnerCmdlets/SetOwner.cs b/NTFSSecurity/OwnerCmdlets/SetOwner.cs index 360b6c5..705e250 100644 --- a/NTFSSecurity/OwnerCmdlets/SetOwner.cs +++ b/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(); } diff --git a/NTFSSecurity/PathCmdlets/TestPath2.cs b/NTFSSecurity/PathCmdlets/TestPath2.cs index 8bb4dfd..e25409f 100644 --- a/NTFSSecurity/PathCmdlets/TestPath2.cs +++ b/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(); } diff --git a/NTFSSecurity/SecurityDescriptorCmdlets/GetSecurityDescriptor.cs b/NTFSSecurity/SecurityDescriptorCmdlets/GetSecurityDescriptor.cs index 4d5e3f4..16a0f9d 100644 --- a/NTFSSecurity/SecurityDescriptorCmdlets/GetSecurityDescriptor.cs +++ b/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(); } diff --git a/Tests/Owner.Tests.ps1 b/Tests/Owner.Tests.ps1 index 7ad1608..026dec3 100644 --- a/Tests/Owner.Tests.ps1 +++ b/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 + } +} \ No newline at end of file