diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67f741b..6d6048a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -272,7 +272,8 @@ The format is based on
- Fix `Test-Path2`, which stopped with the terminating error "Illegal
characters in path" in Windows PowerShell for a path with a character
that Windows doesn't allow in names, such as `|`; it now returns `$false`
- for such a path, as in PowerShell 7
+ for such a path, as in PowerShell 7, and writes the reason as a debug
+ message
- Fix the cmdlets that enable the Backup, Restore, Take Ownership, and
Security privileges, which left them enabled in the session when a later
command, such as `Select-Object -First`, or a terminating error stopped
diff --git a/Docs/Cmdlets/Test-Path2.md b/Docs/Cmdlets/Test-Path2.md
index bf28c32..5b47fc5 100644
--- a/Docs/Cmdlets/Test-Path2.md
+++ b/Docs/Cmdlets/Test-Path2.md
@@ -117,7 +117,7 @@ For each path, the cmdlet writes `$true` when the item exists and matches `-Path
The cmdlet resolves paths through the AlphaFS library, which is not bound by the 260-character `MAX_PATH` limit of the Windows PowerShell file system provider. Use `Test-Path2` instead of `Test-Path` when a path can be longer than that limit.
-A path that does not exist is not an error condition. The cmdlet writes `$false` and continues with the next path. This also applies to a path with a character that Windows doesn't allow in names, such as `|` or `<`; before 5.0.0, such a path stopped the cmdlet with the terminating error "Illegal characters in path" in Windows PowerShell.
+A path that does not exist is not an error condition. The cmdlet writes `$false` and continues with the next path. This also applies to a path with a character that Windows doesn't allow in names, such as `|` or `<`; Windows PowerShell rejects such a path, and the cmdlet writes the reason as a debug message. Before 5.0.0, such a path stopped the cmdlet with the terminating error "Illegal characters in path" in Windows PowerShell.
## RELATED LINKS
diff --git a/NTFSSecurity/PathCmdlets/TestPath2.cs b/NTFSSecurity/PathCmdlets/TestPath2.cs
index b087a2b..5d7c0eb 100644
--- a/NTFSSecurity/PathCmdlets/TestPath2.cs
+++ b/NTFSSecurity/PathCmdlets/TestPath2.cs
@@ -45,42 +45,51 @@ namespace NTFSSecurity
{
foreach (var path in paths)
{
+ FileSystemInfo item = null;
try
{
- FileSystemInfo item;
TryGetFileSystemInfo2(path, out item);
-
- if (item == null)
- WriteObject(false);
- else
- {
- if (PathType == TestPathType.Any)
- WriteObject(true);
- else if (PathType == TestPathType.Container & item is DirectoryInfo)
- WriteObject(true);
- else if (PathType == TestPathType.Leaf & item is FileInfo)
- WriteObject(true);
- else
- WriteObject(false);
- }
}
catch (System.IO.FileNotFoundException ex)
{
WriteError(new ErrorRecord(ex, "PathNotFound", ErrorCategory.ObjectNotFound, path));
+ continue;
}
// In Windows PowerShell, .NET rejects a path with a character that Windows doesn't allow in names.
// Such an item can't exist, so the cmdlet writes $false, as in PowerShell 7 and like Test-Path.
- catch (System.ArgumentException)
+ catch (System.ArgumentException ex)
{
- WriteObject(false);
+ WriteInvalidPath(path, ex);
+ continue;
}
- catch (System.NotSupportedException)
+ catch (System.NotSupportedException ex)
{
+ WriteInvalidPath(path, ex);
+ continue;
+ }
+
+ if (item == null)
WriteObject(false);
+ else
+ {
+ if (PathType == TestPathType.Any)
+ WriteObject(true);
+ else if (PathType == TestPathType.Container & item is DirectoryInfo)
+ WriteObject(true);
+ else if (PathType == TestPathType.Leaf & item is FileInfo)
+ WriteObject(true);
+ else
+ WriteObject(false);
}
}
}
+ private void WriteInvalidPath(string path, System.Exception exception)
+ {
+ WriteDebug(string.Format("'{0}' is not a valid path: {1}", path, exception.Message));
+ WriteObject(false);
+ }
+
protected override void EndProcessing()
{
base.EndProcessing();
diff --git a/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml b/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml
index fd2befb..9dec184 100644
--- a/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml
+++ b/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml
@@ -10136,7 +10136,7 @@ PS C:\> Set-NTFSSecurityDescriptor -SecurityDescriptor $sd
The cmdlet resolves paths through the AlphaFS library, which is not bound by the 260-character `MAX_PATH` limit of the Windows PowerShell file system provider. Use `Test-Path2` instead of `Test-Path` when a path can be longer than that limit.
- A path that does not exist is not an error condition. The cmdlet writes `$false` and continues with the next path. This also applies to a path with a character that Windows doesn't allow in names, such as `|` or `<`; before 5.0.0, such a path stopped the cmdlet with the terminating error "Illegal characters in path" in Windows PowerShell.
+ A path that does not exist is not an error condition. The cmdlet writes `$false` and continues with the next path. This also applies to a path with a character that Windows doesn't allow in names, such as `|` or `<`; Windows PowerShell rejects such a path, and the cmdlet writes the reason as a debug message. Before 5.0.0, such a path stopped the cmdlet with the terminating error "Illegal characters in path" in Windows PowerShell.
diff --git a/Tests/ItemCmdlets.Tests.ps1 b/Tests/ItemCmdlets.Tests.ps1
index cfd91df..ae29a04 100644
--- a/Tests/ItemCmdlets.Tests.ps1
+++ b/Tests/ItemCmdlets.Tests.ps1
@@ -319,6 +319,22 @@ Describe 'Test-Path2' {
$testErrors | Should -BeNullOrEmpty
$result -join ',' | Should -Be 'False,True'
}
+
+ # PowerShell 7 accepts these characters and finds no item, so only Windows PowerShell rejects the path. Before
+ # 5.0.0-rc6, the cmdlet wrote $false for a rejected path without saying why. -Debug would prompt in Windows
+ # PowerShell, so the test sets the preference.
+ It 'Should say in a debug message why it writes $false for a path that Windows PowerShell rejects' -Skip:($PSVersionTable.PSEdition -ne 'Desktop') {
+ $invalid = Join-Path -Path $folder -ChildPath 'a|b'
+ $DebugPreference = 'Continue'
+
+ $output = @(Test-Path2 -Path $invalid -ErrorAction Stop 5>&1)
+
+ $messages = @($output | Where-Object -FilterScript { $_ -is [Management.Automation.DebugRecord] } |
+ Where-Object -Property Message -Like -Value '*is not a valid path*')
+ $messages | Should -HaveCount 1
+ $messages[0].Message.Contains("'$invalid'") | Should -BeTrue
+ $output | Where-Object -FilterScript { $_ -is [bool] } | Should -BeFalse
+ }
}
Describe 'Get-DiskSpace' {