|
|
|
|
<#
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|