mirror of https://github.com/raandree/NTFSSecurity
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
8.9 KiB
187 lines
8.9 KiB
<#
|
|
Tests Remove-Item2 of the module built in NTFSSecurity\bin\Release.
|
|
#>
|
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
|
|
'PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Pester shares variables between blocks.'
|
|
)]
|
|
param ()
|
|
|
|
Describe 'Remove-Item2' {
|
|
BeforeAll {
|
|
Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'TestHelpers.psm1') -Force
|
|
$modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\NTFSSecurity\bin\Release\NTFSSecurity.psd1'
|
|
Import-Module -Name $modulePath -Force -ErrorAction Stop
|
|
$sandbox = New-TestSandbox -Name 'RemoveItem'
|
|
Push-Location -LiteralPath $sandbox
|
|
}
|
|
|
|
AfterAll {
|
|
Pop-Location
|
|
Remove-TestSandbox -Sandbox $sandbox
|
|
Remove-Module -Name NTFSSecurity -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
Context 'Folders and their contents' {
|
|
It 'Should remove an empty folder and return its folder object with -PassThru' {
|
|
$folder = New-TestSandboxItem -Sandbox $sandbox -Name 'Empty' -Directory
|
|
|
|
$result = @(Remove-Item2 -Path $folder -PassThru -ErrorAction Stop)
|
|
|
|
$folder | Should -Not -Exist
|
|
$result | Should -HaveCount 1
|
|
$result[0] | Should -BeOfType [Alphaleonis.Win32.Filesystem.DirectoryInfo]
|
|
$result[0].FullName | Should -Be $folder
|
|
}
|
|
|
|
It 'Should report DeleteError for a non-empty folder without -Recurse and continue with the next path' {
|
|
$folder = New-TestSandboxItem -Sandbox $sandbox -Name 'NonEmpty' -Directory
|
|
$content = Join-Path -Path $folder -ChildPath 'Keep.txt'
|
|
$next = New-TestSandboxItem -Sandbox $sandbox -Name 'Next'
|
|
Assert-TestSandboxPath -Sandbox $sandbox -Path $content
|
|
Set-Content -LiteralPath $content -Value 'Keep'
|
|
|
|
$result = @(Remove-Item2 -Path $folder, $next -PassThru -ErrorVariable removeErrors -ErrorAction SilentlyContinue)
|
|
|
|
$removeErrors | Should -HaveCount 1
|
|
$removeErrors[0].FullyQualifiedErrorId | Should -BeLike 'DeleteError,*'
|
|
$removeErrors[0].CategoryInfo.Category | Should -Be 'InvalidData'
|
|
$removeErrors[0].TargetObject | Should -Be $folder
|
|
Get-Content -LiteralPath $content | Should -Be 'Keep'
|
|
$next | Should -Not -Exist
|
|
$result | Should -HaveCount 1
|
|
$result[0].FullName | Should -Be $next
|
|
}
|
|
|
|
It 'Should remove a folder tree with -Recurse without touching its sibling' {
|
|
$folder = New-TestSandboxItem -Sandbox $sandbox -Name 'Tree' -Directory
|
|
$nested = Join-Path -Path $folder -ChildPath 'Child\Grandchild'
|
|
$content = Join-Path -Path $nested -ChildPath 'Delete.txt'
|
|
$sibling = New-TestSandboxItem -Sandbox $sandbox -Name 'Sibling'
|
|
Assert-TestSandboxPath -Sandbox $sandbox -Path $nested, $content
|
|
New-Item -ItemType Directory -Path $nested -Force | Out-Null
|
|
Set-Content -LiteralPath $content -Value 'Delete'
|
|
|
|
Remove-Item2 -Path $folder -Recurse -ErrorAction Stop
|
|
|
|
$folder | Should -Not -Exist
|
|
Get-Content -LiteralPath $sibling | Should -Be 'Sibling'
|
|
}
|
|
|
|
It 'Should leave a folder tree unchanged with -Recurse -Force -WhatIf and write nothing with -PassThru' {
|
|
$folder = New-TestSandboxItem -Sandbox $sandbox -Name 'Preview' -Directory
|
|
$content = Join-Path -Path $folder -ChildPath 'Keep.txt'
|
|
Assert-TestSandboxPath -Sandbox $sandbox -Path $content
|
|
Set-Content -LiteralPath $content -Value 'Keep'
|
|
[IO.File]::SetAttributes($content, [IO.FileAttributes]::ReadOnly)
|
|
|
|
$result = @(Remove-Item2 -Path $folder -Recurse -Force -WhatIf -PassThru -ErrorAction Stop)
|
|
|
|
$result | Should -BeNullOrEmpty
|
|
Get-Content -LiteralPath $content | Should -Be 'Keep'
|
|
([IO.File]::GetAttributes($content) -band [IO.FileAttributes]::ReadOnly) | Should -Not -Be 0
|
|
}
|
|
|
|
It 'Should remove a folder tree containing read-only files with -Recurse -Force' {
|
|
$folder = New-TestSandboxItem -Sandbox $sandbox -Name 'ReadOnlyTree' -Directory
|
|
$content = Join-Path -Path $folder -ChildPath 'Child\ReadOnly.txt'
|
|
Assert-TestSandboxPath -Sandbox $sandbox -Path $content
|
|
New-Item -ItemType Directory -Path (Split-Path -Path $content -Parent) | Out-Null
|
|
Set-Content -LiteralPath $content -Value 'ReadOnly'
|
|
[IO.File]::SetAttributes($content, [IO.FileAttributes]::ReadOnly)
|
|
|
|
Remove-Item2 -Path $folder -Recurse -Force -ErrorAction Stop
|
|
|
|
$folder | Should -Not -Exist
|
|
}
|
|
|
|
It 'Should write DeleteError when a descendant is open without delete sharing, not a successful -PassThru result' {
|
|
$folder = New-TestSandboxItem -Sandbox $sandbox -Name 'LockedTree' -Directory
|
|
$content = Join-Path -Path $folder -ChildPath 'Locked.txt'
|
|
Assert-TestSandboxPath -Sandbox $sandbox -Path $content
|
|
Set-Content -LiteralPath $content -Value 'Locked'
|
|
$stream = [IO.File]::Open($content, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::None)
|
|
try {
|
|
$result = @(Remove-Item2 -Path $folder -Recurse -Force -PassThru -ErrorVariable removeErrors -ErrorAction SilentlyContinue)
|
|
}
|
|
finally {
|
|
$stream.Dispose()
|
|
}
|
|
|
|
$removeErrors | Should -HaveCount 1
|
|
$removeErrors[0].FullyQualifiedErrorId | Should -BeLike 'DeleteError,*'
|
|
$removeErrors[0].TargetObject | Should -Be $folder
|
|
$result | Should -BeNullOrEmpty
|
|
Get-Content -LiteralPath $content | Should -Be 'Locked'
|
|
}
|
|
|
|
It 'Should delete a junction with -Recurse without deleting or changing its target' {
|
|
$target = New-TestSandboxItem -Sandbox $sandbox -Name 'JunctionTarget' -Directory
|
|
$content = Join-Path -Path $target -ChildPath 'Keep.txt'
|
|
$link = Join-Path -Path $sandbox -ChildPath 'Junction'
|
|
Assert-TestSandboxPath -Sandbox $sandbox -Path $content, $link
|
|
Set-Content -LiteralPath $content -Value 'Keep'
|
|
$before = (Get-Acl -LiteralPath $target).Sddl
|
|
New-Item -ItemType Junction -Path $link -Value $target | Out-Null
|
|
|
|
Remove-Item2 -Path $link -Recurse -Force -ErrorAction Stop
|
|
|
|
$link | Should -Not -Exist
|
|
Get-Content -LiteralPath $content | Should -Be 'Keep'
|
|
(Get-Acl -LiteralPath $target).Sddl | Should -BeExactly $before
|
|
}
|
|
|
|
It 'Should delete a folder tree whose path exceeds 260 characters' {
|
|
$folder = New-TestSandboxItem -Sandbox $sandbox -Name 'LongTree' -Directory
|
|
$long = Join-Path -Path $folder -ChildPath (('A' * 100), ('B' * 100), ('C' * 100) -join '\')
|
|
Assert-TestSandboxPath -Sandbox $sandbox -Path $long
|
|
[IO.Directory]::CreateDirectory('\\?\' + $long) | Out-Null
|
|
[IO.File]::WriteAllText(('\\?\' + $long + '\Delete.txt'), 'Long')
|
|
$long.Length | Should -BeGreaterThan 260
|
|
|
|
Remove-Item2 -Path $folder -Recurse -Force -ErrorAction Stop
|
|
|
|
$folder | Should -Not -Exist
|
|
}
|
|
}
|
|
|
|
Context 'Read-only files' {
|
|
It 'Should refuse a read-only file without -Force, keep its contents and attribute, and return nothing' {
|
|
$file = New-TestSandboxItem -Sandbox $sandbox -Name 'ReadOnly'
|
|
[IO.File]::SetAttributes($file, [IO.FileAttributes]::ReadOnly)
|
|
|
|
$result = @(Remove-Item2 -Path $file -PassThru -ErrorVariable removeErrors -ErrorAction SilentlyContinue)
|
|
|
|
$removeErrors | Should -HaveCount 1
|
|
$removeErrors[0].FullyQualifiedErrorId | Should -BeLike 'DeleteError,*'
|
|
$result | Should -BeNullOrEmpty
|
|
Get-Content -LiteralPath $file | Should -Be 'ReadOnly'
|
|
([IO.File]::GetAttributes($file) -band [IO.FileAttributes]::ReadOnly) | Should -Not -Be 0
|
|
}
|
|
|
|
It 'Should remove a read-only file with -Force' {
|
|
$file = New-TestSandboxItem -Sandbox $sandbox -Name 'Forced'
|
|
[IO.File]::SetAttributes($file, [IO.FileAttributes]::ReadOnly)
|
|
|
|
Remove-Item2 -Path $file -Force -ErrorAction Stop
|
|
|
|
$file | Should -Not -Exist
|
|
}
|
|
}
|
|
Context 'When called with -PassThur, the parameter name in 4.2.6 and earlier' {
|
|
BeforeAll {
|
|
$path = Join-Path -Path $sandbox -ChildPath 'PassThur.txt'
|
|
Assert-TestSandboxPath -Sandbox $sandbox -Path $path
|
|
Set-Content -LiteralPath $path -Value 'Remove-Item2 test'
|
|
|
|
$removedItem = Remove-Item2 -Path $path -PassThur
|
|
}
|
|
|
|
It 'Should delete the file' {
|
|
$path | Should -Not -Exist
|
|
}
|
|
|
|
It 'Should return the deleted file, like -PassThru' {
|
|
$removedItem.Name | Should -BeExactly 'PassThur.txt'
|
|
}
|
|
}
|
|
}
|
|
|