From a3c8508f6db0f1a82877582544bd70f7bc235cd7 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Tue, 19 Sep 2017 13:24:39 -0700 Subject: [PATCH 1/3] [feature] allow * to be used in registry path for remove-item --- .../commands/management/Navigation.cs | 4 ++++ .../Registry.Tests.ps1 | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs index f3aac32cce3..87ce3503136 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs @@ -3266,6 +3266,10 @@ protected override void ProcessRecord() { // not a directory } + catch (System.ArgumentException) + { + // invalid characters (like asterisk) for a file path, but valid for other paths (like registry) + } if (!treatAsFile && !Recurse && hasChildren) { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Registry.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Registry.Tests.ps1 index cbcb0f47d40..5a0493e75b4 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Registry.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Registry.Tests.ps1 @@ -469,6 +469,22 @@ Describe "Extended Registry Provider Tests" -Tags @("Feature", "RequireAdminOnWi $result."$testPropertyName" | Should Be $testPropertyValue } } + + Context "Validate -LiteralPath" { + It "Verify New-Item and Remove-Item work with asterisk" { + try { + $tempPath = "HKCU:\_tmp" + $testPath = "$tempPath\*\sub" + New-Item -Force $testPath + $testPath | Should Exist + Remove-Item -LiteralPath $testPath + $testPath | Should Not Exist + } + finally { + Remove-Item -Recurse $tempPath + } + } + } } } finally { From bc5c902def38c02aab5887d7cc75bea9a1a7e438 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Wed, 20 Sep 2017 09:53:20 -0700 Subject: [PATCH 2/3] [feature] address PR feedback have remove-item return error if -literalpath doesn't resolve to path --- .../commands/management/Navigation.cs | 39 ++++++++++++------- .../FileSystem.Tests.ps1 | 4 ++ .../Registry.Tests.ps1 | 4 +- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs index 87ce3503136..3f80cc59bb3 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs @@ -3107,6 +3107,18 @@ protected override void ProcessRecord() try { resolvedPSPaths = SessionState.Path.GetResolvedPSPathFromPSPath(path, currentContext); + if (null != LiteralPath && 0 == resolvedPSPaths.Count) + { + ItemNotFoundException pathNotFound = + new ItemNotFoundException( + path, + "PathNotFound", + SessionStateStrings.PathNotFound); + WriteError(new ErrorRecord( + pathNotFound.ErrorRecord, + pathNotFound)); + continue; + } } finally { @@ -3253,22 +3265,23 @@ protected override void ProcessRecord() bool shouldRecurse = Recurse; bool treatAsFile = false; - try + + // only check if path is a directory using DirectoryInfo if using FileSystemProvider + if (resolvedPath.Provider.Name.Equals(FileSystemProvider.ProviderName, StringComparison.OrdinalIgnoreCase)) { - System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(providerPath); - if (di != null && (di.Attributes & System.IO.FileAttributes.ReparsePoint) != 0) + try { - shouldRecurse = false; - treatAsFile = true; + System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(providerPath); + if (di != null && (di.Attributes & System.IO.FileAttributes.ReparsePoint) != 0) + { + shouldRecurse = false; + treatAsFile = true; + } + } + catch (System.IO.FileNotFoundException) + { + // not a directory } - } - catch (System.IO.FileNotFoundException) - { - // not a directory - } - catch (System.ArgumentException) - { - // invalid characters (like asterisk) for a file path, but valid for other paths (like registry) } if (!treatAsFile && !Recurse && hasChildren) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/FileSystem.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/FileSystem.Tests.ps1 index 9d460f16f1b..909cc24de08 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/FileSystem.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/FileSystem.Tests.ps1 @@ -370,6 +370,10 @@ Describe "Handling of globbing patterns" -Tags "CI" { Copy-Item -LiteralPath $file.FullName -Destination $newPath Test-Path -LiteralPath $newPath | Should Be $true } + + It "Remove-Item -LiteralPath should fail if it contains asterisk" { + { Remove-Item -LiteralPath ./foo*.txt -ErrorAction Stop } | ShouldBeErrorId "PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand" + } } } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Registry.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Registry.Tests.ps1 index 5a0493e75b4..b4d3539b942 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Registry.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Registry.Tests.ps1 @@ -475,13 +475,13 @@ Describe "Extended Registry Provider Tests" -Tags @("Feature", "RequireAdminOnWi try { $tempPath = "HKCU:\_tmp" $testPath = "$tempPath\*\sub" - New-Item -Force $testPath + $null = New-Item -Force $testPath $testPath | Should Exist Remove-Item -LiteralPath $testPath $testPath | Should Not Exist } finally { - Remove-Item -Recurse $tempPath + Remove-Item -Recurse $tempPath -ErrorAction SilentlyContinue } } } From 5a16dc4207f20ceb8278831dcbe64cebf9b123ac Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Sat, 23 Sep 2017 21:46:29 -0700 Subject: [PATCH 3/3] [feature] fix in navigation exposed an issue with WSMan Config Provider tests that require -Recurse to be used otherwise a confirmation prompt shows up --- .../ConfigProvider.Tests.ps1 | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/powershell/Modules/Microsoft.WSMan.Management/ConfigProvider.Tests.ps1 b/test/powershell/Modules/Microsoft.WSMan.Management/ConfigProvider.Tests.ps1 index fe06cac7697..63c90175d26 100644 --- a/test/powershell/Modules/Microsoft.WSMan.Management/ConfigProvider.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.WSMan.Management/ConfigProvider.Tests.ps1 @@ -292,11 +292,11 @@ Describe "WSMan Config Provider" -Tag Feature,RequireAdminOnWindows { # not a .Net type so can't use BeOfType $newItem.PSObject.TypeNames[0] | Should Be "Microsoft.WSMan.Management.WSManConfigContainerElement#ComputerLevel" $newItem.Name | Should Be $expected - Remove-Item WSMan:\$name + Remove-Item WSMan:\$name -Recurse -Force "WSMan:\$name" | Should Not Exist } finally { - Remove-Item WSMan:\$name -Force -ErrorAction SilentlyContinue + Remove-Item WSMan:\$name -Recurse -Force -ErrorAction SilentlyContinue } } @@ -314,11 +314,11 @@ Describe "WSMan Config Provider" -Tag Feature,RequireAdminOnWindows { $property.Value | Should Be $listenerXml.Listener.$($property.Name) } } - Remove-Item -Path "WSMan:\localhost\Listener\$listenerName" -Force + Remove-Item -Path "WSMan:\localhost\Listener\$listenerName" -Recurse -Force $newListener.PSPath | Should Not Exist } finally { - Remove-Item -Path "WSMan:\localhost\Listener\$listenerName" -Force -ErrorAction SilentlyContinue + Remove-Item -Path "WSMan:\localhost\Listener\$listenerName" -Recurse -Force -ErrorAction SilentlyContinue } } @@ -332,11 +332,11 @@ Describe "WSMan Config Provider" -Tag Feature,RequireAdminOnWindows { -RunAsCredential $creds $expectedMissingProperties = @("InitializationParameters") Test-Plugin -Plugin $plugin -expectedMissingProperties $expectedMissingProperties - Remove-Item WSMan:\localhost\Plugin\TestPlugin2\ + Remove-Item WSMan:\localhost\Plugin\TestPlugin2\ -Recurse -Force "WSMan:\localhost\Plugin\TestPlugin2" | Should Not Exist } finally { - Remove-Item WSMan:\localhost\Plugin\TestPlugin2\ -Force -ErrorAction SilentlyContinue + Remove-Item WSMan:\localhost\Plugin\TestPlugin2\ -Recurse -Force -ErrorAction SilentlyContinue } } @@ -363,11 +363,11 @@ Describe "WSMan Config Provider" -Tag Feature,RequireAdminOnWindows { try { $plugin = New-Item -Path WSMan:\localhost\Plugin -File $testdrive\plugin.xml -Name TestPlugin2 Test-Plugin -Plugin $plugin - Remove-Item WSMan:\localhost\Plugin\TestPlugin2\ + Remove-Item WSMan:\localhost\Plugin\TestPlugin2\ -Recurse -Force "WSMan:\localhost\Plugin\TestPlugin2\" | Should Not Exist } finally { - Remove-Item "WSMan:\localhost\Plugin\TestPlugin2\" -Force -ErrorAction SilentlyContinue + Remove-Item "WSMan:\localhost\Plugin\TestPlugin2\" -Recurse -Force -ErrorAction SilentlyContinue } } @@ -379,11 +379,11 @@ Describe "WSMan Config Provider" -Tag Feature,RequireAdminOnWindows { $properties = Get-ChildItem $resource.PSPath ($properties | Where-Object { $_.Name -eq "ResourceUri" }).Value | Should Be "http://foo/" ($properties | Where-Object { $_.Name -eq "Capability" })[0].Value | Should Be "shell" - Remove-Item $resource.PSPath + Remove-Item $resource.PSPath -Recurse -Force $resource.PSPath | Should Not Exist } finally { - Remove-Item $resource.PSPath -Force -ErrorAction SilentlyContinue + Remove-Item $resource.PSPath -Recurse -Force -ErrorAction SilentlyContinue } } @@ -394,7 +394,7 @@ Describe "WSMan Config Provider" -Tag Feature,RequireAdminOnWindows { $parameterObj = Get-Item $parameter.PSPath $parameterObj.Name | Should Be "foo" $parameterObj.Value | Should Be "bar" - Remove-Item $parameter.PSPath + Remove-Item $parameter.PSPath -Force $parameter.PSPath | Should Not Exist } finally { @@ -407,16 +407,16 @@ Describe "WSMan Config Provider" -Tag Feature,RequireAdminOnWindows { $sddl = "O:NSG:BAD:P(A;;GA;;;BA)" $resource = Get-ChildItem -Path WSMan:\localhost\Plugin\TestPlugin\Resources\ | Select-Object -First 1 # remove existing security resource since the folder name is just a hash of the resource uri - Get-ChildItem "$($resource.PSPath)\Security" | Remove-Item + Get-ChildItem "$($resource.PSPath)\Security" | Remove-Item -Recurse -Force $security = New-Item "$($resource.PSPath)\Security" -SDDL $sddl -Force $security.PSPath | Should Exist $securityObj = Get-Item $security.PSPath (Get-ChildItem $securityObj.PSPath | Where-Object { $_.Name -eq 'sddl' }).Value | Should Be $sddl - Remove-Item $security.PSPath + Remove-Item $security.PSPath -Recurse -Force $security.PSPath | Should Not Exist } finally { - Remove-Item $security.PSPath -Force -ErrorAction SilentlyContinue + Remove-Item $security.PSPath -Recurse -Force -ErrorAction SilentlyContinue } } }