diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs index d726eaa870e..0f3a4cdc09e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Management.Automation; using System.Management.Automation.Internal; @@ -113,7 +114,15 @@ protected override void ProcessRecord() { if (ShouldProcess(path)) { - AlternateDataStreamUtilities.DeleteFileStream(path, "Zone.Identifier"); + try + { + AlternateDataStreamUtilities.DeleteFileStream(path, "Zone.Identifier"); + } + catch (Win32Exception accessException) + { + WriteError(new ErrorRecord(accessException, "RemoveItemUnauthorizedAccessError", ErrorCategory.PermissionDenied, path)); + } + } } } diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 7205120bdd1..2abdce1ff3b 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -8770,7 +8770,11 @@ internal static void DeleteFileStream(string path, string streamName) } string resultPath = path + adjustedStreamName; - NativeMethods.DeleteFile(resultPath); + if (!NativeMethods.DeleteFile(resultPath)) + { + int error = Marshal.GetLastWin32Error(); + throw new Win32Exception(error); + } } internal static void SetZoneOfOrigin(string path, SecurityZone securityZone) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Unblock-File.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Unblock-File.Tests.ps1 index 201e32bb92e..4965571b9ad 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Unblock-File.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Unblock-File.Tests.ps1 @@ -7,7 +7,7 @@ function Test-UnblockFile { return $true } } - + return $false } @@ -37,23 +37,11 @@ Describe "Unblock-File" -Tags "CI" { } It "With '-Path': no file exist" { - try { - Unblock-File -Path nofileexist.ttt -ErrorAction Stop - throw "No Exception!" - } - catch { - $_.FullyQualifiedErrorId | Should Be "FileNotFound,Microsoft.PowerShell.Commands.UnblockFileCommand" - } + { Unblock-File -Path nofileexist.ttt -ErrorAction Stop } | ShouldBeErrorId "FileNotFound,Microsoft.PowerShell.Commands.UnblockFileCommand" } It "With '-LiteralPath': no file exist" { - try { - Unblock-File -LiteralPath nofileexist.ttt -ErrorAction Stop - throw "No Exception!" - } - catch { - $_.FullyQualifiedErrorId | Should Be "FileNotFound,Microsoft.PowerShell.Commands.UnblockFileCommand" - } + { Unblock-File -LiteralPath nofileexist.ttt -ErrorAction Stop } | ShouldBeErrorId "FileNotFound,Microsoft.PowerShell.Commands.UnblockFileCommand" } It "With '-Path': file exist" { @@ -65,4 +53,21 @@ Describe "Unblock-File" -Tags "CI" { Unblock-File -LiteralPath $testfilepath Test-UnblockFile | Should Be $true } + + It "Write an error if a file is read only" { + $TestFile = Join-Path $TestDrive "testfileunlock.ps1" + Set-Content -Path $TestFile -value 'test' + $ZoneIdentifier = { + [ZoneTransfer] + ZoneId=3 + } + Set-Content -Path $TestFile -Value $ZoneIdentifier -Stream 'Zone.Identifier' + Set-ItemProperty -Path $TestFile -Name IsReadOnly -Value $True + + $TestFileCreated = Get-ChildItem $TestFile + $TestFileCreated.IsReadOnly | Should Be $true + + { Unblock-File -LiteralPath $TestFile -ErrorAction SilentlyContinue } | Should Not Throw + $error[0].FullyQualifiedErrorId | Should Be "RemoveItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.UnblockFileCommand" + } }