Summary
Add-LinesToFile leaves the edited file with an empty DACL (no access-control entries). After the edit, every principal - including the file's owner and git - is denied all data access, surfacing as a confusing Access to the path ... is denied rather than a sharing error. The file is unusable until its ACL is manually repaired.
Environment
- PowerShell.MCP module: 1.11.0
- PowerShell: 7.6.3
- OS: Windows 11 (10.0.26200)
What happened
In a git repo I appended a few lines to .gitignore:
Add-LinesToFile .gitignore -Content $var1 # var1 = the new ignore lines
The cmdlet reported success (Added 6 line(s) to .gitignore), but every subsequent access failed:
[IO.File]::ReadAllText('.gitignore') -> UnauthorizedAccessException: Access to the path '...\.gitignore' is denied.
git add .gitignore -> error: open(".gitignore"): Permission denied / fatal: updating files failed
Show-TextFiles .gitignore -> Access denied
Diagnosis
- Not a sharing lock. The Windows Restart Manager (
RmGetList) reported 0 processes locking the file.
- Empty DACL.
icacls .gitignore listed no ACEs at all (just the path + "Successfully processed 1 files", with zero permission entries). A sibling file in the same folder was fully accessible.
- Owner was unchanged (the correct user).
IsReadOnly was False; attributes were normal (Archive).
icacls <file> /reset (restoring inherited permissions) immediately fixed it, and the file content was intact - so only the security descriptor was damaged, not the data.
Impact
The file becomes completely inaccessible (reads, writes, and git all fail). In my case it blocked a commit until I diagnosed and repaired the ACL. The misleading "Access denied" (vs. a lock error) makes this hard to diagnose.
Workaround
icacls <file> /reset
icacls <file> /inheritance:e
Likely cause
The write path appears to create/replace the file (or its security descriptor) without preserving the original DACL or re-enabling inheritance - e.g. writing a new file with an explicit empty SD, or a write-to-temp-then-rename that drops the inherited ACL.
Expected
Add-LinesToFile (and the sibling text cmdlets Update-LinesInFile, Update-MatchInFile, Remove-LinesFromFile) should preserve the existing file's ACL and inheritance across edits.
Repro
- Create a text file in a folder with normal inherited permissions.
Add-LinesToFile <file> -Content $var1 (append any lines).
icacls <file> -> DACL is empty.
Get-Content <file> or git add <file> -> Access denied.
Summary
Add-LinesToFileleaves the edited file with an empty DACL (no access-control entries). After the edit, every principal - including the file's owner andgit- is denied all data access, surfacing as a confusingAccess to the path ... is deniedrather than a sharing error. The file is unusable until its ACL is manually repaired.Environment
What happened
In a git repo I appended a few lines to
.gitignore:The cmdlet reported success (
Added 6 line(s) to .gitignore), but every subsequent access failed:[IO.File]::ReadAllText('.gitignore')->UnauthorizedAccessException: Access to the path '...\.gitignore' is denied.git add .gitignore->error: open(".gitignore"): Permission denied/fatal: updating files failedShow-TextFiles .gitignore-> Access deniedDiagnosis
RmGetList) reported 0 processes locking the file.icacls .gitignorelisted no ACEs at all (just the path + "Successfully processed 1 files", with zero permission entries). A sibling file in the same folder was fully accessible.IsReadOnlywasFalse; attributes were normal (Archive).icacls <file> /reset(restoring inherited permissions) immediately fixed it, and the file content was intact - so only the security descriptor was damaged, not the data.Impact
The file becomes completely inaccessible (reads, writes, and git all fail). In my case it blocked a commit until I diagnosed and repaired the ACL. The misleading "Access denied" (vs. a lock error) makes this hard to diagnose.
Workaround
Likely cause
The write path appears to create/replace the file (or its security descriptor) without preserving the original DACL or re-enabling inheritance - e.g. writing a new file with an explicit empty SD, or a write-to-temp-then-rename that drops the inherited ACL.
Expected
Add-LinesToFile(and the sibling text cmdletsUpdate-LinesInFile,Update-MatchInFile,Remove-LinesFromFile) should preserve the existing file's ACL and inheritance across edits.Repro
Add-LinesToFile <file> -Content $var1(append any lines).icacls <file>-> DACL is empty.Get-Content <file>orgit add <file>-> Access denied.