@ -46,7 +46,7 @@ Adds an access control entry (ACE) to the discretionary access control list (DAC
`-AccessRights` accepts the basic rights such as `Read`, `Modify`, and `FullControl` as well as the granular rights such as `CreateFiles` or `WriteAttributes`, and several values can be combined, for example `-AccessRights ReadData, WriteData, Delete`. For the mapping between the values of this module, the rights that Windows displays, and the entries of the advanced security dialog, see [Concepts](../Concepts.md).
`-AccessRights` accepts the basic rights such as `Read`, `Modify`, and `FullControl` as well as the granular rights such as `CreateFiles` or `WriteAttributes`, and several values can be combined, for example `-AccessRights ReadData, WriteData, Delete`. For the mapping between the values of this module, the rights that Windows displays, and the entries of the advanced security dialog, see [Concepts](../Concepts.md).
The cmdlet has four parameter sets. The `Path` sets read the item from disk and write the changed DACL back immediately, while the `SD` sets change a `Security2.FileSystemSecurity2` object returned by `Get-NTFSSecurityDescriptor` in memory until `Set-NTFSSecurityDescriptor` writes it back. The `Simple` sets take `-AppliesTo`, the `Complex` sets take `-InheritanceFlags` and `-PropagationFlags`; both describe the same ACE flags. A command without `-AppliesTo` uses a `Complex` set, also when it works on a security descriptor, and a command that has `-AppliesTo` together with `-InheritanceFlags` or `-PropagationFlags` fails, because PowerShell can't choose between the sets. The same holds for an object that you pipe in: its property `AppliesTo` selects a `Simple` set, its properties `InheritanceFlags` and `PropagationFlags` select a `Complex` set, and an object that has both kinds, an object that has both `Path` and `SecurityDescriptor`, or one whose `AppliesTo` is `$null`, fails. `Import-Csv` gives `$null` for a column that a row lacks because it has fewer fields than the header. An `AppliesTo` that PowerShell can't convert to a scope, such as the blank cell of a CSV file or a misspelled name, is ignored, and the object is handled as one without `AppliesTo`: it uses its own `InheritanceFlags` and `PropagationFlags`, or the default scope if it has none. Before 5.0.0, a command that used `-SecurityDescriptor` without `-AppliesTo`, `-InheritanceFlags`, or `-PropagationFlags` failed, because PowerShell couldn't choose between the two `SD` sets.
The cmdlet has four parameter sets. The `Path` sets read the item from disk and write the changed DACL back immediately, while the `SD` sets change a `Security2.FileSystemSecurity2` object returned by `Get-NTFSSecurityDescriptor` in memory until `Set-NTFSSecurityDescriptor` writes it back. The `Simple` sets take `-AppliesTo`, the `Complex` sets take `-InheritanceFlags` and `-PropagationFlags`; both describe the same ACE flags. A command without `-AppliesTo` uses a `Complex` set, also when it works on a security descriptor, and a command that has `-AppliesTo` together with `-InheritanceFlags` or `-PropagationFlags` fails, because PowerShell can't choose between the sets. The same holds for an object that you pipe in: its property `AppliesTo` selects a `Simple` set, its properties `InheritanceFlags` and `PropagationFlags` select a `Complex` set, and an object that has both `Path` and `SecurityDescriptor` fails. A `$null`, an empty string, or `DBNull` value of a property counts as present for this choice, the same as a real value, so a CSV file, or any other source of piped objects, should have the columns of only one group: `AppliesTo`, or `InheritanceFlags` and `PropagationFlags`. A row or object that has properties of both groups is an `AmbiguousParameterSet` error, even if the value of one of them is `$null` (for example in a short CSV row, whose missing trailing columns `Import-Csv` fills with `$null`), an empty string, or `DBNull`: the error is terminating when you name the parameters on the command line, and it is reported for just that object, which is left unchanged, when the object comes from the pipeline. A `$null` value of `-AppliesTo` itself, named or piped, fails too, but with the binder's own error for a mandatory parameter, `ParameterArgumentValidationErrorNullNotAllowed`. Within the group that PowerShell did choose, an `AppliesTo`, `AccessType`, `InheritanceFlags`, or `PropagationFlags` value that PowerShell can't convert to its type, such as a blank cell or a misspelled name, is an `InvalidParameterValue` error for that object: the object is left unchanged, and the next one in the pipeline is still processed; the same bad value named on the command line fails the whole command instead. Before 5.0.0, such a piped value was silently ignored, and the object was handled as one without it. A script block is a plain value for these parameters, so a named script block, for example `-AppliesTo { 'FilesOnly' }`, fails with a terminating `InvalidParameterValue` error, the same as any other named value of the wrong type; before 5.0.0, a script block was evaluated once for each piped object. Before 5.0.0, a command that used `-SecurityDescriptor` without `-AppliesTo`, `-InheritanceFlags`, or `-PropagationFlags` failed, because PowerShell couldn't choose between the two `SD` sets.
When `-AccessType`, `-AppliesTo`, `-InheritanceFlags`, and `-PropagationFlags` are omitted, the cmdlet adds an `Allow` ACE that applies to this folder, subfolders, and files, which corresponds to the inheritance flags `ContainerInherit, ObjectInherit` and no propagation flags. An `Allow` ACE always receives the `Synchronize` right in addition to the requested rights, inheritance and propagation flags are ignored on files, and rights for an account that already has an ACE with the same access type and the same flags are merged into that ACE. The cmdlet writes no output unless `-PassThru` is used, and a failure on one item is reported as a non-terminating error while the remaining items are processed.
When `-AccessType`, `-AppliesTo`, `-InheritanceFlags`, and `-PropagationFlags` are omitted, the cmdlet adds an `Allow` ACE that applies to this folder, subfolders, and files, which corresponds to the inheritance flags `ContainerInherit, ObjectInherit` and no propagation flags. An `Allow` ACE always receives the `Synchronize` right in addition to the requested rights, inheritance and propagation flags are ignored on files, and rights for an account that already has an ACE with the same access type and the same flags are merged into that ACE. The cmdlet writes no output unless `-PassThru` is used, and a failure on one item is reported as a non-terminating error while the remaining items are processed.
Specifies whether the ACE allows or denies the rights in `-AccessRights`. The default is `Allow`. A `Deny` ACE takes precedence over `Allow` ACEs that grant the same rights.
Specifies whether the ACE allows or denies the rights in `-AccessRights`. The default is `Allow`. A `Deny` ACE takes precedence over `Allow` ACEs that grant the same rights. A value that cannot be converted to `Allow` or `Deny`, including a blank one, is an `InvalidParameterValue` error: terminating when `-AccessType` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline. The parameter takes one value: a comma list or a collection of several values is an `InvalidParameterValue` error too, because PowerShell would combine the numbers of the values bit by bit, so that one of them wins silently.
Specifies the scope of the ACE in the wording of the Windows security dialog, for example `ThisFolderOnly`, `ThisFolderAndSubfolders`, or `SubfoldersAndFilesOnly`. Without `-AppliesTo`, the cmdlet uses `-InheritanceFlags` and `-PropagationFlags`, whose defaults describe `ThisFolderSubfoldersAndFiles`. The cmdlet translates the value into the equivalent inheritance and propagation flags, so this parameter and the pair `-InheritanceFlags` and `-PropagationFlags` are two ways to describe the same ACE. The values ending in `OneLevel` limit inheritance to the direct children of the folder.
Specifies the scope of the ACE in the wording of the Windows security dialog, for example `ThisFolderOnly`, `ThisFolderAndSubfolders`, or `SubfoldersAndFilesOnly`. Without `-AppliesTo`, the cmdlet uses `-InheritanceFlags` and `-PropagationFlags`, whose defaults describe `ThisFolderSubfoldersAndFiles`. The cmdlet translates the value into the equivalent inheritance and propagation flags, so this parameter and the pair `-InheritanceFlags` and `-PropagationFlags` are two ways to describe the same ACE. The values ending in `OneLevel` limit inheritance to the direct children of the folder. A value that cannot be converted to one of these scopes, including a blank one, is an `InvalidParameterValue` error: terminating when `-AppliesTo` is named on the command line, and reported for just that path or descriptor, unchanged, when it comes from the pipeline. The parameter takes one value: a comma list or a collection of several values is an `InvalidParameterValue` error too, because PowerShell would combine the numbers of the values bit by bit, so that one of them wins silently or a scope that you did not name is selected.
Specifies which kind of child objects inherit the ACE. `ContainerInherit` passes the ACE on to child folders, `ObjectInherit` passes it on to child files, and `None` keeps the ACE on the item itself. The default is `ContainerInherit, ObjectInherit`. Inheritance flags have no effect on files, where the ACE is always created with `None`.
Specifies which kind of child objects inherit the ACE. `ContainerInherit` passes the ACE on to child folders, `ObjectInherit` passes it on to child files, and `None` keeps the ACE on the item itself. The default is `ContainerInherit, ObjectInherit`. Inheritance flags have no effect on files, where the ACE is always created with `None`. A value that cannot be converted to one of these flags, including a blank one, is an `InvalidParameterValue` error: terminating when `-InheritanceFlags` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline.
For details about the flags, see the .NET documentation of the [InheritanceFlags Enum](https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.inheritanceflags).
For details about the flags, see the .NET documentation of the [InheritanceFlags Enum](https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.inheritanceflags).
Specifies how the ACE is propagated to child objects. `None` propagates the ACE to all levels that the inheritance flags allow, `InheritOnly` keeps the ACE from applying to the item it is defined on, and `NoPropagateInherit` limits inheritance to the direct children of the folder. The default is `None`, and propagation flags only have an effect in combination with `-InheritanceFlags`.
Specifies how the ACE is propagated to child objects. `None` propagates the ACE to all levels that the inheritance flags allow, `InheritOnly` keeps the ACE from applying to the item it is defined on, and `NoPropagateInherit` limits inheritance to the direct children of the folder. The default is `None`, and propagation flags only have an effect in combination with `-InheritanceFlags`. A value that cannot be converted to one of these flags, including a blank one, is an `InvalidParameterValue` error: terminating when `-PropagationFlags` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline.
@ -46,7 +46,7 @@ The `Add-NTFSAudit` cmdlet adds an audit entry to the system access control list
In the `PathSimple` and `PathComplex` parameter sets the cmdlet reads the security descriptor of every item in `-Path`, adds the entry, and writes the descriptor back right away. In the `SDSimple` and `SDComplex` parameter sets it adds the entry to an in-memory `Security2.FileSystemSecurity2` object that `Get-NTFSSecurityDescriptor` returned; that change only reaches the file system when you pass the object to `Set-NTFSSecurityDescriptor`. The simple sets describe the scope of the entry with the single `-AppliesTo` parameter, the complex sets with `-InheritanceFlags` and `-PropagationFlags`.
In the `PathSimple` and `PathComplex` parameter sets the cmdlet reads the security descriptor of every item in `-Path`, adds the entry, and writes the descriptor back right away. In the `SDSimple` and `SDComplex` parameter sets it adds the entry to an in-memory `Security2.FileSystemSecurity2` object that `Get-NTFSSecurityDescriptor` returned; that change only reaches the file system when you pass the object to `Set-NTFSSecurityDescriptor`. The simple sets describe the scope of the entry with the single `-AppliesTo` parameter, the complex sets with `-InheritanceFlags` and `-PropagationFlags`.
A command without `-AppliesTo` uses a `Complex` set, also when it works on a security descriptor, and a command that has `-AppliesTo` together with `-InheritanceFlags` or `-PropagationFlags` fails, because PowerShell can't choose between the sets. The same holds for an object that you pipe in: its property `AppliesTo` selects a `Simple` set, its properties `InheritanceFlags` and `PropagationFlags` select a `Complex` set, and an object that has both kinds, an object that has both `Path` and `SecurityDescriptor`, or one whose `AppliesTo` is `$null`, fails. `Import-Csv` gives `$null` for a column that a row lacks because it has fewer fields than the header. An `AppliesTo` that PowerShell can't convert to a scope, such as the blank cell of a CSV file or a misspelled name, is ignored, and the object is handled as one without `AppliesTo`: it uses its own `InheritanceFlags` and `PropagationFlags`, or the default scope if it has none. Before 5.0.0, a command that used `-SecurityDescriptor` without `-AppliesTo`, `-InheritanceFlags`, or `-PropagationFlags` failed, because PowerShell couldn't choose between the two `SD` sets.
A command without `-AppliesTo` uses a `Complex` set, also when it works on a security descriptor, and a command that has `-AppliesTo` together with `-InheritanceFlags` or `-PropagationFlags` fails, because PowerShell can't choose between the sets. The same holds for an object that you pipe in: its property `AppliesTo` selects a `Simple` set, its properties `InheritanceFlags` and `PropagationFlags` select a `Complex` set, and an object that has both `Path` and `SecurityDescriptor` fails. A `$null`, an empty string, or `DBNull` value of a property counts as present for this choice, the same as a real value, so a CSV file, or any other source of piped objects, should have the columns of only one group: `AppliesTo`, or `InheritanceFlags` and `PropagationFlags`. A row or object that has properties of both groups is an `AmbiguousParameterSet` error, even if the value of one of them is `$null` (for example in a short CSV row, whose missing trailing columns `Import-Csv` fills with `$null`), an empty string, or `DBNull`: the error is terminating when you name the parameters on the command line, and it is reported for just that object, which is left unchanged, when the object comes from the pipeline. A `$null` value of `-AppliesTo` itself, named or piped, fails too, but with the binder's own error for a mandatory parameter, `ParameterArgumentValidationErrorNullNotAllowed`. Within the group that PowerShell did choose, an `AppliesTo`, `AuditFlags`, `InheritanceFlags`, or `PropagationFlags` value that PowerShell can't convert to its type, such as a blank cell or a misspelled name, is an `InvalidParameterValue` error for that object: the object is left unchanged, and the next one in the pipeline is still processed; the same bad value named on the command line fails the whole command instead. Before 5.0.0, such a piped value was silently ignored, and the object was handled as one without it. A script block is a plain value for these parameters, so a named script block, for example `-AppliesTo { 'FilesOnly' }`, fails with a terminating `InvalidParameterValue` error, the same as any other named value of the wrong type; before 5.0.0, a script block was evaluated once for each piped object. Before 5.0.0, a command that used `-SecurityDescriptor` without `-AppliesTo`, `-InheritanceFlags`, or `-PropagationFlags` failed, because PowerShell couldn't choose between the two `SD` sets.
When you omit them, `-AuditFlags` is `Success, Failure`, `-InheritanceFlags` is `ContainerInherit, ObjectInherit`, `-PropagationFlags` is `None`, and `-AppliesTo` is `ThisFolderSubfoldersAndFiles`, so both the simple and the complex set audit the item, its subfolders, and its files by default. Inheritance applies to folders only: when the item is a file, the cmdlet stores the entry without inheritance and propagation flags.
When you omit them, `-AuditFlags` is `Success, Failure`, `-InheritanceFlags` is `ContainerInherit, ObjectInherit`, `-PropagationFlags` is `None`, and `-AppliesTo` is `ThisFolderSubfoldersAndFiles`, so both the simple and the complex set audit the item, its subfolders, and its files by default. Inheritance applies to folders only: when the item is a file, the cmdlet stores the entry without inheritance and propagation flags.
Specifies the scope of the audit entry with a single value instead of the `-InheritanceFlags` and `-PropagationFlags` pair, in the same wording the Advanced Security Settings dialog uses. `ThisFolderOnly` audits the folder itself, `ThisFolderSubfoldersAndFiles` audits the folder and everything below it, `SubfoldersAndFilesOnly` audits the content but not the folder itself, and the values ending in `OneLevel` limit inheritance to the direct children. Without `-AppliesTo`, the cmdlet uses `-InheritanceFlags` and `-PropagationFlags`, whose defaults describe `ThisFolderSubfoldersAndFiles`.
Specifies the scope of the audit entry with a single value instead of the `-InheritanceFlags` and `-PropagationFlags` pair, in the same wording the Advanced Security Settings dialog uses. `ThisFolderOnly` audits the folder itself, `ThisFolderSubfoldersAndFiles` audits the folder and everything below it, `SubfoldersAndFilesOnly` audits the content but not the folder itself, and the values ending in `OneLevel` limit inheritance to the direct children. Without `-AppliesTo`, the cmdlet uses `-InheritanceFlags` and `-PropagationFlags`, whose defaults describe `ThisFolderSubfoldersAndFiles`. A value that cannot be converted to one of these scopes, including a blank one, is an `InvalidParameterValue` error: terminating when `-AppliesTo` is named on the command line, and reported for just that path or descriptor, unchanged, when it comes from the pipeline. The parameter takes one value: a comma list or a collection of several values is an `InvalidParameterValue` error too, because PowerShell would combine the numbers of the values bit by bit, so that one of them wins silently or a scope that you did not name is selected.
Specifies which access attempts are audited. `Success` audits attempts that succeeded, `Failure` audits attempts that were denied, and `Success, Failure` audits both. The default is `Success, Failure`.
Specifies which access attempts are audited. `Success` audits attempts that succeeded, `Failure` audits attempts that were denied, and `Success, Failure` audits both. The default is `Success, Failure`. A value that cannot be converted to one of these, including a blank one, is an `InvalidParameterValue` error: terminating when `-AuditFlags` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline.
Specifies which child items inherit the audit entry. `ContainerInherit` passes the entry on to child folders, `ObjectInherit` passes it on to child files, and `None` keeps the entry on the item itself. The values can be combined, and the default is `ContainerInherit, ObjectInherit`. Use `-PropagationFlags` to control whether the entry also applies to the item itself and how far it propagates.
Specifies which child items inherit the audit entry. `ContainerInherit` passes the entry on to child folders, `ObjectInherit` passes it on to child files, and `None` keeps the entry on the item itself. The values can be combined, and the default is `ContainerInherit, ObjectInherit`. Use `-PropagationFlags` to control whether the entry also applies to the item itself and how far it propagates. A value that cannot be converted to one of these flags, including a blank one, is an `InvalidParameterValue` error: terminating when `-InheritanceFlags` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline.
Specifies how the inheritance selected with `-InheritanceFlags` propagates. `None` applies the entry to the item itself and to all inheriting child items, `InheritOnly` applies it to the inheriting child items but not to the item itself, and `NoPropagateInherit` limits inheritance to the direct children. The values `InheritOnly` and `NoPropagateInherit` can be combined, and the default is `None`. The parameter has no effect when `-InheritanceFlags` is `None`.
Specifies how the inheritance selected with `-InheritanceFlags` propagates. `None` applies the entry to the item itself and to all inheriting child items, `InheritOnly` applies it to the inheriting child items but not to the item itself, and `NoPropagateInherit` limits inheritance to the direct children. The values `InheritOnly` and `NoPropagateInherit` can be combined, and the default is `None`. The parameter has no effect when `-InheritanceFlags` is `None`. A value that cannot be converted to one of these flags, including a blank one, is an `InvalidParameterValue` error: terminating when `-PropagationFlags` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline.
The `Get-ChildItem2` cmdlet lists the files and folders in the folders that you specify with `-Path`. It returns an `Alphaleonis.Win32.Filesystem.FileInfo` object for every file and an `Alphaleonis.Win32.Filesystem.DirectoryInfo` object for every folder. The cmdlet is the long-path counterpart of the built-in `Get-ChildItem` cmdlet: it enumerates the file system through the AlphaFS library (`Alphaleonis.Win32.Filesystem`) instead of `System.IO`, so it also returns items whose path is longer than the 260-character `MAX_PATH` limit.
The `Get-ChildItem2` cmdlet lists the files and folders in the folders that you specify with `-Path`. It returns an `Alphaleonis.Win32.Filesystem.FileInfo` object for every file and an `Alphaleonis.Win32.Filesystem.DirectoryInfo` object for every folder. The cmdlet is the long-path counterpart of the built-in `Get-ChildItem` cmdlet: it enumerates the file system through the AlphaFS library (`Alphaleonis.Win32.Filesystem`) instead of `System.IO`, so it also returns items whose path is longer than the 260-character `MAX_PATH` limit.
If you omit `-Path`, the cmdlet lists the current location. Relative paths and the `.` and `..` notations are resolved against the current location. Each path must name a folder, and wildcard characters are not supported. The parameter accepts pipeline input by value and by the property name `FullName`, so you can pipe folders from `Get-ChildItem2` or `Get-Item2` into another `Get-ChildItem2` call, and you can pipe the result into `Get-NTFSAccess` and the other NTFSSecurity cmdlets.
If you omit `-Path`, the cmdlet lists the current location. Relative paths and the `.` and `..` notations are resolved against the current location. Each path must name an existing folder or file, and wildcard characters are not supported. The parameter accepts pipeline input by value and by the property name `FullName`, so you can pipe folders from `Get-ChildItem2` or `Get-Item2` into another `Get-ChildItem2` call, and you can pipe the result into `Get-NTFSAccess` and the other NTFSSecurity cmdlets.
By default the cmdlet returns the immediate content of each folder and omits hidden items. Use `-Recurse` to walk the whole tree, `-Depth` to limit how deep the recursion goes, `-Filter` to restrict the result by name, `-Directory` or `-File` to restrict it by item type, and `-Force`, `-Hidden`, `-System`, `-ReadOnly`, or `-Attributes` to restrict it by file attributes.
By default the cmdlet returns the immediate content of each folder and omits hidden items. Use `-Recurse` to walk the whole tree, `-Depth` to limit how deep the recursion goes, `-Filter` to restrict the result by name, `-Directory` or `-File` to restrict it by item type, and `-Force`, `-Hidden`, `-System`, `-ReadOnly`, or `-Attributes` to restrict it by file attributes.
Specifies a name pattern that an item must match to be returned. The pattern supports the asterisk and the question mark as wildcard characters, an asterisk for any number of characters and a question mark for exactly one, and the match ignores case. Any other character stands for itself; a bracket is an ordinary character, so `Report[1].txt` returns the file of that name. As for `Get-ChildItem`, a pattern of an asterisk, a dot, and an asterisk returns every item, also an item without a dot in its name. The default value is `*`, which returns every item. The pattern is applied to the name of each item, not to its path, and during a recursive listing it restricts only the returned items; the cmdlet still descends into every subfolder.
Specifies a name pattern that an item must match to be returned. The pattern follows the wildcard rules that Windows PowerShell 5.1 applies to `Get-ChildItem -Filter`, in both editions, on the real name of the item, not its 8.3 short name. An asterisk stands for a run of any characters, and a question mark stands for one character that is not a dot, or for nothing where a dot or the end of the name follows. A dot stands for a literal dot, or for nothing where only wildcards or the end of the pattern follow. The match ignores case and is not affected by the culture of the session. Any other character stands for itself, including a bracket, so `Report[1].txt` returns the file of that name.
For example, `Report.*` also returns the item `Report`, which has no dot.
A pattern of an asterisk, a dot, and an asterisk returns every item, also an item without a dot in its name, as `Get-ChildItem` does for this pattern.
`Get-ChildItem2` follows the Windows PowerShell 5.1 rules in both editions, so the result does not depend on the edition. The built-in `Get-ChildItem -Filter` of PowerShell 7 differs for some patterns, for example for a pattern that ends in a dot, for which it returns nothing unless an asterisk comes right before the dot (the pattern of a single dot returns every item), and for a pattern in which an asterisk is followed by a dot and question marks, for which it ignores the dot and the question marks.
Two kinds of pattern are not like Windows PowerShell 5.1: blanks at the end of the pattern, also before a final dot, are part of it, where Windows PowerShell 5.1 drops them, and a pattern that ends in an even number of dots, such as two, is accepted, where Windows PowerShell 5.1 stops with an error.
The default value is `*`, which returns every item, and an empty value also returns every item. The pattern is applied to the name of each item, not to its path, and during a recursive listing it restricts only the returned items; the cmdlet still descends into every subfolder.
```yaml
```yaml
Type: String
Type: String
@ -319,7 +329,11 @@ Before 5.0.0, a `-Path` value that points to a file stopped the cmdlet with an `
Before 5.0.0, `-Filter` read a bracket as the start of a character class, so a file with brackets in its name, such as `Report[1].txt`, was not returned for its name, and a pattern of an asterisk, a dot, and an asterisk dropped the items without a dot in their names, most folders among them.
Before 5.0.0, `-Filter` read a bracket as the start of a character class, so a file with brackets in its name, such as `Report[1].txt`, was not returned for its name, and a pattern of an asterisk, a dot, and an asterisk dropped the items without a dot in their names, most folders among them.
The names are matched twice, by the enumeration of the AlphaFS library and by the cmdlet, which reads a dot as an ordinary character, and their rules for a dot can differ from those of `Get-ChildItem`: a pattern such as `Report.*` does not return the file `Report`, which has no dot, a pattern that ends in a dot returns nothing, and an empty value returns nothing. Only the pattern of an asterisk, a dot, and an asterisk is treated as a single asterisk.
The cmdlet enumerates broadly and matches each name once, with the Win32 "DOS" wildcard rules that Windows PowerShell 5.1 applies to `Get-ChildItem -Filter`, in both editions: a pattern that ends in a dot returns the names without a dot, and an empty value returns every item, the same as a plain asterisk.
For example, `Report.*` also returns the item `Report`, which has no dot. A star in front of a dot token may cross every dot in the name but the last one, so a pattern such as a star followed by a dot also reaches the final segment of a name with two or more dots, for example `archive.tar.gz`.
PowerShell 7 itself differs from Windows PowerShell 5.1 here: its own `Get-ChildItem -Filter` returns nothing for a pattern that ends in a dot, unless the character right before the dot is an asterisk (the pattern of a single dot returns every item), and it ignores the dot and the question marks of a pattern in which an asterisk is followed by a dot and question marks. `Get-ChildItem2` follows the Windows PowerShell 5.1 rules in both editions instead of the edition it runs in, so this is a deliberate difference from the built-in `Get-ChildItem` in PowerShell 7 for these and some similar patterns.
Before 5.0.0, a `break`, a `continue`, or a `throw` in a later command of the pipeline did not end the cmdlet for an item below the first folder, also when the later command took the error of a folder that the cmdlet cannot read, for example with `2>&1`.
Before 5.0.0, a `break`, a `continue`, or a `throw` in a later command of the pipeline did not end the cmdlet for an item below the first folder, also when the later command took the error of a folder that the cmdlet cannot read, for example with `2>&1`.
@ -190,6 +190,8 @@ Before 5.0.0-rc7, a user who wasn't an administrator got the error "Access is de
Before 5.0.0-rc8, the cmdlet returned no access and no error when Windows refused to start the authorization manager for the computer of `-ServerName`, for example for a name of 32,718 characters or more, so that the result looked like an account without any rights. The cmdlet now writes a non-terminating `GetEffectiveAccessError` with the error that Windows reported and returns no result for the item, as it does for every other failure of the calculation. It warns that the result is based on this computer only when it calculated a result; before 5.0.0-rc8, the warning also came before an error when the computer couldn't be reached.
Before 5.0.0-rc8, the cmdlet returned no access and no error when Windows refused to start the authorization manager for the computer of `-ServerName`, for example for a name of 32,718 characters or more, so that the result looked like an account without any rights. The cmdlet now writes a non-terminating `GetEffectiveAccessError` with the error that Windows reported and returns no result for the item, as it does for every other failure of the calculation. It warns that the result is based on this computer only when it calculated a result; before 5.0.0-rc8, the warning also came before an error when the computer couldn't be reached.
A user who has no domain credentials, such as a local standard user, still gets the error "Access is denied" from Windows when it asks for the effective access of a user account of the domain, also for a name of this computer; the cmdlet writes it as a non-terminating `GetEffectiveAccessError` and returns no result for that item. Accounts of this computer and groups such as `Everyone` or `Domain Users` give a result.
@ -174,6 +174,8 @@ When the module setting `EnablePrivileges` is `$true` (the default in the `Priva
If the ACL of an item cannot be read because access is denied, the cmdlet tries once more after making the current account the owner of the item, and restores the previous owner afterwards. Reading the owner, which that fallback needs first, requires the same Read Permissions right as reading the ACL, so the cmdlet then writes a non-terminating `ReadSecurityError` and continues with the next item. Before 5.0.0, it reported that error as an `AddAceError`.
If the ACL of an item cannot be read because access is denied, the cmdlet tries once more after making the current account the owner of the item, and restores the previous owner afterwards. Reading the owner, which that fallback needs first, requires the same Read Permissions right as reading the ACL, so the cmdlet then writes a non-terminating `ReadSecurityError` and continues with the next item. Before 5.0.0, it reported that error as an `AddAceError`.
A read failure that is not an access denial is reported the same way, as a non-terminating `ReadSecurityError`, categorized as `OpenError` and targeting the path; before 5.0.0-rc9, the cmdlet wrote a warning instead (`Could not read item {0}. The error was: {1}`) and returned no entry for the item, without an error to say why.
Before 5.0.0, the cmdlet ignored `-Account` and `-SecurityDescriptor`, and after a path whose ACL could not be read, it returned the orphaned entries of the previous item again.
Before 5.0.0, the cmdlet ignored `-Account` and `-SecurityDescriptor`, and after a path whose ACL could not be read, it returned the orphaned entries of the previous item again.
@ -48,7 +48,7 @@ Only the specified rights are taken away: when an entry grants more than `-Acces
Inherited entries cannot be removed from the item that inherits them. Remove them from the folder named in the `InheritedFrom` property, or run `Disable-NTFSAccessInheritance` on the item first, which copies the inherited entries into it as explicit ones that this cmdlet can then remove.
Inherited entries cannot be removed from the item that inherits them. Remove them from the folder named in the `InheritedFrom` property, or run `Disable-NTFSAccessInheritance` on the item first, which copies the inherited entries into it as explicit ones that this cmdlet can then remove.
The cmdlet has four parameter sets. The `Path` sets read the item from disk and write the changed DACL back immediately, while the `SD` sets change a `Security2.FileSystemSecurity2` object returned by `Get-NTFSSecurityDescriptor` in memory until `Set-NTFSSecurityDescriptor` writes it back. The `Simple` sets take `-AppliesTo`, the `Complex` sets take `-InheritanceFlags` and `-PropagationFlags`. A command without `-AppliesTo` uses a `Complex` set, also when it works on a security descriptor, and a command that has `-AppliesTo` together with `-InheritanceFlags` or `-PropagationFlags` fails, because PowerShell can't choose between the sets. The same holds for an object that you pipe in: its property `AppliesTo` selects a `Simple` set, its properties `InheritanceFlags` and `PropagationFlags` select a `Complex` set, and an object that has both kinds, an object that has both `Path` and `SecurityDescriptor`, or one whose `AppliesTo` is `$null`, fails. `Import-Csv` gives `$null` for a column that a row lacks because it has fewer fields than the header. An `AppliesTo` that PowerShell can't convert to a scope, such as the blank cell of a CSV file or a misspelled name, is ignored, and the object is handled as one without `AppliesTo`: it uses its own `InheritanceFlags` and `PropagationFlags`, or the default scope if it has none. Before 5.0.0, a command that used `-SecurityDescriptor` without `-AppliesTo`, `-InheritanceFlags`, or `-PropagationFlags` failed, because PowerShell couldn't choose between the two `SD` sets. All relevant parameters bind by property name, so the output of `Get-NTFSAccess` and `Get-NTFSOrphanedAccess` can be piped directly into this cmdlet. The cmdlet writes no output unless `-PassThru` is used.
The cmdlet has four parameter sets. The `Path` sets read the item from disk and write the changed DACL back immediately, while the `SD` sets change a `Security2.FileSystemSecurity2` object returned by `Get-NTFSSecurityDescriptor` in memory until `Set-NTFSSecurityDescriptor` writes it back. The `Simple` sets take `-AppliesTo`, the `Complex` sets take `-InheritanceFlags` and `-PropagationFlags`. A command without `-AppliesTo` uses a `Complex` set, also when it works on a security descriptor, and a command that has `-AppliesTo` together with `-InheritanceFlags` or `-PropagationFlags` fails, because PowerShell can't choose between the sets. The same holds for an object that you pipe in: its property `AppliesTo` selects a `Simple` set, its properties `InheritanceFlags` and `PropagationFlags` select a `Complex` set, and an object that has both `Path` and `SecurityDescriptor` fails. A `$null`, an empty string, or `DBNull` value of a property counts as present for this choice, the same as a real value, so a CSV file, or any other source of piped objects, should have the columns of only one group: `AppliesTo`, or `InheritanceFlags` and `PropagationFlags`. A row or object that has properties of both groups is an `AmbiguousParameterSet` error, even if the value of one of them is `$null` (for example in a short CSV row, whose missing trailing columns `Import-Csv` fills with `$null`), an empty string, or `DBNull`: the error is terminating when you name the parameters on the command line, and it is reported for just that object, which is left unchanged, when the object comes from the pipeline. A `$null` value of `-AppliesTo` itself, named or piped, fails too, but with the binder's own error for a mandatory parameter, `ParameterArgumentValidationErrorNullNotAllowed`. Within the group that PowerShell did choose, an `AppliesTo`, `AccessType`, `InheritanceFlags`, or `PropagationFlags` value that PowerShell can't convert to its type, such as a blank cell or a misspelled name, is an `InvalidParameterValue` error for that object: the object is left unchanged, and the next one in the pipeline is still processed; the same bad value named on the command line fails the whole command instead. Before 5.0.0, such a piped value was silently ignored, and the object was handled as one without it. A script block is a plain value for these parameters, so a named script block, for example `-AppliesTo { 'FilesOnly' }`, fails with a terminating `InvalidParameterValue` error, the same as any other named value of the wrong type; before 5.0.0, a script block was evaluated once for each piped object. Before 5.0.0, a command that used `-SecurityDescriptor` without `-AppliesTo`, `-InheritanceFlags`, or `-PropagationFlags` failed, because PowerShell couldn't choose between the two `SD` sets. All relevant parameters bind by property name, so the output of `Get-NTFSAccess` and `Get-NTFSOrphanedAccess` can be piped directly into this cmdlet. The cmdlet writes no output unless `-PassThru` is used.
Specifies whether an `Allow` or a `Deny` entry is addressed. The default is `Allow`. An entry of the other type is not touched.
Specifies whether an `Allow` or a `Deny` entry is addressed. The default is `Allow`. An entry of the other type is not touched. A value that cannot be converted to `Allow` or `Deny`, including a blank one, is an `InvalidParameterValue` error: terminating when `-AccessType` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline. The parameter takes one value: a comma list or a collection of several values is an `InvalidParameterValue` error too, because PowerShell would combine the numbers of the values bit by bit, so that one of them wins silently.
Specifies the scope of the entry that is addressed, in the wording of the Windows security dialog, for example `ThisFolderOnly`, `ThisFolderAndSubfolders`, or `SubfoldersAndFilesOnly`. The cmdlet translates the value into the equivalent inheritance and propagation flags, so this parameter and the pair `-InheritanceFlags` and `-PropagationFlags` are two ways to describe the same entry. Use the scope that `Get-NTFSAccess` shows in the "Applies to" column of the entry.
Specifies the scope of the entry that is addressed, in the wording of the Windows security dialog, for example `ThisFolderOnly`, `ThisFolderAndSubfolders`, or `SubfoldersAndFilesOnly`. The cmdlet translates the value into the equivalent inheritance and propagation flags, so this parameter and the pair `-InheritanceFlags` and `-PropagationFlags` are two ways to describe the same entry. Use the scope that `Get-NTFSAccess` shows in the "Applies to" column of the entry. A value that cannot be converted to one of these scopes, including a blank one, is an `InvalidParameterValue` error: terminating when `-AppliesTo` is named on the command line, and reported for just that path or descriptor, unchanged, when it comes from the pipeline. The parameter takes one value: a comma list or a collection of several values is an `InvalidParameterValue` error too, because PowerShell would combine the numbers of the values bit by bit, so that one of them wins silently or a scope that you did not name is selected.
Specifies the inheritance flags of the entry that is addressed. `ContainerInherit` marks an entry that child folders inherit, `ObjectInherit` marks an entry that child files inherit, and `None` marks an entry that is not inherited at all. The default is `ContainerInherit, ObjectInherit`, which is the scope `ThisFolderSubfoldersAndFiles`. Entries on files always carry `None`.
Specifies the inheritance flags of the entry that is addressed. `ContainerInherit` marks an entry that child folders inherit, `ObjectInherit` marks an entry that child files inherit, and `None` marks an entry that is not inherited at all. The default is `ContainerInherit, ObjectInherit`, which is the scope `ThisFolderSubfoldersAndFiles`. Entries on files always carry `None`. A value that cannot be converted to one of these flags, including a blank one, is an `InvalidParameterValue` error: terminating when `-InheritanceFlags` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline.
Specifies the propagation flags of the entry that is addressed. `None` marks an entry that is inherited by all levels allowed by its inheritance flags, `InheritOnly` marks an entry that does not apply to the item it is defined on, and `NoPropagateInherit` marks an entry that is only inherited by the direct children of the folder. The default is `None`.
Specifies the propagation flags of the entry that is addressed. `None` marks an entry that is inherited by all levels allowed by its inheritance flags, `InheritOnly` marks an entry that does not apply to the item it is defined on, and `NoPropagateInherit` marks an entry that is only inherited by the direct children of the folder. The default is `None`. A value that cannot be converted to one of these flags, including a blank one, is an `InvalidParameterValue` error: terminating when `-PropagationFlags` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline.
@ -46,7 +46,7 @@ The `Remove-NTFSAudit` cmdlet removes an audit entry from the system access cont
Because the inheritance and propagation flags take part in the match, they must describe the entry you want to remove. `-AppliesTo ThisFolderOnly` removes an entry that is not inherited by child items, which is also the shape of every audit entry on a file, while the default of the complex parameter sets removes an entry that applies to the folder, its subfolders, and its files. An entry that an item inherits from a parent folder is stored on that parent, so remove it there, or use `Clear-NTFSAudit` with `-DisableInheritance` to drop the inherited entries on the item.
Because the inheritance and propagation flags take part in the match, they must describe the entry you want to remove. `-AppliesTo ThisFolderOnly` removes an entry that is not inherited by child items, which is also the shape of every audit entry on a file, while the default of the complex parameter sets removes an entry that applies to the folder, its subfolders, and its files. An entry that an item inherits from a parent folder is stored on that parent, so remove it there, or use `Clear-NTFSAudit` with `-DisableInheritance` to drop the inherited entries on the item.
In the `PathSimple` and `PathComplex` parameter sets the cmdlet reads the security descriptor of every item in `-Path` and writes it back right away. In the `SDSimple` and `SDComplex` parameter sets it changes an in-memory `Security2.FileSystemSecurity2` object that `Get-NTFSSecurityDescriptor` returned, and the change reaches the file system only when you pass the object to `Set-NTFSSecurityDescriptor`. A command without `-AppliesTo` uses a `Complex` set, also when it works on a security descriptor, and a command that has `-AppliesTo` together with `-InheritanceFlags` or `-PropagationFlags` fails, because PowerShell can't choose between the sets. The same holds for an object that you pipe in: its property `AppliesTo` selects a `Simple` set, its properties `InheritanceFlags` and `PropagationFlags` select a `Complex` set, and an object that has both kinds, an object that has both `Path` and `SecurityDescriptor`, or one whose `AppliesTo` is `$null`, fails. `Import-Csv` gives `$null` for a column that a row lacks because it has fewer fields than the header. An `AppliesTo` that PowerShell can't convert to a scope, such as the blank cell of a CSV file or a misspelled name, is ignored, and the object is handled as one without `AppliesTo`: it uses its own `InheritanceFlags` and `PropagationFlags`, or the default scope if it has none. Before 5.0.0, a command that used `-SecurityDescriptor` without `-AppliesTo`, `-InheritanceFlags`, or `-PropagationFlags` failed, because PowerShell couldn't choose between the two `SD` sets.
In the `PathSimple` and `PathComplex` parameter sets the cmdlet reads the security descriptor of every item in `-Path` and writes it back right away. In the `SDSimple` and `SDComplex` parameter sets it changes an in-memory `Security2.FileSystemSecurity2` object that `Get-NTFSSecurityDescriptor` returned, and the change reaches the file system only when you pass the object to `Set-NTFSSecurityDescriptor`. A command without `-AppliesTo` uses a `Complex` set, also when it works on a security descriptor, and a command that has `-AppliesTo` together with `-InheritanceFlags` or `-PropagationFlags` fails, because PowerShell can't choose between the sets. The same holds for an object that you pipe in: its property `AppliesTo` selects a `Simple` set, its properties `InheritanceFlags` and `PropagationFlags` select a `Complex` set, and an object that has both `Path` and `SecurityDescriptor` fails. A `$null`, an empty string, or `DBNull` value of a property counts as present for this choice, the same as a real value, so a CSV file, or any other source of piped objects, should have the columns of only one group: `AppliesTo`, or `InheritanceFlags` and `PropagationFlags`. A row or object that has properties of both groups is an `AmbiguousParameterSet` error, even if the value of one of them is `$null` (for example in a short CSV row, whose missing trailing columns `Import-Csv` fills with `$null`), an empty string, or `DBNull`: the error is terminating when you name the parameters on the command line, and it is reported for just that object, which is left unchanged, when the object comes from the pipeline. A `$null` value of `-AppliesTo` itself, named or piped, fails too, but with the binder's own error for a mandatory parameter, `ParameterArgumentValidationErrorNullNotAllowed`. Within the group that PowerShell did choose, an `AppliesTo`, `AuditFlags`, `InheritanceFlags`, or `PropagationFlags` value that PowerShell can't convert to its type, such as a blank cell or a misspelled name, is an `InvalidParameterValue` error for that object: the object is left unchanged, and the next one in the pipeline is still processed; the same bad value named on the command line fails the whole command instead. Before 5.0.0, such a piped value was silently ignored, and the object was handled as one without it. A script block is a plain value for these parameters, so a named script block, for example `-AppliesTo { 'FilesOnly' }`, fails with a terminating `InvalidParameterValue` error, the same as any other named value of the wrong type; before 5.0.0, a script block was evaluated once for each piped object. Before 5.0.0, a command that used `-SecurityDescriptor` without `-AppliesTo`, `-InheritanceFlags`, or `-PropagationFlags` failed, because PowerShell couldn't choose between the two `SD` sets.
When you omit them, `-AuditFlags` is `Success, Failure`, `-InheritanceFlags` is `ContainerInherit, ObjectInherit`, `-PropagationFlags` is `None`. All parameters bind by property name, and `-Path` also binds by value and through its `FullName` alias, so you can pipe the output of `Get-NTFSAudit`, `Get-ChildItem`, `Get-ChildItem2`, and `Get-Item2` into the cmdlet. The cmdlet writes no object unless you use `-PassThru`.
When you omit them, `-AuditFlags` is `Success, Failure`, `-InheritanceFlags` is `ContainerInherit, ObjectInherit`, `-PropagationFlags` is `None`. All parameters bind by property name, and `-Path` also binds by value and through its `FullName` alias, so you can pipe the output of `Get-NTFSAudit`, `Get-ChildItem`, `Get-ChildItem2`, and `Get-Item2` into the cmdlet. The cmdlet writes no object unless you use `-PassThru`.
Specifies the scope of the audit entry to remove with a single value instead of the `-InheritanceFlags` and `-PropagationFlags` pair, in the same wording the Advanced Security Settings dialog uses. The value must describe the entry as `Get-NTFSAudit` reports it, otherwise nothing is removed. Without `-AppliesTo`, the cmdlet uses `-InheritanceFlags` and `-PropagationFlags`, whose defaults describe `ThisFolderSubfoldersAndFiles`.
Specifies the scope of the audit entry to remove with a single value instead of the `-InheritanceFlags` and `-PropagationFlags` pair, in the same wording the Advanced Security Settings dialog uses. The value must describe the entry as `Get-NTFSAudit` reports it, otherwise nothing is removed. Without `-AppliesTo`, the cmdlet uses `-InheritanceFlags` and `-PropagationFlags`, whose defaults describe `ThisFolderSubfoldersAndFiles`. A value that cannot be converted to one of these scopes, including a blank one, is an `InvalidParameterValue` error: terminating when `-AppliesTo` is named on the command line, and reported for just that path or descriptor, unchanged, when it comes from the pipeline. The parameter takes one value: a comma list or a collection of several values is an `InvalidParameterValue` error too, because PowerShell would combine the numbers of the values bit by bit, so that one of them wins silently or a scope that you did not name is selected.
Specifies which audited access attempts are removed from the entry. `Success` removes the auditing of successful attempts, `Failure` removes the auditing of denied attempts, and `Success, Failure` removes both. An entry that audits the flag you did not specify stays in place with that flag. The default is `Success, Failure`.
Specifies which audited access attempts are removed from the entry. `Success` removes the auditing of successful attempts, `Failure` removes the auditing of denied attempts, and `Success, Failure` removes both. An entry that audits the flag you did not specify stays in place with that flag. The default is `Success, Failure`. A value that cannot be converted to one of these, including a blank one, is an `InvalidParameterValue` error: terminating when `-AuditFlags` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline.
Specifies the inheritance flags of the audit entry to remove. `ContainerInherit` addresses an entry that child folders inherit, `ObjectInherit` an entry that child files inherit, and `None` an entry that stays on the item itself. The values can be combined, and the default is `ContainerInherit, ObjectInherit`. The flags must match the entry as `Get-NTFSAudit` reports it, otherwise nothing is removed.
Specifies the inheritance flags of the audit entry to remove. `ContainerInherit` addresses an entry that child folders inherit, `ObjectInherit` an entry that child files inherit, and `None` an entry that stays on the item itself. The values can be combined, and the default is `ContainerInherit, ObjectInherit`. The flags must match the entry as `Get-NTFSAudit` reports it, otherwise nothing is removed. A value that cannot be converted to one of these flags, including a blank one, is an `InvalidParameterValue` error: terminating when `-InheritanceFlags` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline.
Specifies the propagation flags of the audit entry to remove. `None` addresses an entry that applies to the item itself and to all inheriting child items, `InheritOnly` an entry that applies to the child items only, and `NoPropagateInherit` an entry whose inheritance stops at the direct children. The values `InheritOnly` and `NoPropagateInherit` can be combined, and the default is `None`.
Specifies the propagation flags of the audit entry to remove. `None` addresses an entry that applies to the item itself and to all inheriting child items, `InheritOnly` an entry that applies to the child items only, and `NoPropagateInherit` an entry whose inheritance stops at the direct children. The values `InheritOnly` and `NoPropagateInherit` can be combined, and the default is `None`. A value that cannot be converted to one of these flags, including a blank one, is an `InvalidParameterValue` error: terminating when `-PropagationFlags` is named on the command line, and reported for just that item, unchanged, when it comes from the pipeline.
// it never ran, because BeginProcessing always failed first with its own uncaught cast.
}
enablePrivileges=GetEnablePrivilegesSetting();
catch(Exceptionex)
{
thrownewParseException("Could not parse the module's PrivateData field in the module's psd1 file. Please refer to the documentation for further details",ex);
}
//if the command is called from NTFSSecurity.Init.ps1 and EnablePrivileges is set to true in the NTFSSecurity.psd1 or if the cmdlet is called from somewhere else
//if the command is called from NTFSSecurity.Init.ps1 and EnablePrivileges is set to true in the NTFSSecurity.psd1 or if the cmdlet is called from somewhere else
# A blank cell that Import-Csv reads is an empty string: not $null, and not a scope name. The binder cannot convert it, so
# A blank cell that Import-Csv reads is an empty string: not $null, and not a scope name. Since -AppliesTo is
# PathSimple does not bind, and the row gets the default scope, as an object without the property does.
# now an object parameter (Decision 27, fix B), the blank string still binds it, which selects PathSimple,
It'Should give the row of a CSV file whose AppliesTo cell is blank the default scope, and the other rows their own'{
# so the row gets an InvalidParameterValue error instead of the default scope; the other rows are unaffected.
It'Should write an InvalidParameterValue error for the row of a CSV file whose AppliesTo cell is blank, leave its folder alone, and still give the other rows their own scope'{
# Item 5 of Decision 27: a failing change to one of several descriptors (a Deny entry without rights, which .NET
# refuses to build, the same as Access.Tests.ps1:774 pins for -Path) reports an error for that descriptor and goes
# on with the next one, instead of ending the cmdlet with a terminating error.
Context'A failing change to one of several descriptors'{
It'Should write an AddAceError for the descriptor whose change fails in the SDSimple set, continue with the next, and return -PassThru only for the one that succeeded'{
It'Should write an AddAceError for the descriptor whose change fails in the SDComplex set, continue with the next, and return -PassThru only for the one that succeeded'{
# Item 5 of Decision 27: a failing change to one of several descriptors (a Deny entry without rights, which .NET
# refuses to build, the same as Access.Tests.ps1:571 pins for -Path) reports an error for that descriptor and goes
# on with the next one, instead of ending the cmdlet with a terminating error.
Context'A failing change to one of several descriptors'{
It'Should write a RemoveAceError for the descriptor whose change fails in the SDSimple set, continue with the next, and return -PassThru only for the one that succeeded'{
It'Should write a RemoveAceError for the descriptor whose change fails in the SDComplex set, continue with the next, and return -PassThru only for the one that succeeded'{
# AccessType and AppliesTo name one value each, not a combination: PowerShell combines the numbers of a list bit by
# bit, so that one of the values wins silently or, for AppliesTo, a scope that the caller did not name is chosen.
# Every kind of collection counts, also a collection of one element that holds a list.
$accessAppliesToListShapes=@(
@{Shape='a comma list of two names';Value='ThisFolderAndSubfolders,ThisFolderAndFiles';ValueText='ThisFolderAndSubfolders,ThisFolderAndFiles'}
@{Shape='an array of two names';Value=@('ThisFolderAndSubfolders','ThisFolderAndFiles');ValueText='ThisFolderAndSubfolders, ThisFolderAndFiles'}
@{Shape='an array of one comma list';Value=@('ThisFolderAndSubfolders,ThisFolderAndFiles');ValueText='ThisFolderAndSubfolders,ThisFolderAndFiles'}
@{Shape='a hash set of two names';Value=[System.Collections.Generic.HashSet[string]]::new([string[]]@('ThisFolderAndSubfolders','ThisFolderAndFiles'));ValueText=$null}
@{Shape='the keys of a hashtable';Value=(@{ThisFolderAndSubfolders=1;ThisFolderAndFiles=2}).Keys;ValueText=$null}
@{Cmdlet='Add-NTFSAccess';Parameter='AccessType';Shape='a generic list of one object whose ToString throws';Value=[System.Collections.Generic.List[object]]::new([object[]]@($accessThrowingElement));ValueText='System.Collections.Generic.List`1[System.Object]'}
@{Cmdlet='Add-NTFSAccess';Parameter='InheritanceFlags';Shape='a generic list of one object whose ToString throws';Value=[System.Collections.Generic.List[object]]::new([object[]]@($accessThrowingElement));ValueText='System.Collections.Generic.List`1[System.Object]'}
It'Should write one InvalidParameterValue error for <Cmdlet> -<Parameter> (<Shape>), change nothing, and still process the next object'-ForEach$accessInvalidParameterCases{
It'Should write one InvalidParameterValue error per descriptor for <Cmdlet> -<Parameter> bound to a piped descriptor, and leave the descriptors unchanged'-ForEach$accessSdInvalidParameterCases{
It'Should give the row without <Parameter> its own default after a preceding row with an invalid value, with no carry-over'-ForEach$accessNoCarryOverCases{
It'Should throw a terminating InvalidParameterValue error for <Cmdlet> -<Parameter>, catchable with try/catch, and change nothing'-ForEach$accessNamedInvalidParameterCases{
Context'Choosing the parameter set with a mix of string and enum values'{
It'Should reject a piped object whose AppliesTo is <AppliesToShape> combined with InheritanceFlags as <FlagShape> with an AmbiguousParameterSet error'-ForEach$accessAmbiguousValueCases{
It'Should reject a named call whose -AppliesTo is <AppliesToShape> combined with -PropagationFlags as <FlagShape> with an AmbiguousParameterSet error'-ForEach$accessAmbiguousValueCases{
# A typed parameter skips a $null, an empty string, or DBNull value of a property, and the entry was created for
# every shape below; the object-typed parameters count such a value of a property of the other group as present
# too, so PowerShell cannot resolve the parameter set and nothing is changed.
Context'A blank value of a property of the other group'{
It'Should reject <Cmdlet> (<TargetKind>) for <Direction> (<Shape>) with the error the binder gives, change nothing, and still process the next object'-ForEach$accessAmbiguousOtherGroupCases{
# With the object type, a script block is a plain value (a typed parameter evaluates it once per piped object),
# so ValidateNamedValue in BeginProcessing rejects it the same as any other bad value, before any piped object
# is processed.
Context'A named script block is a terminating error'{
It'Should throw a terminating InvalidParameterValue error for a named script block value of <Cmdlet> -<Parameter>, and change nothing'-ForEach$accessScriptBlockCases{
It'Should complete Add-NTFSAccess -<Parameter> for the unquoted, single-quoted, double-quoted, and wildcard forms of <ExpectedName>'-ForEach$accessCompletionFormCases{
$base='Add-NTFSAccess -Path C:\x -Account a -AccessRights Read -{0} '-f$Parameter
# A blank cell that Import-Csv reads is an empty string, not $null: the row gets the default scope (ParameterSets.Access.Tests.ps1
# A blank cell that Import-Csv reads is an empty string, not $null. Since -AppliesTo is now an object
# has the same rows and says why).
# parameter (Decision 27, fix B), the blank string still binds it, which selects PathSimple, so the row gets
It'Should give the row of a CSV file whose AppliesTo cell is blank the default scope, and the other rows their own'-Skip:(-not$canReadAudit){
# an InvalidParameterValue error instead of the default scope (ParameterSets.Access.Tests.ps1 has the same rows).
It'Should write an InvalidParameterValue error for the row of a CSV file whose AppliesTo cell is blank, leave its folder alone, and still give the other rows their own scope'-Skip:(-not$canReadAudit){
# Item 5 of Decision 27: a failing change to one of several descriptors (an audit entry without rights, which
# .NET refuses to build, the same as Audit.Tests.ps1:141 pins for -Path) reports an error for that descriptor and
# goes on with the next one, instead of ending the cmdlet with a terminating error.
Context'A failing change to one of several descriptors'{
It'Should write an AddAceError for the descriptor whose change fails in the SDSimple set, continue with the next, and return -PassThru only for the one that succeeded'-Skip:(-not$canReadAudit){
It'Should write an AddAceError for the descriptor whose change fails in the SDComplex set, continue with the next, and return -PassThru only for the one that succeeded'-Skip:(-not$canReadAudit){
# Item 5 of Decision 27: a failing change to one of several descriptors (an audit entry without rights, which
# .NET refuses to build, the same as Audit.Tests.ps1:141 pins for -Path) reports an error for that descriptor and
# goes on with the next one, instead of ending the cmdlet with a terminating error. Only the SDComplex set is
# listed as open in Quality-Gate-Test-Round-2026-10-20-ParameterSets.csv (row 26); SDSimple is already closed.
Context'A failing change to one of several descriptors'{
It'Should write a RemoveAceError for the descriptor whose change fails in the SDComplex set, continue with the next, and return -PassThru only for the one that succeeded'-Skip:(-not$canReadAudit){
@{Shape='an array of one misspelled name';Value=@('Failurre');ValueText='Failurre'}
@{Shape='an array of one object whose ToString throws';Value=@($auditThrowingElement);ValueText=$null}
)
# The cross product of the two cmdlets that share these parameters and every bad shape: 2 * (7 + 3 * 7 + 6) = 68 rows.
# AppliesTo names one value, not a combination: PowerShell combines the numbers of a list bit by bit, so that one
# of the values wins silently or a scope that the caller did not name is chosen. AuditFlags and the two flags
# parameters take a list. Every kind of collection counts, also a collection of one element that holds a list.
$auditAppliesToListShapes=@(
@{Shape='a comma list of two names';Value='ThisFolderAndSubfolders,ThisFolderAndFiles';ValueText='ThisFolderAndSubfolders,ThisFolderAndFiles'}
@{Shape='an array of two names';Value=@('ThisFolderAndSubfolders','ThisFolderAndFiles');ValueText='ThisFolderAndSubfolders, ThisFolderAndFiles'}
@{Shape='an array of one comma list';Value=@('ThisFolderAndSubfolders,ThisFolderAndFiles');ValueText='ThisFolderAndSubfolders,ThisFolderAndFiles'}
@{Shape='a hash set of two names';Value=[System.Collections.Generic.HashSet[string]]::new([string[]]@('ThisFolderAndSubfolders','ThisFolderAndFiles'));ValueText=$null}
@{Shape='the keys of a hashtable';Value=(@{ThisFolderAndSubfolders=1;ThisFolderAndFiles=2}).Keys;ValueText=$null}
# Writing an audit entry needs the Security privilege, so without it the "good" object right next to the bad
# one fails too, with its own (unrelated) privilege error; that part of the test runs only with the privilege,
# the same way most of Audit.Tests.ps1 does. The conversion failure that this test pins happens before the
# cmdlet ever touches the SACL, so the core assertions below run in every configuration.
It'Should write one InvalidParameterValue error for <Cmdlet> -<Parameter> (<Shape>), change nothing, and still process the next object'-ForEach$auditInvalidParameterCases{
# A descriptor that Get-NTFSSecurityDescriptor read without the Security privilege has no audit section, so
# without the privilege the "good" descriptor also gets its own (unrelated) ReadSecurityError; see above.
It'Should write one InvalidParameterValue error per descriptor for <Cmdlet> -<Parameter> bound to a piped descriptor, and leave the descriptors unchanged'-ForEach$auditSdInvalidParameterCases{
It'Should give the row without AuditFlags the default Success and Failure after a preceding Failure-only row, with no carry-over'-Skip:(-not$canReadAudit){
It'Should give the row without <Parameter> its own default after a preceding row with an invalid value, with no carry-over'-ForEach$auditNoCarryOverCases-Skip:(-not$canReadAudit){
It'Should throw a terminating InvalidParameterValue error for <Cmdlet> -<Parameter>, catchable with try/catch, and change nothing'-ForEach$auditNamedInvalidParameterCases{
It'Should still give <Cmdlet> -<Parameter> its own default for a piped $null, unaffected by the named $null fix'-ForEach$auditNamedNullCases-Skip:(-not$canReadAudit){
Context'Choosing the parameter set with a mix of string and enum values'{
It'Should reject a piped object whose AppliesTo is <AppliesToShape> combined with InheritanceFlags as <FlagShape> with an AmbiguousParameterSet error'-ForEach$auditAmbiguousValueCases{
It'Should reject a named call whose -AppliesTo is <AppliesToShape> combined with -PropagationFlags as <FlagShape> with an AmbiguousParameterSet error'-ForEach$auditAmbiguousValueCases{
# A typed parameter skips a $null, an empty string, or DBNull value of a property, and the entry was created for
# every shape below; the object-typed parameters count such a value of a property of the other group as present
# too, so PowerShell cannot resolve the parameter set and nothing is changed. The conversion/parameter-set
# failure happens before the cmdlet ever touches the SACL, so the core assertion (the error id, and that the bad
# object's audit entries are unchanged) runs in every configuration; only the "good next object succeeded" part
# needs the Security privilege, the same way the rest of this file does.
Context'A blank value of a property of the other group'{
It'Should reject <Cmdlet> (<TargetKind>) for <Direction> (<Shape>) with the error the binder gives, change nothing, and still process the next object'-ForEach$auditAmbiguousOtherGroupCases{
# With the object type, a script block is a plain value (a typed parameter evaluates it once per piped object),
# so ValidateNamedValue in BeginProcessing rejects it the same as any other bad value, before any piped object
# is processed and before the cmdlet ever touches the SACL. The terminating error itself needs no Security
# privilege; reading the SACL back to confirm nothing changed does, the same way the rest of this file does.
Context'A named script block is a terminating error'{
It'Should throw a terminating InvalidParameterValue error for a named script block value of <Cmdlet> -<Parameter>, and change nothing'-ForEach$auditScriptBlockCases{
It'Should complete Add-NTFSAudit -<Parameter> for the unquoted, single-quoted, double-quoted, and wildcard forms of <ExpectedName>'-ForEach$auditCompletionFormCases{
$base='Add-NTFSAudit -Path C:\x -Account a -AccessRights Read -{0} '-f$Parameter
It'<_> should pass on what a later command raises at the RestoreOwnerError record instead of reporting it as the item''s own error, and leave the next path untouched'-Skip:(-not$holdsRestorePrivilege)-ForEach$laterCommandRestoreOwnerNames{
It'Should stop a cmdlet and Enable-Privileges with one EnablePrivilegesSettingInvalid error for <Case>, not an InvalidCastException or a NullReferenceException'-ForEach@(