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.
13 KiB
13 KiB
| status | last-verified | owner | source |
|---|---|---|---|
| current | 2026-10-08 | active-agent | repository evidence |
Tech context
Stack
- C# class libraries, old-style
.csproj, .NET Framework 4.5.2, solutionNTFSSecurity.sln(Visual Studio 2017 format). - Projects:
NTFSSecurity(cmdlets),Security2(ACL object model, Win32 interop),PrivilegeControlandProcessPrivileges(token privileges),Log,TestClient,NTFSSecurityTest(MSTest, minimal coverage). - NuGet (
packages.config): AlphaFS 2.2.x for long paths;System.Management.Automation.dll10.0.10586.0. For a drive or volume root, AlphaFSDirectoryInforeaches the device object, whileDirectory.Get/SetAccessControl('C:\')reaches the root folder (#41). - Module:
NTFSSecurity.psd1loadsNTFSSecurity.psm1(aliasesdir2,gi2,rm2,del2),NTFSSecurity.Init.ps1(Add-Type of the helper assemblies, prependsNTFSSecurity.format.ps1xml), andNTFSSecurity.dll. - Documentation: Markdown in
DocsandREADME.md, rendered by GitHub and published to the wiki by CI; no documentation site (Decisions 9 and 11). Cmdlet pages are platyPS 0.14 markdown (schema 2.0.0) inDocs/Cmdlets. - Help:
NTFSSecurity\en-US\NTFSSecurity.dll-Help.xml, generated fromDocs/Cmdletsand committed (Decision 8). - Tests: Pester 5 in
Tests, one file per area, against the Release build;Wiki.Tests.ps1(wiki conversion) runs without a build. - CI: GitHub Actions,
.github/workflows/ci.ymlwith the scripts in.github/scripts(Decision 11).
Environment
- Windows only (NTFS, Win32 security APIs).
- The Debug build writes straight into
C:\Program Files\WindowsPowerShell\Modules\NTFSSecurity\. - No Visual Studio MSBuild or .NET Framework targeting pack on the
workstation. A local build works with the .NET Framework MSBuild
(
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe) plus/p:CscToolPathto the Roslyncsc.exeof theMicrosoft.Net.Compilerspackage; the legacy C# 5 compiler fails with CS0136.dotnet msbuildfails on the binary resources inResources.resx(MSB3822, MSB3823). - platyPS 0.14.2, Pester 5.7.1, PSScriptAnalyzer, and powershell-yaml are
installed only for PowerShell 7. Windows PowerShell 5.1, started from
PowerShell 7, imports platyPS and Pester by full path
(
~\OneDrive\Documents\PowerShell\Modules\platyPS\0.14.2,C:\Program Files\PowerShell\Modules\Pester\5.7.1). Leave$env:PSModulePathalone: PowerShell 7 hands the child the Windows PowerShell default path, and clearing it leaves Windows PowerShell without its core modules (Pester fails:Add-Membernot found). - MarkdownLinkCheck is not installed, and
Save-Modulecrashed (FailFast) in PowerShell 7.6 on 2026-10-04. Download the 0.2.0 package fromhttps://www.powershellgallery.com/api/v2/package/MarkdownLinkCheck/0.2.0into$env:TEMP, extract it, and import it by path. - The first workstation is ARM64; PowerShell 7 runs as x64 under emulation.
- The NuGet cache (
~\.nuget\packages) holds every build dependency: copyalphafs\2.2.1,system.management.automation.dll\10.0.10586, andmicrosoft.netframework.referenceassemblies.net452\1.0.3intopackages\<Id>.<Version>, and pointCscToolPathatmicrosoft.net.compilers\4.2.0\tools. - The second workstation (x64, used since 2026-10-05) runs the agent
session elevated, so the tests that need privileges run there as in CI.
It has no NuGet cache with these packages: download each from
https://api.nuget.org/v3-flatcontainer/<id>/<version>/<id>.<version>.nupkg, extract the first three intopackages\<Id>.<Version>and the compilers into$env:TEMP; Pester 5.7.1 comes from the Gallery package API the same way, its folder first on$env:PSModulePathof the test process. The GitHub CLI is inC:\Program Files\GitHub CLI, outside the PATH of sessions started before its installation. - The third workstation (
ExHost, a Windows Server 2025 VM, x64, used since 2026-10-07) runs the agent session elevated and hosts the AutomatedLab labWindowsAccessControlLab(Decision 20) with Hyper-V and AutomatedLab 5.61.704. It has no NuGet cache or platyPS: check each nuget.org package against the SHA-512packageHashof its catalog entry (https://api.nuget.org/v3/registration5-semver1/<id>/<version>.json, thencatalogEntry), and each Gallery package againstPackageHashofapi/v2/Packages(Id='<id>',Version='<version>'). Pester 5.7.1 is inV:\Git\WindowsAccessControl\output\RequiredModules. The GitHub CLI 2.102.0 is inC:\Program Files\GitHub CLI, outside the PATH, and signed in asraandreesince 2026-10-08;Block-RemoteMutationdenies its mutating commands, so the agent uses it read-only. The lab domainsa.forest1.netandb.forest1.nethad a maximum password age of 42 days, so the password ofinstallexpired on 2026-09-15 and AutomatedLab got access denied; it never expires since 2026-10-07, as inforest1.net.
Constraints
ModuleVersionis5.0.0with the prerelease labelrc5. The latest stable tag and Gallery release is4.2.6. The manifest requires PowerShell 5.1 and .NET Framework 4.5.2, usesRootModule, and lists exactly 36 cmdlets;Test-ModuleManifestpasses in Windows PowerShell 5.1 and PowerShell 7.6.- The module source at
masterdiffers from tag4.2.6by the changes thatCHANGELOG.mdlists under[Unreleased], the release notes of each 5.0.0 prerelease. - PowerShell Gallery versions (publish dates): 4.0.0 (2015-08-19), 4.2.2 (2016-05-18), 4.2.3 (2016-05-19), 4.2.4 (2018-08-13), 4.2.5 (2019-07-11), 4.2.6 (2019-07-12), none with release notes; 5.0.0-rc1 (2026-10-04), 5.0.0-rc2 (2026-10-05), 5.0.0-rc3 and 5.0.0-rc4 (2026-10-06), 5.0.0-rc5 (2026-10-08), published by CI. Older versions were released on CodePlex only, and their dates are lost. The git history starts on 2016-10-10, when the project moved from CodePlex.
- Releases up to 4.2.6 were Debug builds published by hand, with the whole
output folder; their tags carry the previous version. From 5.0.0 on, CI
publishes on a version tag (Decision 12). GitHub releases attach
NTFSSecurity.zip. - CI: GitHub Actions on pull requests, pushes to
master, and version tags (Decision 11); AppVeyor and Read the Docs aren't used (Decision 9). CHANGELOG.mdlists user-visible changes only; CI and build-only changes get no entry (Decision 7).- Remote mutations are the maintainer's: the user-level preToolUse hook
Block-RemoteMutation.ps1deniesgit pushand mutatingghcommands (pr create,pr close, and others) from the agent session, even after an explicit request. Its override,COPILOT_ATELIER_ALLOW_REMOTE=1, is read from the environment that VS Code starts the hook with; setting it inside an agent command has no effect (verified 2026-10-04). The hook matches the whole command text, so a commit message that quotes such a command is blocked too. Prepare the commands and descriptions; the maintainer runs them. Hand over each command as its own fenced code block at the end of the reply, which the chat shows with a copy button, and end the turn there; the maintainer reports back in the chat. The question dialog joins the lines of its text, has no copy button, and covers the reply before it (maintainer, 2026-10-06). A long question also hides its choices, so that it can't be answered: keep it to a few short sentences (2026-10-07). A pull request description names an issue without a closing keyword (fixes, closes, resolves) unless the merge should close it: "fixes #34" in #112 closed #34. Simulatedghcommands in offline tests must print what the real ones print, such as the URL of a new comment.
Validation
- CI (
.github/workflows/ci.yml): jobbuildonwindows-2025installs platyPS 0.14.2, MarkdownLinkCheck 0.2.0, and Pester 5.7.1 for all users, restorespackages.configper project plusMicrosoft.NETFramework.ReferenceAssemblies.net4521.0.3, buildsNTFSSecurity.csprojin Release with the MSBuild thatvswherefinds, then: 01Update-MarkdownHelpand fail ongit diff -- Docs/Cmdlets; 02Get-MarkdownLink -BrokenOnly; 03 regenerate the help file and fail ongit status --porcelain -- NTFSSecurity/en-US; 04Invoke-Tests.ps1in Windows PowerShell 5.1 and in PowerShell 7. Jobwikionubuntu-latest(read-only) clones the wiki (gh auth setup-gitwith the built-in token), runsExport-WikiContent.ps1, and lists the changed pages in the job summary; jobpublish-wiki(contents: write) repeats that and publishes, formasteronly. After the tests,buildrunsNew-ModulePackage.ps1and uploads the artifactpackages(nupkg andNTFSSecurity.zip). Jobreleaseruns only for tags matching[0-9]+.[0-9]+.[0-9]+or[0-9]+.[0-9]+.[0-9]+-*, in the environmentpowershell-gallery(secretPSGALLERY_API_KEY); see Decision 12. Actions are pinned by commit SHA:actions/checkoutv7.0.1,actions/upload-artifactv7.0.1,actions/download-artifactv8.0.1; Dependabot proposes updates weekly, one week after a release. - Packaging needs PSResourceGet (
Compress-PSResource, PowerShell 7.4 or later); its tests skip in Windows PowerShell. Dry run locally: runNew-ModulePackage.ps1againstNTFSSecurity\bin\Releaseinto$env:TEMP, then extract the nupkg into a folder and import it there. - Read CI runs with
gh run list --repo raandree/NTFSSecurity --workflow ci.yml,gh pr checks <number>, andgh run view <id> --log-failed(read-only). - Workflow lint: actionlint (download the release zip into
$env:TEMPand check its SHA-256 against the checksum file); PowerShell steps check$LASTEXITCODEafter every native command, because GitHub checks only the last one. - Run platyPS in Windows PowerShell 5.1 to avoid PowerShell 7.4+
-ProgressActionnoise. - Placeholder check: no
{{left inDocs/Cmdlets/*.md. - Help file:
New-ExternalHelp -Path .\Docs\Cmdlets -OutputPath .\NTFSSecurity\en-US -Forcemust leavegit statusunchanged. - Pester: run detached (
Start-DetachedPowerShell.ps1) in Windows PowerShell 5.1: the launcher startspwsh, and its payload runspowershell.exe -NoProfile -EncodedCommandwith Pester imported by full path. A run withoutbin\Release\en-USmust fail. - Tests that run only without a privilege skip in CI and in an elevated
session. Run them as a basic user with
runas /trustlevel:0x20000, and give Windows PowerShell its ownPSModulePath; that token holds one privilege, so theEnable-Privileges -PassThrucount test fails there.runasreturns at once, so the script it starts writes its own log. Pester reports a skipped-ForEachtest under its template name, such as<_> should ..., and a test that ran under the expanded name: compare runs by template. - C# coverage (Decision 21): AltCover 9.0.145 (
tools\net472\AltCover.exeof the nuget.org package) instruments a copy of the local Release build, which has the PDB files that the published package lacks:--save,--reportFormat=OpenCover, AlphaFS andSystem.Management.Automationexcluded with--assemblyFilter. Put the instrumented module inNTFSSecurity\bin\Releaseof agit worktree, run.github\scripts\Invoke-Tests.ps1elevated and as a basic user in both editions, thenAltCover.exe runner --collect --recorderDirectory=<the instrumented folder>. Baseline of the rc5 tree on 2026-10-08: 55.9% of the lines (1,943 of 3,476), 37.4% of the branches (700 of 1,873); 60.1% of the lines without 244 lines in classes that no cmdlet calls. - Live tests (Decision 20): in an elevated Windows PowerShell 5.1 session
on the lab host,
Tests\Lab\Invoke-NTFSSecurityLabTest.ps1with-Versionfor Gallery packages or-ModulePathfor a build; it writes the results to$env:TEMP\NTFSSecurityLab\Results. A run of two versions in both editions takes about 30 minutes;-RemoveFixtureremoves its accounts, share, and folders from the lab. - Markdown lint:
npx markdownlint-cli2withMD013limited to prose (tables, code, and headings excluded) on the conceptual pages; forCHANGELOG.mdalsoMD024withsiblings_only: true, because every version repeats the category headings. - Gallery packages: download
https://www.powershellgallery.com/api/v2/package/NTFSSecurity/<version>into$env:TEMPand extract it; dates come from the OData endpointapi/v2/FindPackagesById()?id='NTFSSecurity'. Import each version in its own process: every version'sNTFSSecurity.dllhas assembly version 4.2.1.0, so a second version in the same process reuses the first DLL. - YAML:
ConvertFrom-Yaml(powershell-yaml) on.github/workflows/ci.yml. - Links: the CI step 02 (MarkdownLinkCheck 0.2.0) checks only relative
links in
Docs; it strips anchors and skips absolute URLs.Wiki.Tests.ps1checks the wiki links with their anchors; check the links inREADME.mdandCHANGELOG.mdwith a script.