diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c73265..a523644 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -134,5 +134,13 @@ The format is based on
- Fix the cmdlets that take ownership of an item to repeat an operation that
was denied: when the second attempt failed as well, the account that ran
the cmdlet stayed the owner of the item; now the previous owner is restored
+- Fix `-PassThru` of `Enable-Privileges` and `Disable-Privileges`, which
+ wrote the privileges as one collection instead of one object per
+ privilege, and of `New-NTFSSymbolicLink`, which returned a file object for
+ a link to a folder
+- Declare the output types of `Test-Path2`, `Get-FileHash2`,
+ `Add-NTFSAudit`, `Remove-NTFSAudit`, `Copy-Item2`, `Move-Item2`,
+ `Remove-Item2`, and the inheritance cmdlets correctly, so that
+ `Get-Command` and tab completion report the objects they write
[Unreleased]: https://github.com/raandree/NTFSSecurity/compare/4.2.6...HEAD
diff --git a/Docs/Cmdlets/Copy-Item2.md b/Docs/Cmdlets/Copy-Item2.md
index 9bd30c6..f43b357 100644
--- a/Docs/Cmdlets/Copy-Item2.md
+++ b/Docs/Cmdlets/Copy-Item2.md
@@ -176,9 +176,13 @@ You can pipe an object that has a `Destination` property to supply the target of
## OUTPUTS
-### System.Object
+### Alphaleonis.Win32.Filesystem.FileInfo
-By default this cmdlet returns nothing. With `-PassThru $true` it returns an `Alphaleonis.Win32.Filesystem.FileInfo` or `Alphaleonis.Win32.Filesystem.DirectoryInfo` object for each item that it copied.
+By default this cmdlet returns nothing. With `-PassThru $true` it returns a file object for each file that it copied.
+
+### Alphaleonis.Win32.Filesystem.DirectoryInfo
+
+With `-PassThru $true` the cmdlet returns a folder object for each folder that it copied.
## NOTES
diff --git a/Docs/Cmdlets/Disable-NTFSAccessInheritance.md b/Docs/Cmdlets/Disable-NTFSAccessInheritance.md
index fc19225..0a8ca64 100644
--- a/Docs/Cmdlets/Disable-NTFSAccessInheritance.md
+++ b/Docs/Cmdlets/Disable-NTFSAccessInheritance.md
@@ -156,7 +156,7 @@ You can pipe the security descriptors that `Get-NTFSSecurityDescriptor` returns
## OUTPUTS
-### System.Object
+### Security2.FileSystemInheritanceInfo
By default this cmdlet returns no output. With `-PassThru` it writes one `Security2.FileSystemInheritanceInfo` object per item, which reports the `AccessInheritanceEnabled` and `AuditInheritanceEnabled` state after the change.
diff --git a/Docs/Cmdlets/Disable-NTFSAuditInheritance.md b/Docs/Cmdlets/Disable-NTFSAuditInheritance.md
index 18ad002..4fca4bc 100644
--- a/Docs/Cmdlets/Disable-NTFSAuditInheritance.md
+++ b/Docs/Cmdlets/Disable-NTFSAuditInheritance.md
@@ -156,7 +156,7 @@ You can pipe the security descriptors that `Get-NTFSSecurityDescriptor` returns
## OUTPUTS
-### System.Object
+### Security2.FileSystemInheritanceInfo
By default this cmdlet returns no output. With `-PassThru` it writes one `Security2.FileSystemInheritanceInfo` object per item, which reports the `AccessInheritanceEnabled` and `AuditInheritanceEnabled` state after the change.
diff --git a/Docs/Cmdlets/Disable-Privileges.md b/Docs/Cmdlets/Disable-Privileges.md
index 0d48b8f..223adff 100644
--- a/Docs/Cmdlets/Disable-Privileges.md
+++ b/Docs/Cmdlets/Disable-Privileges.md
@@ -93,7 +93,7 @@ This cmdlet does not accept pipeline input.
### ProcessPrivileges.PrivilegeAndAttributes
-With `-PassThru`, the cmdlet writes the privilege collection of the current process. The pipeline enumerates it into one `ProcessPrivileges.PrivilegeAndAttributes` object per privilege, each with a `Privilege`, a `PrivilegeAttributes`, and a `PrivilegeState` property. Without `-PassThru`, the cmdlet writes nothing.
+With `-PassThru`, the cmdlet writes one `ProcessPrivileges.PrivilegeAndAttributes` object per privilege of the current process, each with a `Privilege`, a `PrivilegeAttributes`, and a `PrivilegeState` property. Without `-PassThru`, the cmdlet writes nothing. Before 5.0.0, it wrote the privileges as one collection.
## NOTES
diff --git a/Docs/Cmdlets/Enable-NTFSAccessInheritance.md b/Docs/Cmdlets/Enable-NTFSAccessInheritance.md
index 0a8b6da..6f38c39 100644
--- a/Docs/Cmdlets/Enable-NTFSAccessInheritance.md
+++ b/Docs/Cmdlets/Enable-NTFSAccessInheritance.md
@@ -155,7 +155,7 @@ You can pipe the security descriptors that `Get-NTFSSecurityDescriptor` returns
## OUTPUTS
-### System.Object
+### Security2.FileSystemInheritanceInfo
By default this cmdlet returns no output. With `-PassThru` it writes one `Security2.FileSystemInheritanceInfo` object per item, which reports the `AccessInheritanceEnabled` and `AuditInheritanceEnabled` state after the change.
diff --git a/Docs/Cmdlets/Enable-NTFSAuditInheritance.md b/Docs/Cmdlets/Enable-NTFSAuditInheritance.md
index 4765a1b..36fd685 100644
--- a/Docs/Cmdlets/Enable-NTFSAuditInheritance.md
+++ b/Docs/Cmdlets/Enable-NTFSAuditInheritance.md
@@ -155,7 +155,7 @@ You can pipe the security descriptors that `Get-NTFSSecurityDescriptor` returns
## OUTPUTS
-### System.Object
+### Security2.FileSystemInheritanceInfo
By default this cmdlet returns no output. With `-PassThru` it writes one `Security2.FileSystemInheritanceInfo` object per item, which reports the `AccessInheritanceEnabled` and `AuditInheritanceEnabled` state after the change.
diff --git a/Docs/Cmdlets/Enable-Privileges.md b/Docs/Cmdlets/Enable-Privileges.md
index a8c7fa3..cc0c479 100644
--- a/Docs/Cmdlets/Enable-Privileges.md
+++ b/Docs/Cmdlets/Enable-Privileges.md
@@ -95,7 +95,7 @@ This cmdlet does not accept pipeline input.
### ProcessPrivileges.PrivilegeAndAttributes
-With `-PassThru`, the cmdlet writes the privilege collection of the current process. The pipeline enumerates it into one `ProcessPrivileges.PrivilegeAndAttributes` object per privilege, each with a `Privilege`, a `PrivilegeAttributes`, and a `PrivilegeState` property. Without `-PassThru`, the cmdlet writes nothing.
+With `-PassThru`, the cmdlet writes one `ProcessPrivileges.PrivilegeAndAttributes` object per privilege of the current process, each with a `Privilege`, a `PrivilegeAttributes`, and a `PrivilegeState` property. Without `-PassThru`, the cmdlet writes nothing. Before 5.0.0, it wrote the privileges as one collection.
## NOTES
diff --git a/Docs/Cmdlets/Get-FileHash2.md b/Docs/Cmdlets/Get-FileHash2.md
index 6dd281e..783aa4d 100644
--- a/Docs/Cmdlets/Get-FileHash2.md
+++ b/Docs/Cmdlets/Get-FileHash2.md
@@ -111,9 +111,9 @@ You can supply the `-Algorithm` value through a pipeline object that has an `Alg
## OUTPUTS
-### Security2.FileSystemAccessRule2
+### Alphaleonis.Win32.Filesystem.FileInfo
-The cmdlet does not return access rules. For every hashed file it writes the file object of that file, decorated with the type name `Alphaleonis.Win32.Filesystem.FileInfo+Hash` and extended with the `Hash` and `Algorithm` note properties, so all regular file properties such as `FullName`, `Name`, and `Length` remain available.
+For every hashed file, the cmdlet writes the file object of that file, decorated with the type name `Alphaleonis.Win32.Filesystem.FileInfo+Hash` and extended with the `Hash` and `Algorithm` note properties, so all regular file properties such as `FullName`, `Name`, and `Length` remain available.
## NOTES
diff --git a/Docs/Cmdlets/Move-Item2.md b/Docs/Cmdlets/Move-Item2.md
index b4f3eff..0f49d4d 100644
--- a/Docs/Cmdlets/Move-Item2.md
+++ b/Docs/Cmdlets/Move-Item2.md
@@ -176,9 +176,13 @@ You can pipe an object that has a `Destination` property to supply the target of
## OUTPUTS
-### System.Object
+### Alphaleonis.Win32.Filesystem.FileInfo
-By default this cmdlet returns nothing. With `-PassThru $true` it returns an `Alphaleonis.Win32.Filesystem.FileInfo` or `Alphaleonis.Win32.Filesystem.DirectoryInfo` object for each item that it moved, pointing at the new location.
+By default this cmdlet returns nothing. With `-PassThru $true` it returns a file object for each file that it moved, pointing at the new location.
+
+### Alphaleonis.Win32.Filesystem.DirectoryInfo
+
+With `-PassThru $true` the cmdlet returns a folder object for each folder that it moved, pointing at the new location.
## NOTES
diff --git a/Docs/Cmdlets/New-NTFSSymbolicLink.md b/Docs/Cmdlets/New-NTFSSymbolicLink.md
index 2be53db..b1757ff 100644
--- a/Docs/Cmdlets/New-NTFSSymbolicLink.md
+++ b/Docs/Cmdlets/New-NTFSSymbolicLink.md
@@ -124,11 +124,11 @@ You can pass the path of the new link and the path of the target as strings.
### Alphaleonis.Win32.Filesystem.FileInfo
-With `-PassThru`, the cmdlet writes a file object for the new link. The cmdlet writes that object type for a link to a folder as well. Without `-PassThru`, the cmdlet writes nothing.
+With `-PassThru`, the cmdlet writes a file object for a new link to a file. Without `-PassThru`, the cmdlet writes nothing.
### Alphaleonis.Win32.Filesystem.DirectoryInfo
-The cmdlet does not write folder objects. A directory symbolic link is also returned as a file object.
+With `-PassThru`, the cmdlet writes a folder object for a new link to a folder. Before 5.0.0, it wrote a file object for those links as well.
## NOTES
diff --git a/Docs/Cmdlets/Remove-Item2.md b/Docs/Cmdlets/Remove-Item2.md
index 0669f84..9b28de8 100644
--- a/Docs/Cmdlets/Remove-Item2.md
+++ b/Docs/Cmdlets/Remove-Item2.md
@@ -169,9 +169,13 @@ You can pipe one or more paths to this cmdlet, either as strings or as objects t
## OUTPUTS
-### System.Object
+### Alphaleonis.Win32.Filesystem.FileInfo
-By default this cmdlet returns nothing. With `-PassThru` it returns an `Alphaleonis.Win32.Filesystem.FileInfo` or `Alphaleonis.Win32.Filesystem.DirectoryInfo` object for each item that it deleted.
+By default this cmdlet returns nothing. With `-PassThru` it returns a file object for each file that it deleted.
+
+### Alphaleonis.Win32.Filesystem.DirectoryInfo
+
+With `-PassThru` the cmdlet returns a folder object for each folder that it deleted.
## NOTES
diff --git a/Docs/Cmdlets/Set-NTFSInheritance.md b/Docs/Cmdlets/Set-NTFSInheritance.md
index 34c141f..be5a2d4 100644
--- a/Docs/Cmdlets/Set-NTFSInheritance.md
+++ b/Docs/Cmdlets/Set-NTFSInheritance.md
@@ -178,7 +178,7 @@ You can supply `-AccessInheritanceEnabled` and `-AuditInheritanceEnabled` throug
## OUTPUTS
-### System.Object
+### Security2.FileSystemInheritanceInfo
By default this cmdlet returns no output. With `-PassThru` it writes one `Security2.FileSystemInheritanceInfo` object per item, which reports the `AccessInheritanceEnabled` and `AuditInheritanceEnabled` state after the change.
diff --git a/Docs/Cmdlets/Test-Path2.md b/Docs/Cmdlets/Test-Path2.md
index ee925f0..41e14d6 100644
--- a/Docs/Cmdlets/Test-Path2.md
+++ b/Docs/Cmdlets/Test-Path2.md
@@ -109,13 +109,9 @@ You can supply the `-PathType` value through a pipeline object that has a `PathT
## OUTPUTS
-### Alphaleonis.Win32.Filesystem.FileInfo
+### System.Boolean
-`Test-Path2` does not write file objects. For each path it writes a single `System.Boolean` value that is `$true` when the item exists and matches `-PathType`, and `$false` otherwise.
-
-### Alphaleonis.Win32.Filesystem.DirectoryInfo
-
-`Test-Path2` does not write folder objects either. A folder is reported through the same `System.Boolean` result as a file.
+For each path, the cmdlet writes `$true` when the item exists and matches `-PathType`, and `$false` otherwise.
## NOTES
diff --git a/NTFSSecurity/AuditCmdlets/AddAudit.cs b/NTFSSecurity/AuditCmdlets/AddAudit.cs
index 4ce3edb..d5a11f2 100644
--- a/NTFSSecurity/AuditCmdlets/AddAudit.cs
+++ b/NTFSSecurity/AuditCmdlets/AddAudit.cs
@@ -8,7 +8,7 @@ using System.Security.AccessControl;
namespace NTFSSecurity
{
[Cmdlet(VerbsCommon.Add, "NTFSAudit", DefaultParameterSetName = "PathComplex")]
- [OutputType(typeof(FileSystemAccessRule2))]
+ [OutputType(typeof(FileSystemAuditRule2))]
public class AddAudit : BaseCmdletWithPrivControl
{
private IdentityReference2[] account;
diff --git a/NTFSSecurity/AuditCmdlets/RemoveAudit.cs b/NTFSSecurity/AuditCmdlets/RemoveAudit.cs
index f075b30..c9b618b 100644
--- a/NTFSSecurity/AuditCmdlets/RemoveAudit.cs
+++ b/NTFSSecurity/AuditCmdlets/RemoveAudit.cs
@@ -8,7 +8,7 @@ using System.Security.AccessControl;
namespace NTFSSecurity
{
[Cmdlet(VerbsCommon.Remove, "NTFSAudit", DefaultParameterSetName = "PathComplex")]
- [OutputType(typeof(FileSystemAccessRule2))]
+ [OutputType(typeof(FileSystemAuditRule2))]
public class RemoveAudit : BaseCmdletWithPrivControl
{
private IdentityReference2[] account;
diff --git a/NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs b/NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs
index f459e61..8204ba6 100644
--- a/NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs
+++ b/NTFSSecurity/InheritanceCmdlets/DisableAccessInheritance.cs
@@ -6,6 +6,7 @@ using System.Management.Automation;
namespace NTFSSecurity
{
[Cmdlet(VerbsLifecycle.Disable, "NTFSAccessInheritance", DefaultParameterSetName = "Path")]
+ [OutputType(typeof(FileSystemInheritanceInfo))]
public class DisableAccessInheritance : BaseCmdletWithPrivControl
{
private bool removeInheritedAccessRules;
diff --git a/NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs b/NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs
index bf51018..c64168e 100644
--- a/NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs
+++ b/NTFSSecurity/InheritanceCmdlets/DisableAuditInheritance.cs
@@ -7,6 +7,7 @@ namespace NTFSSecurity
{
[Cmdlet(VerbsLifecycle.Disable, "NTFSAuditInheritance", DefaultParameterSetName = "Path")]
+ [OutputType(typeof(FileSystemInheritanceInfo))]
public class DisableAuditInheritance : BaseCmdletWithPrivControl
{
private bool removeInheritedAccessRules;
diff --git a/NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs b/NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs
index 1821e49..8db7bc6 100644
--- a/NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs
+++ b/NTFSSecurity/InheritanceCmdlets/EnableAccessInheritance.cs
@@ -6,6 +6,7 @@ using System.Management.Automation;
namespace NTFSSecurity
{
[Cmdlet(VerbsLifecycle.Enable, "NTFSAccessInheritance", DefaultParameterSetName = "Path")]
+ [OutputType(typeof(FileSystemInheritanceInfo))]
public class EnableAccessInheritance : BaseCmdletWithPrivControl
{
private bool removeExplicitAccessRules;
diff --git a/NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs b/NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs
index d3c753c..5a19158 100644
--- a/NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs
+++ b/NTFSSecurity/InheritanceCmdlets/EnableAuditInheritance.cs
@@ -6,6 +6,7 @@ using System.Management.Automation;
namespace NTFSSecurity
{
[Cmdlet(VerbsLifecycle.Enable, "NTFSAuditInheritance", DefaultParameterSetName = "Path")]
+ [OutputType(typeof(FileSystemInheritanceInfo))]
public class EnableAuditInheritance : BaseCmdletWithPrivControl
{
private bool removeExplicitAccessRules;
diff --git a/NTFSSecurity/InheritanceCmdlets/SetInheritance.cs b/NTFSSecurity/InheritanceCmdlets/SetInheritance.cs
index 3dcc8b3..ec3333b 100644
--- a/NTFSSecurity/InheritanceCmdlets/SetInheritance.cs
+++ b/NTFSSecurity/InheritanceCmdlets/SetInheritance.cs
@@ -6,6 +6,7 @@ using System.Management.Automation;
namespace NTFSSecurity
{
[Cmdlet(VerbsCommon.Set, "NTFSInheritance", DefaultParameterSetName = "Path")]
+ [OutputType(typeof(FileSystemInheritanceInfo))]
public class SetInheritance : BaseCmdletWithPrivControl
{
private bool? accessInheritanceEnabled;
diff --git a/NTFSSecurity/ItemCmdlets/CopyItem2.cs b/NTFSSecurity/ItemCmdlets/CopyItem2.cs
index 3e391d9..ed373da 100644
--- a/NTFSSecurity/ItemCmdlets/CopyItem2.cs
+++ b/NTFSSecurity/ItemCmdlets/CopyItem2.cs
@@ -5,6 +5,7 @@ using System.Management.Automation;
namespace NTFSSecurity
{
[Cmdlet(VerbsCommon.Copy, "Item2", SupportsShouldProcess = true)]
+ [OutputType(typeof(FileInfo), typeof(DirectoryInfo))]
public class CopyItem2 : BaseCmdlet
{
private string destination;
diff --git a/NTFSSecurity/ItemCmdlets/MoveItem2.cs b/NTFSSecurity/ItemCmdlets/MoveItem2.cs
index 2a360e1..33d7369 100644
--- a/NTFSSecurity/ItemCmdlets/MoveItem2.cs
+++ b/NTFSSecurity/ItemCmdlets/MoveItem2.cs
@@ -5,6 +5,7 @@ using System.Management.Automation;
namespace NTFSSecurity
{
[Cmdlet(VerbsCommon.Move, "Item2", SupportsShouldProcess = true)]
+ [OutputType(typeof(FileInfo), typeof(DirectoryInfo))]
public class MoveItem2 : BaseCmdlet
{
private string destination;
diff --git a/NTFSSecurity/ItemCmdlets/RemoveItem2.cs b/NTFSSecurity/ItemCmdlets/RemoveItem2.cs
index de34ca0..252d80b 100644
--- a/NTFSSecurity/ItemCmdlets/RemoveItem2.cs
+++ b/NTFSSecurity/ItemCmdlets/RemoveItem2.cs
@@ -5,6 +5,7 @@ using System.Management.Automation;
namespace NTFSSecurity
{
[Cmdlet(VerbsCommon.Remove, "Item2", SupportsShouldProcess = true)]
+ [OutputType(typeof(FileInfo), typeof(DirectoryInfo))]
public class RemoveItem2 : BaseCmdlet
{
private SwitchParameter force;
diff --git a/NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs b/NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs
index 81d85ca..64ee2a1 100644
--- a/NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs
+++ b/NTFSSecurity/LinkCmdlets/NewSymbolicLink.cs
@@ -70,7 +70,10 @@ namespace NTFSSecurity
if (passThru)
{
- WriteObject(new FileInfo(path));
+ if (targetItem is FileInfo)
+ WriteObject(new FileInfo(path));
+ else
+ WriteObject(new DirectoryInfo(path));
}
}
catch (System.IO.FileNotFoundException ex)
diff --git a/NTFSSecurity/MiscCmdlets/GetFileHash2.cs b/NTFSSecurity/MiscCmdlets/GetFileHash2.cs
index 2e46f78..91ef656 100644
--- a/NTFSSecurity/MiscCmdlets/GetFileHash2.cs
+++ b/NTFSSecurity/MiscCmdlets/GetFileHash2.cs
@@ -7,7 +7,7 @@ using Security2.FileSystem.FileInfo;
namespace NTFSSecurity
{
[Cmdlet(VerbsCommon.Get, "FileHash2")]
- [OutputType(typeof(FileSystemAccessRule2))]
+ [OutputType(typeof(FileInfo))]
public class GetFileHash2 : BaseCmdlet
{
private HashAlgorithms algorithm = HashAlgorithms.SHA256;
diff --git a/NTFSSecurity/OtherCmdlets.cs b/NTFSSecurity/OtherCmdlets.cs
index 83edb5d..b34aa17 100644
--- a/NTFSSecurity/OtherCmdlets.cs
+++ b/NTFSSecurity/OtherCmdlets.cs
@@ -54,7 +54,7 @@ namespace NTFSSecurity
if (passThru)
{
- this.WriteObject(this.privControl.GetPrivileges());
+ this.WriteObject(this.privControl.GetPrivileges(), true);
}
}
@@ -104,7 +104,7 @@ namespace NTFSSecurity
if (passThru)
{
- this.WriteObject(this.privControl.GetPrivileges());
+ this.WriteObject(this.privControl.GetPrivileges(), true);
}
}
diff --git a/NTFSSecurity/PathCmdlets/TestPath2.cs b/NTFSSecurity/PathCmdlets/TestPath2.cs
index 220f7da..8bb4dfd 100644
--- a/NTFSSecurity/PathCmdlets/TestPath2.cs
+++ b/NTFSSecurity/PathCmdlets/TestPath2.cs
@@ -5,7 +5,7 @@ using System.Management.Automation;
namespace NTFSSecurity
{
[Cmdlet(VerbsDiagnostic.Test, "Path2")]
- [OutputType(typeof(FileInfo), typeof(DirectoryInfo))]
+ [OutputType(typeof(bool))]
public class TestPath2 : BaseCmdlet
{
private TestPathType pathType = TestPathType.Any;
diff --git a/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml b/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml
index 9425ccf..d9e5d0f 100644
--- a/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml
+++ b/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml
@@ -2163,10 +2163,18 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd
- System.Object
+ Alphaleonis.Win32.Filesystem.FileInfo
+
+
+ By default this cmdlet returns nothing. With `-PassThru $true` it returns a file object for each file that it copied.
+
+
+
+
+ Alphaleonis.Win32.Filesystem.DirectoryInfo
- By default this cmdlet returns nothing. With `-PassThru $true` it returns an `Alphaleonis.Win32.Filesystem.FileInfo` or `Alphaleonis.Win32.Filesystem.DirectoryInfo` object for each item that it copied.
+ With `-PassThru $true` the cmdlet returns a folder object for each folder that it copied.
@@ -2400,7 +2408,7 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd
- System.Object
+ Security2.FileSystemInheritanceInfo
By default this cmdlet returns no output. With `-PassThru` it writes one `Security2.FileSystemInheritanceInfo` object per item, which reports the `AccessInheritanceEnabled` and `AuditInheritanceEnabled` state after the change.
@@ -2645,7 +2653,7 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd
- System.Object
+ Security2.FileSystemInheritanceInfo
By default this cmdlet returns no output. With `-PassThru` it writes one `Security2.FileSystemInheritanceInfo` object per item, which reports the `AccessInheritanceEnabled` and `AuditInheritanceEnabled` state after the change.
@@ -2785,7 +2793,7 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd
ProcessPrivileges.PrivilegeAndAttributes
- With `-PassThru`, the cmdlet writes the privilege collection of the current process. The pipeline enumerates it into one `ProcessPrivileges.PrivilegeAndAttributes` object per privilege, each with a `Privilege`, a `PrivilegeAttributes`, and a `PrivilegeState` property. Without `-PassThru`, the cmdlet writes nothing.
+ With `-PassThru`, the cmdlet writes one `ProcessPrivileges.PrivilegeAndAttributes` object per privilege of the current process, each with a `Privilege`, a `PrivilegeAttributes`, and a `PrivilegeState` property. Without `-PassThru`, the cmdlet writes nothing. Before 5.0.0, it wrote the privileges as one collection.
@@ -3017,7 +3025,7 @@ PS C:\> Get-Privileges | Where-Object { $_.Privilege -in 'Backup', 'Restore',
- System.Object
+ Security2.FileSystemInheritanceInfo
By default this cmdlet returns no output. With `-PassThru` it writes one `Security2.FileSystemInheritanceInfo` object per item, which reports the `AccessInheritanceEnabled` and `AuditInheritanceEnabled` state after the change.
@@ -3262,7 +3270,7 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd
- System.Object
+ Security2.FileSystemInheritanceInfo
By default this cmdlet returns no output. With `-PassThru` it writes one `Security2.FileSystemInheritanceInfo` object per item, which reports the `AccessInheritanceEnabled` and `AuditInheritanceEnabled` state after the change.
@@ -3403,7 +3411,7 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd
ProcessPrivileges.PrivilegeAndAttributes
- With `-PassThru`, the cmdlet writes the privilege collection of the current process. The pipeline enumerates it into one `ProcessPrivileges.PrivilegeAndAttributes` object per privilege, each with a `Privilege`, a `PrivilegeAttributes`, and a `PrivilegeState` property. Without `-PassThru`, the cmdlet writes nothing.
+ With `-PassThru`, the cmdlet writes one `ProcessPrivileges.PrivilegeAndAttributes` object per privilege of the current process, each with a `Privilege`, a `PrivilegeAttributes`, and a `PrivilegeState` property. Without `-PassThru`, the cmdlet writes nothing. Before 5.0.0, it wrote the privileges as one collection.
@@ -4140,10 +4148,10 @@ PS C:\> Disable-Privileges
- Security2.FileSystemAccessRule2
+ Alphaleonis.Win32.Filesystem.FileInfo
- The cmdlet does not return access rules. For every hashed file it writes the file object of that file, decorated with the type name `Alphaleonis.Win32.Filesystem.FileInfo+Hash` and extended with the `Hash` and `Algorithm` note properties, so all regular file properties such as `FullName`, `Name`, and `Length` remain available.
+ For every hashed file, the cmdlet writes the file object of that file, decorated with the type name `Alphaleonis.Win32.Filesystem.FileInfo+Hash` and extended with the `Hash` and `Algorithm` note properties, so all regular file properties such as `FullName`, `Name`, and `Length` remain available.
@@ -6938,10 +6946,18 @@ PS C:\Data> Get-NTFSSecurityDescriptor
- System.Object
+ Alphaleonis.Win32.Filesystem.FileInfo
- By default this cmdlet returns nothing. With `-PassThru $true` it returns an `Alphaleonis.Win32.Filesystem.FileInfo` or `Alphaleonis.Win32.Filesystem.DirectoryInfo` object for each item that it moved, pointing at the new location.
+ By default this cmdlet returns nothing. With `-PassThru $true` it returns a file object for each file that it moved, pointing at the new location.
+
+
+
+
+ Alphaleonis.Win32.Filesystem.DirectoryInfo
+
+
+ With `-PassThru $true` the cmdlet returns a folder object for each folder that it moved, pointing at the new location.
@@ -7300,7 +7316,7 @@ PS C:\Data> Get-NTFSSecurityDescriptor
Alphaleonis.Win32.Filesystem.FileInfo
- With `-PassThru`, the cmdlet writes a file object for the new link. The cmdlet writes that object type for a link to a folder as well. Without `-PassThru`, the cmdlet writes nothing.
+ With `-PassThru`, the cmdlet writes a file object for a new link to a file. Without `-PassThru`, the cmdlet writes nothing.
@@ -7308,7 +7324,7 @@ PS C:\Data> Get-NTFSSecurityDescriptor
Alphaleonis.Win32.Filesystem.DirectoryInfo
- The cmdlet does not write folder objects. A directory symbolic link is also returned as a file object.
+ With `-PassThru`, the cmdlet writes a folder object for a new link to a folder. Before 5.0.0, it wrote a file object for those links as well.
@@ -7545,10 +7561,18 @@ PS C:\Data> Get-NTFSSecurityDescriptor
- System.Object
+ Alphaleonis.Win32.Filesystem.FileInfo
- By default this cmdlet returns nothing. With `-PassThru` it returns an `Alphaleonis.Win32.Filesystem.FileInfo` or `Alphaleonis.Win32.Filesystem.DirectoryInfo` object for each item that it deleted.
+ By default this cmdlet returns nothing. With `-PassThru` it returns a file object for each file that it deleted.
+
+
+
+
+ Alphaleonis.Win32.Filesystem.DirectoryInfo
+
+
+ With `-PassThru` the cmdlet returns a folder object for each folder that it deleted.
@@ -9508,7 +9532,7 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd
- System.Object
+ Security2.FileSystemInheritanceInfo
By default this cmdlet returns no output. With `-PassThru` it writes one `Security2.FileSystemInheritanceInfo` object per item, which reports the `AccessInheritanceEnabled` and `AuditInheritanceEnabled` state after the change.
@@ -10085,18 +10109,10 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd
- Alphaleonis.Win32.Filesystem.FileInfo
-
-
- `Test-Path2` does not write file objects. For each path it writes a single `System.Boolean` value that is `$true` when the item exists and matches `-PathType`, and `$false` otherwise.
-
-
-
-
- Alphaleonis.Win32.Filesystem.DirectoryInfo
+ System.Boolean
- `Test-Path2` does not write folder objects either. A folder is reported through the same `System.Boolean` result as a file.
+ For each path, the cmdlet writes `$true` when the item exists and matches `-PathType`, and `$false` otherwise.
diff --git a/Tests/OutputTypes.Tests.ps1 b/Tests/OutputTypes.Tests.ps1
new file mode 100644
index 0000000..643f668
--- /dev/null
+++ b/Tests/OutputTypes.Tests.ps1
@@ -0,0 +1,87 @@
+<#
+ Tests the output types of the cmdlets of the module built in NTFSSecurity\bin\Release: the [OutputType] that
+ Get-Command reports, and the objects that -PassThru writes. Tests that need a privilege skip without it and run
+ in CI, whose runners are elevated.
+#>
+[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Pester shares variables between blocks.'
+)]
+param ()
+
+BeforeDiscovery {
+ Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'TestHelpers.psm1') -Force
+ $holdsBackupPrivilege = Test-PrivilegeHeld -Name 'SeBackupPrivilege'
+ $canCreateSymbolicLinks = Test-PrivilegeHeld -Name 'SeCreateSymbolicLinkPrivilege'
+
+ $itemTypes = @('Alphaleonis.Win32.Filesystem.FileInfo', 'Alphaleonis.Win32.Filesystem.DirectoryInfo')
+ $declaredTypes = @(
+ @{ Name = 'Test-Path2'; Types = @('System.Boolean') }
+ @{ Name = 'Get-FileHash2'; Types = @('Alphaleonis.Win32.Filesystem.FileInfo') }
+ @{ Name = 'Add-NTFSAudit'; Types = @('Security2.FileSystemAuditRule2') }
+ @{ Name = 'Remove-NTFSAudit'; Types = @('Security2.FileSystemAuditRule2') }
+ @{ Name = 'Copy-Item2'; Types = $itemTypes }
+ @{ Name = 'Move-Item2'; Types = $itemTypes }
+ @{ Name = 'Remove-Item2'; Types = $itemTypes }
+ @{ Name = 'Enable-NTFSAccessInheritance'; Types = @('Security2.FileSystemInheritanceInfo') }
+ @{ Name = 'Disable-NTFSAccessInheritance'; Types = @('Security2.FileSystemInheritanceInfo') }
+ @{ Name = 'Enable-NTFSAuditInheritance'; Types = @('Security2.FileSystemInheritanceInfo') }
+ @{ Name = 'Disable-NTFSAuditInheritance'; Types = @('Security2.FileSystemInheritanceInfo') }
+ @{ Name = 'Set-NTFSInheritance'; Types = @('Security2.FileSystemInheritanceInfo') }
+ )
+}
+
+BeforeAll {
+ Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'TestHelpers.psm1') -Force
+ $modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\NTFSSecurity\bin\Release\NTFSSecurity.psd1'
+ Import-Module -Name $modulePath -Force -ErrorAction Stop
+ $sandbox = New-TestSandbox -Name 'OutputTypes'
+ Push-Location -LiteralPath $sandbox
+}
+
+AfterAll {
+ Pop-Location
+ Remove-TestSandbox -Sandbox $sandbox
+ Remove-Module -Name NTFSSecurity -Force -ErrorAction SilentlyContinue
+}
+
+Describe 'Declared output types' {
+ It ' should declare the type of the objects it writes' -ForEach $declaredTypes {
+ @((Get-Command -Name $Name).OutputType.Name) | Should -Be $Types
+ }
+}
+
+Describe 'Privilege cmdlets with -PassThru' {
+ AfterEach {
+ Disable-Privileges -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
+ }
+
+ # Before 5.0.0, -PassThru wrote the privileges as one collection.
+ It 'Enable-Privileges should write one object per privilege' {
+ $result = @(Enable-Privileges -PassThru -ErrorAction SilentlyContinue)
+
+ $result.Count | Should -BeGreaterThan 1
+ $result | ForEach-Object -Process { $_ | Should -BeOfType [ProcessPrivileges.PrivilegeAndAttributes] }
+ }
+
+ It 'Disable-Privileges should write one object per privilege' -Skip:(-not $holdsBackupPrivilege) {
+ Enable-Privileges -ErrorAction SilentlyContinue
+
+ $result = @(Disable-Privileges -PassThru -WarningAction SilentlyContinue)
+
+ $result.Count | Should -BeGreaterThan 1
+ $result | ForEach-Object -Process { $_ | Should -BeOfType [ProcessPrivileges.PrivilegeAndAttributes] }
+ }
+}
+
+Describe 'New-NTFSSymbolicLink with -PassThru' {
+ # Before 5.0.0, the cmdlet returned a file object for a link to a folder as well.
+ It 'Should return a folder object for a link to a folder' -Skip:(-not $canCreateSymbolicLinks) {
+ $folder = New-TestSandboxItem -Sandbox $sandbox -Name 'Target' -Directory
+ $link = Join-Path -Path $sandbox -ChildPath 'FolderLink'
+ Assert-TestSandboxPath -Sandbox $sandbox -Path $link
+
+ $result = New-NTFSSymbolicLink -Path $link -Target $folder -PassThru
+
+ $result | Should -BeOfType [Alphaleonis.Win32.Filesystem.DirectoryInfo]
+ }
+}