From 4c97719834a7262fb2b3c942018d320658868d5d Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Mon, 5 Oct 2026 02:49:47 +0200 Subject: [PATCH] docs: answer recurring questions in an FAQ and correct two cmdlet pages The new FAQ page answers the questions that the issues ask again and again and links the pages with the details. The Get-NTFSEffectiveAccess page said that a security descriptor produces no result, and the Copy-Item2 page now says that -PassThru returns the copy; tests pin both -PassThru objects. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant --- Docs/Cmdlets/Copy-Item2.md | 4 +- Docs/Cmdlets/Get-NTFSEffectiveAccess.md | 2 +- Docs/FAQ.md | 64 ++++++++++++++++++++ Docs/README.md | 3 +- NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml | 6 +- Tests/ItemCmdlets.Tests.ps1 | 13 ++++ 6 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 Docs/FAQ.md diff --git a/Docs/Cmdlets/Copy-Item2.md b/Docs/Cmdlets/Copy-Item2.md index 0d78423..9e7b0b6 100644 --- a/Docs/Cmdlets/Copy-Item2.md +++ b/Docs/Cmdlets/Copy-Item2.md @@ -178,11 +178,11 @@ You can pipe an object that has a `Destination` property to supply the target of ### Alphaleonis.Win32.Filesystem.FileInfo -By default this cmdlet returns nothing. With `-PassThru $true` it returns a file object for each file that it copied. +By default this cmdlet returns nothing. With `-PassThru $true` it returns a file object for each file that it copied, pointing at the copy. ### Alphaleonis.Win32.Filesystem.DirectoryInfo -With `-PassThru $true` the cmdlet returns a folder object for each folder that it copied. +With `-PassThru $true` the cmdlet returns a folder object for each folder that it copied, pointing at the copy. ## NOTES diff --git a/Docs/Cmdlets/Get-NTFSEffectiveAccess.md b/Docs/Cmdlets/Get-NTFSEffectiveAccess.md index c10b202..0385c01 100644 --- a/Docs/Cmdlets/Get-NTFSEffectiveAccess.md +++ b/Docs/Cmdlets/Get-NTFSEffectiveAccess.md @@ -164,7 +164,7 @@ One or more paths of files or folders, piped by value or by the property `FullNa ### Security2.FileSystemSecurity2[] -Security descriptors are accepted by the parameter binder but produce no result in this cmdlet. +One or more security descriptors that `Get-NTFSSecurityDescriptor` returned. The cmdlet calculates the effective access from the descriptor in memory instead of reading the item again. ### Security2.IdentityReference2 diff --git a/Docs/FAQ.md b/Docs/FAQ.md new file mode 100644 index 0000000..8f31dc8 --- /dev/null +++ b/Docs/FAQ.md @@ -0,0 +1,64 @@ +# Frequently asked questions + +Answers to questions that come up again and again in the issues. For the +background, read [Concepts](Concepts.md); for longer scripts, read +[Examples](Examples.md). + +## The module fails to load with HRESULT 0x80131515 + +Windows blocks the assemblies of a ZIP file that was downloaded from the +internet. Install the module from the PowerShell Gallery instead, as +described in [Installation](README.md#installation), or unblock the files of +a downloaded copy with `Get-ChildItem -Recurse | Unblock-File` before you +import it. + +## Access is denied, although I am an administrator + +Run PowerShell elevated. Only an elevated session holds the Backup, +Restore, Take Ownership, and Security privileges, which the cmdlets enable +to read and change items that your account has no rights on. Reading or +changing audit entries always needs the Security privilege. See +[Privileges](Concepts.md#privileges) and the module setting +`EnablePrivileges` in [Module settings](Concepts.md#module-settings). + +## Get-NTFSEffectiveAccess shows other rights than Explorer + +`Get-NTFSEffectiveAccess` calculates the rights that the NTFS permissions +of the item grant to one account. It doesn't include share permissions, +which Explorer adds for a path on a file share, and the account must be +resolvable on the computer that runs the cmdlet. See +[Get-NTFSEffectiveAccess](Cmdlets/Get-NTFSEffectiveAccess.md). + +## Get-ChildItem2 -Recurse runs in a loop through junctions + +A junction can point to a folder above it. Use `-SkipMountPoints` and +`-SkipSymbolicLinks` to leave out junctions and symbolic links when you +walk a tree, for example before you pipe the items to `Get-NTFSAccess`. +See [Get-ChildItem2](Cmdlets/Get-ChildItem2.md). + +## How do I restore permissions that I exported? + +`Get-NTFSAccess` returns the account, the rights, the type, and the +inheritance and propagation flags of each entry. `Add-NTFSAccess` binds +`-Account`, `-AccessRights`, `-AccessType`, `-InheritanceFlags`, and +`-PropagationFlags` by property name, so the objects, or the rows of a CSV +file with these columns and the path, can be piped back to it. See +[Add-NTFSAccess](Cmdlets/Add-NTFSAccess.md). + +## How do I apply the same audit entries to a whole folder tree? + +Add the entry to the top folder only. By default, `Add-NTFSAudit` applies +it to the folder, its subfolders, and its files, so the items below inherit +it. To remove other entries from the items below, use `Clear-NTFSAudit`, +and use `Enable-NTFSAuditInheritance` where inheritance is blocked. +Changing audit entries needs an elevated session. See +[Add-NTFSAudit](Cmdlets/Add-NTFSAudit.md). + +## Can I use a PowerShell drive in a path? + +No. The cmdlets read and write the file system directly through the AlphaFS +library, not through the PowerShell providers, so they don't know drives +that `New-PSDrive` created, or drives of other providers such as `HKLM:`. +Use the file system path instead, such as `C:\Data` or `\\server\share`. A +relative path is resolved against the current file system location. See +[Long paths](Concepts.md#long-paths). diff --git a/Docs/README.md b/Docs/README.md index 8d6bcff..956b1c0 100644 --- a/Docs/README.md +++ b/Docs/README.md @@ -72,7 +72,8 @@ Get-NTFSAccess -Path C:\Windows Read [Concepts](Concepts.md) for the background and [Examples](Examples.md) for common tasks. Every cmdlet has a reference page with all parameters and -examples; see the [cmdlet list](#cmdlets). +examples; see the [cmdlet list](#cmdlets). The [FAQ](FAQ.md) answers +questions that come up again and again. ## Cmdlets diff --git a/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml b/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml index fd81345..9b8a512 100644 --- a/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml +++ b/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml @@ -2166,7 +2166,7 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd Alphaleonis.Win32.Filesystem.FileInfo - By default this cmdlet returns nothing. With `-PassThru $true` it returns a file object for each file that it copied. + By default this cmdlet returns nothing. With `-PassThru $true` it returns a file object for each file that it copied, pointing at the copy. @@ -2174,7 +2174,7 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd Alphaleonis.Win32.Filesystem.DirectoryInfo - With `-PassThru $true` the cmdlet returns a folder object for each folder that it copied. + With `-PassThru $true` the cmdlet returns a folder object for each folder that it copied, pointing at the copy. @@ -5117,7 +5117,7 @@ PS C:\> Get-NTFSAudit -SecurityDescriptor $sd Security2.FileSystemSecurity2[] - Security descriptors are accepted by the parameter binder but produce no result in this cmdlet. + One or more security descriptors that `Get-NTFSSecurityDescriptor` returned. The cmdlet calculates the effective access from the descriptor in memory instead of reading the item again. diff --git a/Tests/ItemCmdlets.Tests.ps1 b/Tests/ItemCmdlets.Tests.ps1 index c629536..4586755 100644 --- a/Tests/ItemCmdlets.Tests.ps1 +++ b/Tests/ItemCmdlets.Tests.ps1 @@ -129,6 +129,19 @@ Describe 'Copy-Item2, Move-Item2, and Remove-Item2 with several paths' { $messages.Message | Should -Contain ("File '{0}' {1} to '{2}'" -f $first, $Verb, $target) } + # With -PassThru, both cmdlets return the item at the destination, as their pages say. + It 'Copy-Item2 -PassThru should return the copy' { + $result = Copy-Item2 -Path $first -Destination $destination -PassThru $true + + $result.FullName | Should -Be (Join-Path -Path $destination -ChildPath 'First.txt') + $first | Should -Exist + } + + It 'Move-Item2 -PassThru should return the item at its new location' { + $result = Move-Item2 -Path $first -Destination $destination -PassThru $true + + $result.FullName | Should -Be (Join-Path -Path $destination -ChildPath 'First.txt') + } # Before 5.0.0, -PassThru wrote the item also when -WhatIf skipped the operation. It '<_> should write nothing with -PassThru and -WhatIf' -ForEach @('Copy-Item2', 'Move-Item2', 'Remove-Item2') { $parameters = @{ Path = $first; PassThru = $true; WhatIf = $true }