|
|
|
|
<#
|
|
|
|
|
Tests how the cmdlets of the module built in NTFSSecurity\bin\Release handle the Backup, Restore, Take Ownership,
|
|
|
|
|
and Security privileges. These tests need an access token that holds the privileges, so they skip without them
|
|
|
|
|
and run in CI, whose runners are elevated. They change only the privileges of the test process and restore the
|
|
|
|
|
module setting EnablePrivileges.
|
|
|
|
|
#>
|
|
|
|
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
|
|
|
|
|
'PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Pester shares variables between blocks.'
|
|
|
|
|
)]
|
|
|
|
|
param ()
|
|
|
|
|
|
|
|
|
|
BeforeDiscovery {
|
|
|
|
|
Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'TestHelpers.psm1') -Force
|
|
|
|
|
$missingPrivileges = @('SeBackupPrivilege', 'SeRestorePrivilege', 'SeTakeOwnershipPrivilege', 'SeSecurityPrivilege') |
|
|
|
|
|
Where-Object -FilterScript { -not (Test-PrivilegeHeld -Name $_) }
|
|
|
|
|
$holdsPrivileges = -not $missingPrivileges
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 'Privileges'
|
|
|
|
|
Push-Location -LiteralPath $sandbox
|
|
|
|
|
|
|
|
|
|
$privateData = (Get-Module -Name NTFSSecurity).PrivateData
|
|
|
|
|
$enablePrivileges = $privateData['EnablePrivileges']
|
|
|
|
|
|
|
|
|
|
function Get-BackupPrivilegeState {
|
|
|
|
|
(Get-Privileges | Where-Object -Property Privilege -EQ -Value 'Backup').PrivilegeState
|
|
|
|
|
}
|
fix: disable the privileges by their current state when a cmdlet ends
A cmdlet that enables the Backup, Restore, Take Ownership, and Security
privileges decided which ones to disable on the states that it had read
when it enabled them, and stopped at the first one that failed. When
another command in the pipeline, such as Disable-Privileges, had disabled
one of them, the cmdlet stopped with "Priviledge already disabled" and
left the privileges after that one enabled. After an early stop, which
Dispose handles since this branch, it left them enabled without any
message, because PowerShell ignores exceptions thrown in Dispose; and
Disable-Privileges threw that exception in Dispose on every call while
the privileges were disabled. 4.2.6 already decided on the old states.
DisablePrivilege now reads the current state, and the cleanup tries every
privilege: in EndProcessing, a privilege that it can't disable gives a
warning; in Dispose, it is ignored.
The early-stop tests now pin EnablePrivileges and check that the cmdlet
had enabled the privileges, so that they can't pass without testing
anything.
Found by the security review of fcb370e..00c3646 (findings 1 to 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
|
|
|
|
|
function Get-EnabledFileSystemPrivilege {
|
|
|
|
|
# The names of the privileges that the cmdlets enable, as far as they are enabled now
|
|
|
|
|
@(Get-Privileges | Where-Object -FilterScript {
|
|
|
|
|
$_.Privilege -in 'TakeOwnership', 'Restore', 'Backup', 'Security' -and $_.PrivilegeState -eq 'Enabled'
|
|
|
|
|
} | ForEach-Object -Process { $_.Privilege.ToString() })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AfterAll {
|
|
|
|
|
$privateData['EnablePrivileges'] = $enablePrivileges
|
|
|
|
|
Disable-Privileges -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
|
|
|
|
|
Pop-Location
|
|
|
|
|
Remove-TestSandbox -Sandbox $sandbox
|
|
|
|
|
Remove-Module -Name NTFSSecurity -Force -ErrorAction SilentlyContinue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Describe 'Disable-Privileges' {
|
|
|
|
|
Context 'When the module setting EnablePrivileges is $false' {
|
|
|
|
|
BeforeAll {
|
|
|
|
|
$privateData['EnablePrivileges'] = $false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AfterAll {
|
|
|
|
|
$privateData['EnablePrivileges'] = $enablePrivileges
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Before 5.0.0, the cmdlet warned that it could not disable the privileges and left them enabled.
|
|
|
|
|
It 'Should disable the privileges that Enable-Privileges enabled' -Skip:(-not $holdsPrivileges) {
|
|
|
|
|
Enable-Privileges
|
|
|
|
|
Get-BackupPrivilegeState | Should -Be 'Enabled'
|
|
|
|
|
|
|
|
|
|
Disable-Privileges -WarningVariable privilegeWarnings -WarningAction SilentlyContinue
|
|
|
|
|
|
|
|
|
|
$privilegeWarnings | Should -BeNullOrEmpty
|
|
|
|
|
Get-BackupPrivilegeState | Should -Be 'Disabled'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Before 5.0.0, the verbose message said that the privileges were now enabled.
|
|
|
|
|
It 'Should say in the verbose message that the privileges are disabled' -Skip:(-not $holdsPrivileges) {
|
|
|
|
|
Enable-Privileges
|
|
|
|
|
|
|
|
|
|
$messages = Disable-Privileges -Verbose -WarningAction SilentlyContinue 4>&1
|
|
|
|
|
|
|
|
|
|
$messages.Message | Should -Contain "The privileges 'TakeOwnership', 'Restore' and 'Backup' are now disabled."
|
|
|
|
|
}
|
|
|
|
|
}
|
fix: drive roots, audit descriptors, -WhatIf conflicts, and small items
- #41: for the root of a drive, the cmdlets read and changed the security
descriptor of the drive, a device object. FileSystemSecurity2 now routes
drive roots through the path-based AlphaFS methods, which keep the
trailing backslash; the removal and inheritance helpers use it too.
- #109: Add-, Remove-, and Clear-NTFSAudit report a security descriptor
without the audit entries like Get-NTFSAudit, through one helper, and
Get-NTFSEffectiveAccess names the cause that Windows reported instead
of a missing Security privilege.
- #108: Copy-Item2 and Move-Item2 check the destination only for an
operation that runs; with -WhatIf, a verbose message names the conflict.
- #111: Disable-Privileges skips the privileges that the token doesn't
hold, the privilege messages are spelled right, and Get-FileHash2
declares the type name of its objects; 05-Releasing.md documents the
release metadata tests.
- rc3 review leftovers: Remove-NTFSAudit writes nothing for an item
without a SACL, the owner retry of Set-NTFSSecurityDescriptor restores
the previous owner in a finally block and keeps an owner that the
descriptor sets, and FileSystemSecurity2.Write with another item writes
only the sections that were read.
Each fix has a test that failed first, in Windows PowerShell 5.1 and
PowerShell 7; writing a drive root was checked once on a temporary VHD.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
|
|
|
|
|
Context 'When the access token holds only some of the privileges' {
|
|
|
|
|
# Before 5.0.0-rc4, the cmdlet also tried to disable the privileges that the access token doesn't hold, and
|
|
|
|
|
# warned for each one that it couldn't disable it. A removed privilege can't be added back, so the test removes
|
|
|
|
|
# them in a child process.
|
|
|
|
|
It 'Should not warn about the privileges that the access token does not hold' -Skip:(-not $holdsPrivileges) {
|
|
|
|
|
$script = Join-Path -Path $sandbox -ChildPath 'Disable-PartialPrivileges.ps1'
|
|
|
|
|
Assert-TestSandboxPath -Sandbox $sandbox -Path $script
|
|
|
|
|
Set-Content -LiteralPath $script -Value @'
|
|
|
|
|
param ($ModulePath)
|
|
|
|
|
Import-Module -Name $ModulePath -ErrorAction Stop
|
|
|
|
|
$process = [System.Diagnostics.Process]::GetCurrentProcess()
|
|
|
|
|
[ProcessPrivileges.ProcessExtensions]::RemovePrivilege($process, [ProcessPrivileges.Privilege]::TakeOwnership) | Out-Null
|
|
|
|
|
[ProcessPrivileges.ProcessExtensions]::RemovePrivilege($process, [ProcessPrivileges.Privilege]::Security) | Out-Null
|
|
|
|
|
Enable-Privileges -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
|
|
|
|
|
Disable-Privileges -WarningVariable privilegeWarnings -WarningAction SilentlyContinue
|
|
|
|
|
'WARNINGS:{0}' -f @($privilegeWarnings).Count
|
|
|
|
|
'@
|
|
|
|
|
|
|
|
|
|
$output = & (Get-Process -Id $PID).Path -NoProfile -NonInteractive -ExecutionPolicy Bypass -File $script -ModulePath ([IO.Path]::GetFullPath($modulePath))
|
|
|
|
|
|
|
|
|
|
$output | Should -Contain 'WARNINGS:0'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Describe 'Inheritance cmdlets' {
|
|
|
|
|
Context 'When the module setting EnablePrivileges is $false' {
|
|
|
|
|
BeforeAll {
|
|
|
|
|
$privateData['EnablePrivileges'] = $false
|
|
|
|
|
$file = New-TestSandboxItem -Sandbox $sandbox -Name 'Inheritance'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AfterAll {
|
|
|
|
|
$privateData['EnablePrivileges'] = $enablePrivileges
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Before 5.0.0, the inheritance cmdlets enabled the privileges anyway and left them enabled.
|
|
|
|
|
It '<_> should leave the privileges disabled' -Skip:(-not $holdsPrivileges) -ForEach @(
|
|
|
|
|
'Get-NTFSInheritance', 'Set-NTFSInheritance', 'Enable-NTFSAccessInheritance',
|
|
|
|
|
'Disable-NTFSAccessInheritance', 'Enable-NTFSAuditInheritance', 'Disable-NTFSAuditInheritance'
|
|
|
|
|
) {
|
|
|
|
|
Get-BackupPrivilegeState | Should -Be 'Disabled'
|
|
|
|
|
|
|
|
|
|
& $_ -Path $file -ErrorAction SilentlyContinue | Out-Null
|
|
|
|
|
|
|
|
|
|
Get-BackupPrivilegeState | Should -Be 'Disabled'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Describe 'Privileges when the pipeline stops early' {
|
|
|
|
|
BeforeAll {
|
fix: disable the privileges by their current state when a cmdlet ends
A cmdlet that enables the Backup, Restore, Take Ownership, and Security
privileges decided which ones to disable on the states that it had read
when it enabled them, and stopped at the first one that failed. When
another command in the pipeline, such as Disable-Privileges, had disabled
one of them, the cmdlet stopped with "Priviledge already disabled" and
left the privileges after that one enabled. After an early stop, which
Dispose handles since this branch, it left them enabled without any
message, because PowerShell ignores exceptions thrown in Dispose; and
Disable-Privileges threw that exception in Dispose on every call while
the privileges were disabled. 4.2.6 already decided on the old states.
DisablePrivilege now reads the current state, and the cleanup tries every
privilege: in EndProcessing, a privilege that it can't disable gives a
warning; in Dispose, it is ignored.
The early-stop tests now pin EnablePrivileges and check that the cmdlet
had enabled the privileges, so that they can't pass without testing
anything.
Found by the security review of fcb370e..00c3646 (findings 1 to 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
# The cmdlets enable the privileges only with this setting; without it, these tests would prove nothing.
|
|
|
|
|
$privateData['EnablePrivileges'] = $true
|
|
|
|
|
$files = 1..3 | ForEach-Object -Process { New-TestSandboxItem -Sandbox $sandbox -Name "Stopped$_" }
|
|
|
|
|
$missing = Join-Path -Path $sandbox -ChildPath 'StoppedMissing.txt'
|
|
|
|
|
}
|
|
|
|
|
|
fix: disable the privileges by their current state when a cmdlet ends
A cmdlet that enables the Backup, Restore, Take Ownership, and Security
privileges decided which ones to disable on the states that it had read
when it enabled them, and stopped at the first one that failed. When
another command in the pipeline, such as Disable-Privileges, had disabled
one of them, the cmdlet stopped with "Priviledge already disabled" and
left the privileges after that one enabled. After an early stop, which
Dispose handles since this branch, it left them enabled without any
message, because PowerShell ignores exceptions thrown in Dispose; and
Disable-Privileges threw that exception in Dispose on every call while
the privileges were disabled. 4.2.6 already decided on the old states.
DisablePrivilege now reads the current state, and the cleanup tries every
privilege: in EndProcessing, a privilege that it can't disable gives a
warning; in Dispose, it is ignored.
The early-stop tests now pin EnablePrivileges and check that the cmdlet
had enabled the privileges, so that they can't pass without testing
anything.
Found by the security review of fcb370e..00c3646 (findings 1 to 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
AfterAll {
|
|
|
|
|
$privateData['EnablePrivileges'] = $enablePrivileges
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BeforeEach {
|
|
|
|
|
Disable-Privileges -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AfterEach {
|
|
|
|
|
# A failing test must not leave the privileges enabled for the tests that follow.
|
|
|
|
|
Disable-Privileges -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Before 5.0.0-rc6, a cmdlet disabled the privileges that it had enabled only in EndProcessing, which PowerShell
|
|
|
|
|
# skips when a later command or a terminating error stops the pipeline. The Backup, Restore, Take Ownership, and
|
|
|
|
|
# Security privileges then stayed enabled in the session.
|
|
|
|
|
It 'Should disable the privileges after Select-Object -First stops the pipeline' -Skip:(-not $holdsPrivileges) {
|
|
|
|
|
Get-BackupPrivilegeState | Should -Be 'Disabled'
|
|
|
|
|
|
fix: disable the privileges by their current state when a cmdlet ends
A cmdlet that enables the Backup, Restore, Take Ownership, and Security
privileges decided which ones to disable on the states that it had read
when it enabled them, and stopped at the first one that failed. When
another command in the pipeline, such as Disable-Privileges, had disabled
one of them, the cmdlet stopped with "Priviledge already disabled" and
left the privileges after that one enabled. After an early stop, which
Dispose handles since this branch, it left them enabled without any
message, because PowerShell ignores exceptions thrown in Dispose; and
Disable-Privileges threw that exception in Dispose on every call while
the privileges were disabled. 4.2.6 already decided on the old states.
DisablePrivilege now reads the current state, and the cleanup tries every
privilege: in EndProcessing, a privilege that it can't disable gives a
warning; in Dispose, it is ignored.
The early-stop tests now pin EnablePrivileges and check that the cmdlet
had enabled the privileges, so that they can't pass without testing
anything.
Found by the security review of fcb370e..00c3646 (findings 1 to 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
$stateWhileRunning = Get-NTFSOwner -Path $files | ForEach-Object -Process { Get-BackupPrivilegeState } |
|
|
|
|
|
Select-Object -First 1
|
|
|
|
|
|
fix: disable the privileges by their current state when a cmdlet ends
A cmdlet that enables the Backup, Restore, Take Ownership, and Security
privileges decided which ones to disable on the states that it had read
when it enabled them, and stopped at the first one that failed. When
another command in the pipeline, such as Disable-Privileges, had disabled
one of them, the cmdlet stopped with "Priviledge already disabled" and
left the privileges after that one enabled. After an early stop, which
Dispose handles since this branch, it left them enabled without any
message, because PowerShell ignores exceptions thrown in Dispose; and
Disable-Privileges threw that exception in Dispose on every call while
the privileges were disabled. 4.2.6 already decided on the old states.
DisablePrivilege now reads the current state, and the cleanup tries every
privilege: in EndProcessing, a privilege that it can't disable gives a
warning; in Dispose, it is ignored.
The early-stop tests now pin EnablePrivileges and check that the cmdlet
had enabled the privileges, so that they can't pass without testing
anything.
Found by the security review of fcb370e..00c3646 (findings 1 to 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
$stateWhileRunning | Should -Be 'Enabled'
|
|
|
|
|
Get-BackupPrivilegeState | Should -Be 'Disabled'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'Should disable the privileges after a terminating error' -Skip:(-not $holdsPrivileges) {
|
|
|
|
|
Get-BackupPrivilegeState | Should -Be 'Disabled'
|
fix: disable the privileges by their current state when a cmdlet ends
A cmdlet that enables the Backup, Restore, Take Ownership, and Security
privileges decided which ones to disable on the states that it had read
when it enabled them, and stopped at the first one that failed. When
another command in the pipeline, such as Disable-Privileges, had disabled
one of them, the cmdlet stopped with "Priviledge already disabled" and
left the privileges after that one enabled. After an early stop, which
Dispose handles since this branch, it left them enabled without any
message, because PowerShell ignores exceptions thrown in Dispose; and
Disable-Privileges threw that exception in Dispose on every call while
the privileges were disabled. 4.2.6 already decided on the old states.
DisablePrivilege now reads the current state, and the cleanup tries every
privilege: in EndProcessing, a privilege that it can't disable gives a
warning; in Dispose, it is ignored.
The early-stop tests now pin EnablePrivileges and check that the cmdlet
had enabled the privileges, so that they can't pass without testing
anything.
Found by the security review of fcb370e..00c3646 (findings 1 to 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
$statesWhileRunning = New-Object -TypeName 'System.Collections.Generic.List[string]'
|
|
|
|
|
|
fix: disable the privileges by their current state when a cmdlet ends
A cmdlet that enables the Backup, Restore, Take Ownership, and Security
privileges decided which ones to disable on the states that it had read
when it enabled them, and stopped at the first one that failed. When
another command in the pipeline, such as Disable-Privileges, had disabled
one of them, the cmdlet stopped with "Priviledge already disabled" and
left the privileges after that one enabled. After an early stop, which
Dispose handles since this branch, it left them enabled without any
message, because PowerShell ignores exceptions thrown in Dispose; and
Disable-Privileges threw that exception in Dispose on every call while
the privileges were disabled. 4.2.6 already decided on the old states.
DisablePrivilege now reads the current state, and the cleanup tries every
privilege: in EndProcessing, a privilege that it can't disable gives a
warning; in Dispose, it is ignored.
The early-stop tests now pin EnablePrivileges and check that the cmdlet
had enabled the privileges, so that they can't pass without testing
anything.
Found by the security review of fcb370e..00c3646 (findings 1 to 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
{
|
|
|
|
|
Get-NTFSAccess -Path $files[0], $missing -ErrorAction Stop |
|
|
|
|
|
ForEach-Object -Process { $statesWhileRunning.Add((Get-BackupPrivilegeState)) }
|
|
|
|
|
} | Should -Throw
|
|
|
|
|
|
fix: disable the privileges by their current state when a cmdlet ends
A cmdlet that enables the Backup, Restore, Take Ownership, and Security
privileges decided which ones to disable on the states that it had read
when it enabled them, and stopped at the first one that failed. When
another command in the pipeline, such as Disable-Privileges, had disabled
one of them, the cmdlet stopped with "Priviledge already disabled" and
left the privileges after that one enabled. After an early stop, which
Dispose handles since this branch, it left them enabled without any
message, because PowerShell ignores exceptions thrown in Dispose; and
Disable-Privileges threw that exception in Dispose on every call while
the privileges were disabled. 4.2.6 already decided on the old states.
DisablePrivilege now reads the current state, and the cleanup tries every
privilege: in EndProcessing, a privilege that it can't disable gives a
warning; in Dispose, it is ignored.
The early-stop tests now pin EnablePrivileges and check that the cmdlet
had enabled the privileges, so that they can't pass without testing
anything.
Found by the security review of fcb370e..00c3646 (findings 1 to 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
$statesWhileRunning | Should -Not -BeNullOrEmpty
|
|
|
|
|
$statesWhileRunning | Should -Not -Contain 'Disabled'
|
|
|
|
|
Get-BackupPrivilegeState | Should -Be 'Disabled'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'Enable-Privileges should keep the privileges enabled also when the pipeline stops early' -Skip:(-not $holdsPrivileges) {
|
|
|
|
|
Enable-Privileges -PassThru | Select-Object -First 1 | Out-Null
|
|
|
|
|
|
|
|
|
|
Get-BackupPrivilegeState | Should -Be 'Enabled'
|
|
|
|
|
}
|
|
|
|
|
}
|
fix: disable the privileges by their current state when a cmdlet ends
A cmdlet that enables the Backup, Restore, Take Ownership, and Security
privileges decided which ones to disable on the states that it had read
when it enabled them, and stopped at the first one that failed. When
another command in the pipeline, such as Disable-Privileges, had disabled
one of them, the cmdlet stopped with "Priviledge already disabled" and
left the privileges after that one enabled. After an early stop, which
Dispose handles since this branch, it left them enabled without any
message, because PowerShell ignores exceptions thrown in Dispose; and
Disable-Privileges threw that exception in Dispose on every call while
the privileges were disabled. 4.2.6 already decided on the old states.
DisablePrivilege now reads the current state, and the cleanup tries every
privilege: in EndProcessing, a privilege that it can't disable gives a
warning; in Dispose, it is ignored.
The early-stop tests now pin EnablePrivileges and check that the cmdlet
had enabled the privileges, so that they can't pass without testing
anything.
Found by the security review of fcb370e..00c3646 (findings 1 to 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
|
|
|
|
|
Describe 'Privileges that another command in the pipeline changes' {
|
|
|
|
|
BeforeAll {
|
|
|
|
|
$privateData['EnablePrivileges'] = $true
|
|
|
|
|
$files = 1..3 | ForEach-Object -Process { New-TestSandboxItem -Sandbox $sandbox -Name "Changed$_" }
|
|
|
|
|
|
|
|
|
|
function Disable-TakeOwnershipOnce {
|
|
|
|
|
# Passes the objects on and disables the Take Ownership privilege when the first one passes, as another
|
|
|
|
|
# command in the pipeline can. Records the state of the Backup privilege at that moment.
|
|
|
|
|
param (
|
|
|
|
|
[Parameter(ValueFromPipeline)]
|
|
|
|
|
[object]
|
|
|
|
|
$InputObject,
|
|
|
|
|
|
|
|
|
|
[Parameter(Mandatory)]
|
|
|
|
|
[AllowEmptyCollection()]
|
|
|
|
|
[System.Collections.Generic.List[string]]
|
|
|
|
|
$BackupState
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
begin {
|
|
|
|
|
$first = $true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
process {
|
|
|
|
|
if ($first) {
|
|
|
|
|
$BackupState.Add((Get-BackupPrivilegeState))
|
|
|
|
|
$null = [ProcessPrivileges.ProcessExtensions]::DisablePrivilege(
|
|
|
|
|
[System.Diagnostics.Process]::GetCurrentProcess(), [ProcessPrivileges.Privilege]::TakeOwnership
|
|
|
|
|
)
|
|
|
|
|
$first = $false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$InputObject
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AfterAll {
|
|
|
|
|
$privateData['EnablePrivileges'] = $enablePrivileges
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BeforeEach {
|
|
|
|
|
Disable-Privileges -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AfterEach {
|
|
|
|
|
Disable-Privileges -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Before 5.0.0-rc6, a cmdlet decided which privileges to disable on the states that it had read when it enabled
|
|
|
|
|
# them. A privilege that another command had disabled since then stopped it with "Priviledge already disabled",
|
|
|
|
|
# and the privileges after that one in its list stayed enabled.
|
|
|
|
|
It 'Should disable the other privileges when another command disabled one of them' -Skip:(-not $holdsPrivileges) {
|
|
|
|
|
$backupState = New-Object -TypeName 'System.Collections.Generic.List[string]'
|
|
|
|
|
|
|
|
|
|
{ Get-NTFSOwner -Path $files | Disable-TakeOwnershipOnce -BackupState $backupState | Out-Null } | Should -Not -Throw
|
|
|
|
|
|
|
|
|
|
$backupState | Should -Be 'Enabled'
|
|
|
|
|
Get-EnabledFileSystemPrivilege | Should -BeNullOrEmpty
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'Should disable the other privileges when another command disabled one of them and the pipeline stops early' -Skip:(-not $holdsPrivileges) {
|
|
|
|
|
$backupState = New-Object -TypeName 'System.Collections.Generic.List[string]'
|
|
|
|
|
|
|
|
|
|
Get-NTFSOwner -Path $files | Disable-TakeOwnershipOnce -BackupState $backupState | Select-Object -First 1 | Out-Null
|
|
|
|
|
|
|
|
|
|
$backupState | Should -Be 'Enabled'
|
|
|
|
|
Get-EnabledFileSystemPrivilege | Should -BeNullOrEmpty
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'Should not fail when Disable-Privileges runs inside the pipeline' -Skip:(-not $holdsPrivileges) {
|
|
|
|
|
{
|
|
|
|
|
Get-NTFSOwner -Path $files |
|
|
|
|
|
ForEach-Object -Process { Disable-Privileges -WarningAction SilentlyContinue; $_ } |
|
|
|
|
|
Out-Null
|
|
|
|
|
} | Should -Not -Throw
|
|
|
|
|
|
|
|
|
|
Get-EnabledFileSystemPrivilege | Should -BeNullOrEmpty
|
|
|
|
|
}
|
|
|
|
|
}
|