test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
[ CmdletBinding ( ) ]
param (
[ Parameter ( Mandatory ) ] [ ValidateSet ( 'Snapshot' , 'Verify' , 'Repair' ) ] [string] $Mode ,
[ Parameter ( Mandatory ) ] [string] $SidFile ,
[ Parameter ( Mandatory ) ] [string] $OutFile ,
[string] $LabName = 'NtfsSecurityOsMatrixLab' ,
[string[]] $DomainController = @ ( 'OSDC1' ) ,
test(lab): check the probe residue, read the cell timeline, and model the stale managers
Test-MatrixCleanup.ps1 now counts and repairs the probe folders
(C:\NtfsProbeRecreation and C:\NtfsProbeModules), the local NtfsProbe*
users with their profiles, and the NtfsProbe* objects of the directory.
The scripts of the matrix default to the client OSWin11E.
Export-CellTimeline.ps1 writes one row for every cell, edition, and
Admin role: the module, the account and its relative ID, the times, and
the three effective-access tests. Test-StaleAuthzModel.ps1 replays such a
timeline against a model of the failures: the fit, a listing of the runs,
the cells of a controller that reuses the account name, and a permutation
test.
The comment in the controller says what the replay showed. The code of
the controller is unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
[string[]] $Machine = @ ( 'OSFile19' , 'OSFile22' , 'OSFile25' , 'OSWin11E' )
test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
)
# Independent end-state check of the fixture of Invoke-NTFSSecurityLabTest.ps1 in a lab (Windows PowerShell 5.1, on the host). Snapshot
# records the SIDs of the NtfsLive* accounts while the fixture exists. Verify reads the domains and every machine again, and reports
# the organizational unit, the accounts, the share, the folders, the local group, the memberships of Administrators, Access Control
test(lab): give each new fixture a new account for the effective-access case
When an account is deleted and created again with the same name, a Kerberos S4U
logon for it keeps returning the SID and the groups of the deleted account for
a while, on the domain controller, the client, and the file server. The matrix
deletes the fixture after each cell and creates it for the next, so the
effective-access tests of the Admin role found no access for the new account in
cells that followed within minutes (Windows Server 2022 cell, candidate and
baseline alike, shown by a probe that creates the accounts in a loop). A new
fixture now gets NtfsLiveSubject and four digits; a fixture that exists keeps
its account.
The end-state check of the matrix also reports leftover scheduled tasks, stage
folders, standard users, and probe accounts, which the review asked for.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
# Assistance Operators, and Remote Management Users, and the profiles of those SIDs, and what the suite runs and the probes of the kit leave
# behind (scheduled tasks, items in the stage folders, the folders of the account probe, standard users NtfsProbe* with their profiles and their
# entries in Performance Log Users, probe accounts of the domain). The result is judged from this log, never from the wrapper of the controller
# or a global error count. Repair is for a run whose removal failed: with the SIDs of the snapshot, it removes what that run left on the machines
# (the memberships, also of orphaned SIDs, which net localgroup deletes by SID; the share; the local group; the folders) and what the kit leaves
# (the items in the stage folders, the folders of the account probe, the scheduled tasks NtfsMatrix*, the standard users NtfsProbe* with their
# profiles and their entries in Performance Log Users, and the domain accounts NtfsProbe*), and then reports like Verify.
test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
& {
$ErrorActionPreference = 'Stop'
# -File passes an array as one string, so a list may arrive as 'A,B'.
$DomainController = @ ( $DomainController | ForEach-Object -Process { $_ -split ',' } | Where-Object -FilterScript { $_ } )
$Machine = @ ( $Machine | ForEach-Object -Process { $_ -split ',' } | Where-Object -FilterScript { $_ } )
'[{0:yyyy-MM-dd HH:mm:ss}Z] START matrix-cleanup-{1} lab={2}' -f [DateTime] :: UtcNow , $Mode , $LabName
Import-Lab -Name $LabName -NoValidation -NoDisplay
$labCommand = @ { NoDisplay = $true ; PassThru = $true ; ErrorAction = 'Stop' }
test(lab): check the probe residue, read the cell timeline, and model the stale managers
Test-MatrixCleanup.ps1 now counts and repairs the probe folders
(C:\NtfsProbeRecreation and C:\NtfsProbeModules), the local NtfsProbe*
users with their profiles, and the NtfsProbe* objects of the directory.
The scripts of the matrix default to the client OSWin11E.
Export-CellTimeline.ps1 writes one row for every cell, edition, and
Admin role: the module, the account and its relative ID, the times, and
the three effective-access tests. Test-StaleAuthzModel.ps1 replays such a
timeline against a model of the failures: the fit, a listing of the runs,
the cells of a controller that reuses the account name, and a permutation
test.
The comment in the controller says what the replay showed. The code of
the controller is unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
if ( $Mode -eq 'Repair' ) {
# The accounts that the probes of the kit create in the domain, by their prefix; this runs before the directory is read, so that the report shows the result.
$repairDirectoryScript = {
Import-Module -Name ActiveDirectory
$domain = Get-ADDomain
$objects = @ ( Get-ADObject -LDAPFilter '(sAMAccountName=NtfsProbe*)' -SearchBase $domain . DistinguishedName -Server $domain . PDCEmulator )
foreach ( $object in $objects ) { Remove-ADObject -Identity $object -Recursive -Confirm : $false -Server $domain . PDCEmulator }
'{0}: removed {1} account(s) named NtfsProbe*' -f $domain . DNSRoot , $objects . Count
}
foreach ( $name in $DomainController ) {
foreach ( $message in @ ( Invoke-LabCommand -ComputerName $name -ActivityName " Repair the directory of $ name " -ScriptBlock $repairDirectoryScript @labCommand ) ) {
'{0,-9} repair: {1}' -f $name , $message
}
}
}
test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
$directoryScript = {
Import-Module -Name ActiveDirectory
$domain = Get-ADDomain
$unit = Get-ADOrganizationalUnit -LDAPFilter '(ou=NTFSSecurityLive)' -SearchBase $domain . DistinguishedName -SearchScope OneLevel -Server $domain . PDCEmulator
[pscustomobject] @ {
test(lab): give each new fixture a new account for the effective-access case
When an account is deleted and created again with the same name, a Kerberos S4U
logon for it keeps returning the SID and the groups of the deleted account for
a while, on the domain controller, the client, and the file server. The matrix
deletes the fixture after each cell and creates it for the next, so the
effective-access tests of the Admin role found no access for the new account in
cells that followed within minutes (Windows Server 2022 cell, candidate and
baseline alike, shown by a probe that creates the accounts in a loop). A new
fixture now gets NtfsLiveSubject and four digits; a fixture that exists keeps
its account.
The end-state check of the matrix also reports leftover scheduled tasks, stage
folders, standard users, and probe accounts, which the review asked for.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
Domain = $domain . DNSRoot
Unit = [bool] $unit
Sids = @ ( Get-ADObject -LDAPFilter '(sAMAccountName=NtfsLive*)' -SearchBase $domain . DistinguishedName -Server $domain . PDCEmulator -Properties objectSid , sAMAccountName |
test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
ForEach-Object -Process { '{0}={1}' -f $_ . sAMAccountName , $_ . objectSid . Value } )
test(lab): give each new fixture a new account for the effective-access case
When an account is deleted and created again with the same name, a Kerberos S4U
logon for it keeps returning the SID and the groups of the deleted account for
a while, on the domain controller, the client, and the file server. The matrix
deletes the fixture after each cell and creates it for the next, so the
effective-access tests of the Admin role found no access for the new account in
cells that followed within minutes (Windows Server 2022 cell, candidate and
baseline alike, shown by a probe that creates the accounts in a loop). A new
fixture now gets NtfsLiveSubject and four digits; a fixture that exists keeps
its account.
The end-state check of the matrix also reports leftover scheduled tasks, stage
folders, standard users, and probe accounts, which the review asked for.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
ProbeAccounts = @ ( Get-ADObject -LDAPFilter '(sAMAccountName=NtfsProbe*)' -SearchBase $domain . DistinguishedName -Server $domain . PDCEmulator ) . Count
test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
}
}
$directory = @ ( foreach ( $name in $DomainController ) { Invoke-LabCommand -ComputerName $name -ActivityName " Read the fixture of $ name " -ScriptBlock $directoryScript @labCommand } )
foreach ( $state in $directory ) {
test(lab): give each new fixture a new account for the effective-access case
When an account is deleted and created again with the same name, a Kerberos S4U
logon for it keeps returning the SID and the groups of the deleted account for
a while, on the domain controller, the client, and the file server. The matrix
deletes the fixture after each cell and creates it for the next, so the
effective-access tests of the Admin role found no access for the new account in
cells that followed within minutes (Windows Server 2022 cell, candidate and
baseline alike, shown by a probe that creates the accounts in a loop). A new
fixture now gets NtfsLiveSubject and four digits; a fixture that exists keeps
its account.
The end-state check of the matrix also reports leftover scheduled tasks, stage
folders, standard users, and probe accounts, which the review asked for.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
'{0,-14} OU NTFSSecurityLive: {1,-5} NtfsLive* accounts: {2}; probe accounts: {3}' -f $state . Domain , $state . Unit , ( $ ( if ( $state . Sids ) { $state . Sids -join ', ' } else { 'none' } ) ) , $state . ProbeAccounts
test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
}
if ( $Mode -eq 'Snapshot' ) {
$sids = @ ( $directory | ForEach-Object -Process { $_ . Sids } | ForEach-Object -Process { ( $_ -split '=' , 2 ) [ 1 ] } )
ConvertTo-Json -InputObject $sids | Set-Content -LiteralPath $SidFile -Encoding utf8
" saved $( $sids . Count ) SIDs to $ SidFile "
}
else {
$sids = [string[]] ( Get-Content -LiteralPath $SidFile -Raw | ConvertFrom-Json )
" checking $( $sids . Count ) SIDs of the snapshot "
$machineScript = {
param ( $Sid )
# net localgroup lists an orphaned SID, which Get-LocalGroupMember in Windows PowerShell 5.1 fails on and skips.
$groups = foreach ( $groupSid in 'S-1-5-32-544' , 'S-1-5-32-579' , 'S-1-5-32-580' ) {
$groupName = ( [System.Security.Principal.SecurityIdentifier] $groupSid ) . Translate ( [System.Security.Principal.NTAccount] ) . Value -replace '^.*\\' , ''
$members = @ ( & net . exe localgroup $groupName 2 > & 1 | ForEach-Object -Process { " $ _ " . Trim ( ) } )
$hits = @ ( $members | Where-Object -FilterScript { $_ -match 'NtfsLive' -or $_ -in $Sid } )
'{0}: {1} fixture member(s)' -f $groupSid , $hits . Count
}
# What the account probe leaves: the profiles and the profile folders of its users, and its entries in Performance Log Users. net.exe lists a
# local user by its bare name, and an entry of a deleted domain account as its SID, or as its name for a while (the cache of names).
$usersFolder = Join-Path -Path $env:SystemDrive -ChildPath 'Users'
$probePaths = @ ( @ ( Get-CimInstance -ClassName Win32_UserProfile | Where-Object -FilterScript { $_ . LocalPath -like ( Join-Path -Path $usersFolder -ChildPath 'NtfsProbe*' ) } | ForEach-Object -Process { $_ . LocalPath } ) +
@ ( Get-ChildItem -LiteralPath $usersFolder -Filter 'NtfsProbe*' -Force -ErrorAction SilentlyContinue | ForEach-Object -Process { $_ . FullName } ) | Sort-Object -Unique )
$logGroup = ( [System.Security.Principal.SecurityIdentifier] 'S-1-5-32-559' ) . Translate ( [System.Security.Principal.NTAccount] ) . Value -replace '^.*\\' , ''
$probeMembers = @ ( & net . exe localgroup $logGroup 2 > & 1 | ForEach-Object -Process { " $ _ " . Trim ( ) } | Where-Object -FilterScript { $_ -match '^S-1-5-21-[\d-]+$' -or $_ -match 'NtfsProbe' } )
test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
[pscustomobject] @ {
Share = [bool] ( Get-SmbShare -Name 'NTFSSecurityLive' -ErrorAction SilentlyContinue )
ShareRoot = Test-Path -LiteralPath 'C:\NTFSSecurityLive'
Payload = Test-Path -LiteralPath 'C:\NTFSSecurityLab'
LocalGroup = [bool] ( Get-LocalGroup -Name 'NtfsLiveLocal' -ErrorAction SilentlyContinue )
Groups = $groups -join '; '
Profiles = @ ( Get-CimInstance -ClassName Win32_UserProfile | Where-Object -FilterScript { $_ . SID -in $Sid } ) . Count
test(lab): check the probe residue, read the cell timeline, and model the stale managers
Test-MatrixCleanup.ps1 now counts and repairs the probe folders
(C:\NtfsProbeRecreation and C:\NtfsProbeModules), the local NtfsProbe*
users with their profiles, and the NtfsProbe* objects of the directory.
The scripts of the matrix default to the client OSWin11E.
Export-CellTimeline.ps1 writes one row for every cell, edition, and
Admin role: the module, the account and its relative ID, the times, and
the three effective-access tests. Test-StaleAuthzModel.ps1 replays such a
timeline against a model of the failures: the fit, a listing of the runs,
the cells of a controller that reuses the account name, and a permutation
test.
The comment in the controller says what the replay showed. The code of
the controller is unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
# What the suite runs and the probes of the kit leave behind: scheduled tasks, items in the stage folders, the folders of the
# account probe, and standard users
Tasks = @ ( Get-ScheduledTask -ErrorAction SilentlyContinue | Where-Object -FilterScript { $_ . TaskName -like 'NtfsMatrix*' } ) . Count
Stages = @ ( 'C:\NtfsMatrixLocal' , 'C:\NtfsMatrixProbe' | Where-Object -FilterScript { Test-Path -LiteralPath $_ } | ForEach-Object -Process { Get-ChildItem -LiteralPath $_ -Force -ErrorAction SilentlyContinue } ) . Count +
test(lab): check the probe residue, read the cell timeline, and model the stale managers
Test-MatrixCleanup.ps1 now counts and repairs the probe folders
(C:\NtfsProbeRecreation and C:\NtfsProbeModules), the local NtfsProbe*
users with their profiles, and the NtfsProbe* objects of the directory.
The scripts of the matrix default to the client OSWin11E.
Export-CellTimeline.ps1 writes one row for every cell, edition, and
Admin role: the module, the account and its relative ID, the times, and
the three effective-access tests. Test-StaleAuthzModel.ps1 replays such a
timeline against a model of the failures: the fit, a listing of the runs,
the cells of a controller that reuses the account name, and a permutation
test.
The comment in the controller says what the replay showed. The code of
the controller is unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
@ ( 'C:\NtfsProbeRecreation' , 'C:\NtfsProbeModules' | Where-Object -FilterScript { Test-Path -LiteralPath $_ } ) . Count
Users = @ ( Get-LocalUser -ErrorAction SilentlyContinue | Where-Object -FilterScript { $_ . Name -like 'NtfsProbe*' } ) . Count
ProbeProfiles = $probePaths . Count
ProbeMembers = $probeMembers . Count
test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
}
}
foreach ( $name in $Machine ) {
if ( $Mode -eq 'Repair' ) {
$repairScript = {
param ( $Sid )
$messages = New-Object -TypeName 'System.Collections.Generic.List[string]'
foreach ( $groupSid in 'S-1-5-32-544' , 'S-1-5-32-579' , 'S-1-5-32-580' ) {
$groupName = ( [System.Security.Principal.SecurityIdentifier] $groupSid ) . Translate ( [System.Security.Principal.NTAccount] ) . Value -replace '^.*\\' , ''
$named = @ ( & net . exe localgroup $groupName 2 > & 1 | ForEach-Object -Process { " $ _ " . Trim ( ) } | Where-Object -FilterScript { $_ -match 'NtfsLive' } )
foreach ( $member in @ ( $Sid ) + $named ) { $null = & net . exe localgroup $groupName $member / delete 2 > & 1 }
}
if ( Get-SmbShare -Name 'NTFSSecurityLive' -ErrorAction SilentlyContinue ) { Remove-SmbShare -Name 'NTFSSecurityLive' -Force }
$null = & net . exe localgroup 'NtfsLiveLocal' / delete 2 > & 1
foreach ( $path in 'C:\NTFSSecurityLive' , 'C:\NTFSSecurityLab' ) {
$command = '$errors = @(); Remove-Item -LiteralPath ''__PATH__'' -Recurse -Force -ErrorAction SilentlyContinue -ErrorVariable errors; $errors | ForEach-Object -Process { "$_" }' . Replace ( '__PATH__' , $path )
$encoded = [Convert] :: ToBase64String ( [System.Text.Encoding] :: Unicode . GetBytes ( $command ) )
$attempt = 0
while ( ( Test-Path -LiteralPath $path ) -and $attempt -lt 6 ) {
$attempt + +
if ( $attempt -gt 1 ) { Start-Sleep -Seconds 5 }
$null = & ( Join-Path -Path $env:ProgramFiles -ChildPath 'PowerShell\7\pwsh.exe' ) -NoProfile -NonInteractive -EncodedCommand $encoded 2 > & 1
}
$messages . Add ( ( '{0}: present after {1} attempt(s): {2}' -f $path , $attempt , ( Test-Path -LiteralPath $path ) ) )
}
test(lab): check the probe residue, read the cell timeline, and model the stale managers
Test-MatrixCleanup.ps1 now counts and repairs the probe folders
(C:\NtfsProbeRecreation and C:\NtfsProbeModules), the local NtfsProbe*
users with their profiles, and the NtfsProbe* objects of the directory.
The scripts of the matrix default to the client OSWin11E.
Export-CellTimeline.ps1 writes one row for every cell, edition, and
Admin role: the module, the account and its relative ID, the times, and
the three effective-access tests. Test-StaleAuthzModel.ps1 replays such a
timeline against a model of the failures: the fit, a listing of the runs,
the cells of a controller that reuses the account name, and a permutation
test.
The comment in the controller says what the replay showed. The code of
the controller is unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
# What the suite runner and the probes of the kit left: the items in their stage folders, the folders of the account probe,
# their scheduled tasks, and the standard users that the probe of the authorization managers creates (with their profiles)
foreach ( $stage in 'C:\NtfsMatrixLocal' , 'C:\NtfsMatrixProbe' ) {
if ( Test-Path -LiteralPath $stage ) { Get-ChildItem -LiteralPath $stage -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }
}
test(lab): check the probe residue, read the cell timeline, and model the stale managers
Test-MatrixCleanup.ps1 now counts and repairs the probe folders
(C:\NtfsProbeRecreation and C:\NtfsProbeModules), the local NtfsProbe*
users with their profiles, and the NtfsProbe* objects of the directory.
The scripts of the matrix default to the client OSWin11E.
Export-CellTimeline.ps1 writes one row for every cell, edition, and
Admin role: the module, the account and its relative ID, the times, and
the three effective-access tests. Test-StaleAuthzModel.ps1 replays such a
timeline against a model of the failures: the fit, a listing of the runs,
the cells of a controller that reuses the account name, and a permutation
test.
The comment in the controller says what the replay showed. The code of
the controller is unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
foreach ( $folder in 'C:\NtfsProbeRecreation' , 'C:\NtfsProbeModules' ) {
if ( Test-Path -LiteralPath $folder ) { Remove-Item -LiteralPath $folder -Recurse -Force -ErrorAction SilentlyContinue }
}
Get-ScheduledTask -ErrorAction SilentlyContinue | Where-Object -FilterScript { $_ . TaskName -like 'NtfsMatrix*' } | ForEach-Object -Process { Unregister-ScheduledTask -TaskName $_ . TaskName -Confirm : $false -ErrorAction SilentlyContinue }
foreach ( $user in @ ( Get-LocalUser -ErrorAction SilentlyContinue | Where-Object -FilterScript { $_ . Name -like 'NtfsProbe*' } ) ) { Remove-LocalUser -SID $user . SID -ErrorAction SilentlyContinue }
# The entries of the probe in Performance Log Users go by SID or name through the cmdlet: net.exe doesn't take the SID of an account that its name cache still resolves.
$logGroup = ( [System.Security.Principal.SecurityIdentifier] 'S-1-5-32-559' ) . Translate ( [System.Security.Principal.NTAccount] ) . Value -replace '^.*\\' , ''
foreach ( $member in @ ( & net . exe localgroup $logGroup 2 > & 1 | ForEach-Object -Process { " $ _ " . Trim ( ) } | Where-Object -FilterScript { $_ -match '^S-1-5-21-[\d-]+$' -or $_ -match 'NtfsProbe' } ) ) {
Remove-LocalGroupMember -SID 'S-1-5-32-559' -Member $member -ErrorAction SilentlyContinue
test(lab): check the probe residue, read the cell timeline, and model the stale managers
Test-MatrixCleanup.ps1 now counts and repairs the probe folders
(C:\NtfsProbeRecreation and C:\NtfsProbeModules), the local NtfsProbe*
users with their profiles, and the NtfsProbe* objects of the directory.
The scripts of the matrix default to the client OSWin11E.
Export-CellTimeline.ps1 writes one row for every cell, edition, and
Admin role: the module, the account and its relative ID, the times, and
the three effective-access tests. Test-StaleAuthzModel.ps1 replays such a
timeline against a model of the failures: the fit, a listing of the runs,
the cells of a controller that reuses the account name, and a permutation
test.
The comment in the controller says what the replay showed. The code of
the controller is unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
}
# A profile that the last task of a probe user used stays loaded for a few seconds, so the removal is repeated. What stays is
# reported by the check that follows, found by its folder and not by its user, who is gone by now.
$usersFolder = Join-Path -Path $env:SystemDrive -ChildPath 'Users'
$attempt = 0
do {
$attempt + +
@ ( Get-CimInstance -ClassName Win32_UserProfile | Where-Object -FilterScript { $_ . LocalPath -like ( Join-Path -Path $usersFolder -ChildPath 'NtfsProbe*' ) } ) | Remove-CimInstance -ErrorAction SilentlyContinue
Get-ChildItem -LiteralPath $usersFolder -Filter 'NtfsProbe*' -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
$left = @ ( Get-CimInstance -ClassName Win32_UserProfile | Where-Object -FilterScript { $_ . LocalPath -like ( Join-Path -Path $usersFolder -ChildPath 'NtfsProbe*' ) } ) . Count +
@ ( Get-ChildItem -LiteralPath $usersFolder -Filter 'NtfsProbe*' -Force -ErrorAction SilentlyContinue ) . Count
if ( $left -gt 0 -and $attempt -lt 10 ) { Start-Sleep -Seconds 3 }
} while ( $left -gt 0 -and $attempt -lt 10 )
$messages . Add ( ( 'stage items, probe folders, probe users, their entries in the log group, and scheduled tasks of the kit removed; profile items left: {0} after {1} attempt(s)' -f $left , $attempt ) )
test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
$messages
}
foreach ( $message in @ ( Invoke-LabCommand -ComputerName $name -ActivityName " Repair $ name " -ScriptBlock $repairScript -ArgumentList ( , $sids ) @labCommand ) ) {
'{0,-9} repair: {1}' -f $name , $message
}
}
$state = Invoke-LabCommand -ComputerName $name -ActivityName " Check $ name " -ScriptBlock $machineScript -ArgumentList ( , $sids ) @labCommand
'{0,-9} share={1} C:\NTFSSecurityLive={2} C:\NTFSSecurityLab={3} NtfsLiveLocal={4} profiles={5}' -f $name , $state . Share , $state . ShareRoot , $state . Payload , $state . LocalGroup , $state . Profiles
' {0}' -f $state . Groups
' residue: scheduled tasks={0} stage items={1} probe users={2} probe profiles={3} probe group members={4}' -f $state . Tasks , $state . Stages , $state . Users , $state . ProbeProfiles , $state . ProbeMembers
test(lab): add the kit that deploys and runs the operating-system matrix
Tests\Lab\Acceptance gets the scripts of Decision 24, which extends the
acceptance of the live tests from one lab to several operating-system builds:
- Deploy-OsMatrixLab.ps1, Add-OsMatrixMachine.ps1, Complete-OsMatrixLab.ps1
and Repair-OsMatrixBoot.ps1 build NtfsSecurityOsMatrixLab with AutomatedLab
(Server 2019, 2022 and 2025 file servers, Windows 11 clients) and repair a
base image whose host-side bcdboot left an empty EFI system partition.
- Test-MatrixReadiness.ps1 and Test-MatrixCleanup.ps1 gate each run and prove
that it left nothing behind (fixture accounts, shares, folders, group
members, orphaned SIDs, profiles); -Mode Repair removes what is left.
- Run-MatrixSequence.ps1 runs the live controller for every cell of the matrix
and stops after an infrastructure failure.
- Run-MatrixLocalSuite.ps1 and Invoke-LocalSuite.ps1 run the module's own
Pester suite on each machine in both editions, elevated and as a basic user,
as scheduled tasks: a process started from a remoting session gets every
privilege enabled, which eight of the tests do not expect.
- Export-MatrixResults.ps1 collates the cells, the skipped tests and the
package hashes into the results table.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
}
}
'[{0:yyyy-MM-dd HH:mm:ss}Z] matrix-cleanup-{1}-DONE' -f [DateTime] :: UtcNow , $Mode
} * > & 1 | Out-File -FilePath $OutFile -Encoding utf8 -Width 400