对我来说,诀窍是您不能对当前没有 SACL(系统访问控制列表,也称为审核规则)的文件夹或文件执行此操作。我写了一个函数,在父节点上设置规则,然后递归遍历所有子节点来设置规则,确保它被继承,然后删除额外的规则。
<#
.SYNOPSIS
Sets auditing on the file or folder.
.DESCRIPTION
Implements a File System Audit Rule on the file or folder.
.PARAMETER Path (Required)
Specifies the file or folder on which to apply the audit rule.
.PARAMETER Principal (Required)
Specifies the NTAccount name.
.PARAMETER Success (Optional, Required if "Failure" not present)
Specifies to implement an audit rule for successes.
.PARAMETER Failure (Optional, Required if "Success" not present)
Specifies to implement an audit rule for failures.
.PARAMETER Flags (Required)
This is an array of two integers that indicate what to apply the audit rule to and what type of recursion should be used.
Inheritance, Propagation:
This folder only = 0,0
This folder, subfolders and files = 3,0
This folder and subfolders = 1,0
This folder and files = 2,0
Subfolders and files only = 3,2
Subfolders only = 1,2
Files only = 2,3
.EXAMPLE
Set-Auditing
#>
function Set-Auditing {
[CmdletBinding(SupportsShouldProcess=$true)]
Param([Parameter(Mandatory=$true, ValueFromPipeline=$false)] [ValidateNotNullOrEmpty()] [string]$Path,
[Parameter(Mandatory=$true, ValueFromPipeline=$false)] [ValidateNotNullOrEmpty()] [string]$Principal,
[Parameter(Mandatory=$true, ValueFromPipeline=$false)] [ValidateSet("AppendData","ChangePermissions","CreateDirectories","CreateFiles","Delete","DeleteSubdirectoriesAndFiles","ExecuteFile","FullControl","ListDirectory","Modify","Read","ReadAndExecute","ReadAttributes","ReadData","ReadExtendedAttributes","ReadPermissions","Synchronize","TakeOwnership","Traverse","Write","WriteAttributes","WriteData","WriteExtendedAttributes")] [string[]]$Rights,
[Parameter(Mandatory=$true, ValueFromPipeline=$false, ParameterSetName="Both")]
[Parameter(Mandatory=$true, ValueFromPipeline=$false, ParameterSetName="Success")] [switch]$Success,
[Parameter(Mandatory=$true, ValueFromPipeline=$false, ParameterSetName="Both")]
[Parameter(Mandatory=$true, ValueFromPipeline=$false, ParameterSetName="Failure")] [switch]$Failure,
[Parameter(Mandatory=$true, ValueFromPipeline=$false)] [int[]]$Flags)
Begin {
# Determine if audit rule exists
if ($Success.IsPresent) { $AuditFlags=1 } else { $AuditFlags=0 }
if ($Failure.IsPresent) { $AuditFlags+=2 }
# Inheritance Flags
# This folder only = 0
# This folder, subfolders and files = 3
# This folder and subfolders = 1
# This folder and files = 2
# Subfolders and files only = 3
# Subfolders only = 1
# Files only = 2
# Propagation Flags
# This folder only = 0
# This folder, subfolders and files = 0
# This folder and subfolders = 0
# This folder and files = 0
# Subfolders and files only = 2
# Subfolders only = 2
# Files only = 2
# File System Rights
$fsrAppendData =0x000004
$fsrChangePermissions =0x040000
$fsrCreateDirectories =0x000004
$fsrCreateFiles =0x000002
$fsrDelete =0x010000
$fsrDeleteSubdirectoriesAndFiles=0x000040
$fsrExecuteFile =0x000020
$fsrFullControl =0x1F01FF
$fsrListDirectory =0x000001
$fsrModify =0x0301BF
$fsrRead =0x020089
$fsrReadAndExecute =0x0200A9
$fsrReadAttributes =0x000080
$fsrReadData =0x000001
$fsrReadExtendedAttributes =0x000008
$fsrReadPermissions =0x020000
$fsrSynchronize =0x100000
$fsrTakeOwnership =0x080000
$fsrTraverse =0x000020
$fsrWrite =0x000116
$fsrWriteAttributes =0x000100
$fsrWriteData =0x000002
$fsrWriteExtendedAttributes =0x000010
$RightValues=0
for ($i=0; $i -lt $Rights.Count; $i++) {
switch ($Rights[$i]) {
"AppendData" { $RightValues=$RightValues -bor $fsrAppendData }
"ChangePermissions" { $RightValues=$RightValues -bor $fsrChangePermissions }
"CreateDirectories" { $RightValues=$RightValues -bor $fsrCreateDirectories }
"CreateFiles" { $RightValues=$RightValues -bor $fsrCreateFiles }
"Delete" { $RightValues=$RightValues -bor $fsrDelete }
"DeleteSubdirectoriesAndFiles" { $RightValues=$RightValues -bor $fsrDeleteSubdirectoriesAndFiles }
"ExecuteFile" { $RightValues=$RightValues -bor $fsrExecuteFile }
"FullControl" { $RightValues=$RightValues -bor $fsrFullControl }
"ListDirectory" { $RightValues=$RightValues -bor $fsrListDirectory }
"Modify" { $RightValues=$RightValues -bor $fsrModify }
"Read" { $RightValues=$RightValues -bor $fsrRead }
"ReadAndExecute" { $RightValues=$RightValues -bor $fsrReadAndExecute }
"ReadAttributes" { $RightValues=$RightValues -bor $fsrReadAttributes }
"ReadData" { $RightValues=$RightValues -bor $fsrReadData }
"ReadExtendedAttributes" { $RightValues=$RightValues -bor $fsrReadExtendedAttributes }
"ReadPermissions" { $RightValues=$RightValues -bor $fsrReadPermissions }
"Synchronize" { $RightValues=$RightValues -bor $fsrSynchronize }
"TakeOwnership" { $RightValues=$RightValues -bor $fsrTakeOwnership }
"Traverse" { $RightValues=$RightValues -bor $fsrTraverse }
"Write" { $RightValues=$RightValues -bor $fsrWrite }
"WriteAttributes" { $RightValues=$RightValues -bor $fsrWriteAttributes }
"WriteData" { $RightValues=$RightValues -bor $fsrWriteData }
"WriteExtendedAttributes" { $RightValues=$RightValues -bor $fsrWriteExtendedAttributes }
}
}
Write-Verbose "Acquiring object $($FS.FullName)"
$FS=Get-Item -Path $Path
$ACL=Get-Acl -Path $Path -Audit
$NothingToDo=$false
for ($i=0; $i -lt $ACL.Audit.Count; $i++) {
if ($ACL.Audit[$i].IdentityReference.Value -eq $Principal) {
if ($ACL.Audit[$i].AuditFlags.value__ -eq $AuditFlags) {
if ($ACL.Audit[$i].PropagationFlags.value__ -eq $Flags[1]) {
if ($ACL.Audit[$i].InheritanceFlags.value__ -eq $Flags[0]) {
if ($ACL.Audit[$i].FileSystemRights.value__ -eq $RightValues) { $NothingToDo=$true; Write-Verbose "Nothing to do" }
}
}
}
}
}
}
Process {
if (!$NothingToDo) {
# There is one case where we will not propagage the rules. This is when $Flags = 0,0
if (($Flags[0] -eq 0) -and ($Flags[1] -eq 0)) { Write-Verbose "Flags = 0,0; no propagation necessary." }
else {
Write-Verbose "Setting Audit Rule"
if ($Principal.Contains("\")) { $NTAccount=New-Object System.Security.Principal.NTAccount(($Principal.Split("\"))[0],($Principal.Split("\"))[1]) }
else { $NTAccount=New-Object System.Security.Principal.NTAccount($Principal) }
$FSAR=New-Object System.Security.AccessControl.FileSystemAuditRule($NTAccount,$RightValues,$Flags[0],$Flags[1],$AuditFlags)
$FAR=New-Object System.Security.AccessControl.FileSystemAuditRule($NTAccount,$RightValues,$AuditFlags)
$ACL.AddAuditRule($FSAR)
$ACL.SetAuditRuleProtection($false, $true)
Write-Verbose "Applying rule to $($ACL.Path.Replace('Microsoft.PowerShell.Core\FileSystem::',''))"
$FS.SetAccessControl($ACL)
# Now, ensure that all folders and files have inheritance enabled.
$FS=Get-ChildItem -Path $Path -Recurse
$FS=@($FS)
for ($i=0; $i -lt $FS.Count; $i++) {
Write-Verbose "Acquiring object $($FS[$i].FullName)"
$ACL=Get-Acl -Path $FS[$i].FullName -Audit
if (Test-Path $ACL.Path -PathType Leaf) { $ACL.AddAuditRule($FAR) } else { $ACL.AddAuditRule($FSAR) }
$ACL.SetAuditRuleProtection($false, $true)
$FS[$i].SetAccessControl($ACL)
Write-Verbose "Applying rule to $($ACL.Path.Replace('Microsoft.PowerShell.Core\FileSystem::',''))"
if (Test-Path $ACL.Path -PathType Leaf) { $ACL.RemoveAuditRule($FAR) > $null } else { $ACL.RemoveAuditRule($FSAR) > $null }
Write-Verbose "Removing extra rule from $($ACL.Path)"
$FS[$i].SetAccessControl($ACL)
}
}
}
else { Write-Verbose "Nothing to do." }
}
}