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.
152 lines
4.9 KiB
152 lines
4.9 KiB
using Alphaleonis.Win32.Filesystem;
|
|
using Security2;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Management.Automation;
|
|
|
|
namespace NTFSSecurity
|
|
{
|
|
[Cmdlet(VerbsCommon.Get, "NTFSAudit")]
|
|
[OutputType(typeof(FileSystemAuditRule2))]
|
|
public class GetAudit : BaseCmdletWithPrivControl
|
|
{
|
|
private bool excludeInherited;
|
|
private bool excludeExplicit;
|
|
private IdentityReference2 account;
|
|
|
|
protected bool getInheritedFrom = false;
|
|
|
|
[Parameter(Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "Path")]
|
|
[ValidateNotNullOrEmpty]
|
|
[Alias("FullName")]
|
|
[FileSystemPathTransformation]
|
|
public string[] Path
|
|
{
|
|
get { return paths.ToArray(); }
|
|
set
|
|
{
|
|
paths.Clear();
|
|
paths.AddRange(value);
|
|
}
|
|
}
|
|
|
|
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "SD")]
|
|
[ValidateNotNullOrEmpty]
|
|
public FileSystemSecurity2[] SecurityDescriptor
|
|
{
|
|
get { return securityDescriptors.ToArray(); }
|
|
set
|
|
{
|
|
securityDescriptors.Clear();
|
|
securityDescriptors.AddRange(value);
|
|
}
|
|
}
|
|
|
|
[Parameter(ValueFromRemainingArguments = true)]
|
|
[Alias("IdentityReference", "ID")]
|
|
[ValidateNotNullOrEmpty]
|
|
public IdentityReference2 Account
|
|
{
|
|
get { return account; }
|
|
set { account = value; }
|
|
}
|
|
|
|
[Parameter]
|
|
public SwitchParameter ExcludeExplicit
|
|
{
|
|
get { return excludeExplicit; }
|
|
set { excludeExplicit = value; }
|
|
}
|
|
|
|
[Parameter]
|
|
public SwitchParameter ExcludeInherited
|
|
{
|
|
get { return excludeInherited; }
|
|
set { excludeInherited = value; }
|
|
}
|
|
|
|
protected override void BeginProcessing()
|
|
{
|
|
base.BeginProcessing();
|
|
|
|
getInheritedFrom = (bool)((System.Collections.Hashtable)MyInvocation.MyCommand.Module.PrivateData)["GetInheritedFrom"];
|
|
|
|
if (paths.Count == 0)
|
|
{
|
|
paths = new List<string>() { GetCurrentLocation() };
|
|
}
|
|
}
|
|
|
|
protected override void ProcessRecord()
|
|
{
|
|
if (ParameterSetName == "Path")
|
|
{
|
|
foreach (var path in paths)
|
|
{
|
|
FileSystemInfo item = null;
|
|
IEnumerable<FileSystemAuditRule2> acl = null;
|
|
|
|
try
|
|
{
|
|
item = GetFileSystemInfo2(path);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
WriteError(new ErrorRecord(ex, "ReadFileError", ErrorCategory.OpenError, path));
|
|
continue;
|
|
}
|
|
|
|
try
|
|
{
|
|
acl = GetAuditRules(item);
|
|
}
|
|
catch (UnauthorizedAccessException ex)
|
|
{
|
|
// Taking ownership grants no access to the SACL, so it wouldn't help, and it would change the owner.
|
|
WriteError(new ErrorRecord(ex, "ReadSecurityError", ErrorCategory.PermissionDenied, path));
|
|
continue;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
WriteError(new ErrorRecord(ex, "ReadSecurityError", ErrorCategory.OpenError, path));
|
|
continue;
|
|
}
|
|
|
|
WriteAuditRules(acl);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var sd in securityDescriptors)
|
|
{
|
|
if (!TestAuditSection(sd))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
WriteAuditRules(FileSystemAuditRule2.GetFileSystemAuditRules(sd, !excludeExplicit, !excludeInherited, getInheritedFrom));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads only the SACL of an item. Without the Security privilege, this fails instead of returning no entries.
|
|
/// </summary>
|
|
protected IEnumerable<FileSystemAuditRule2> GetAuditRules(FileSystemInfo item)
|
|
{
|
|
var sd = new FileSystemSecurity2(item, System.Security.AccessControl.AccessControlSections.Audit);
|
|
return FileSystemAuditRule2.GetFileSystemAuditRules(sd, !excludeExplicit, !excludeInherited, getInheritedFrom);
|
|
}
|
|
|
|
private void WriteAuditRules(IEnumerable<FileSystemAuditRule2> acl)
|
|
{
|
|
if (account != null)
|
|
{
|
|
acl = acl.Where(ace => ace.Account == account);
|
|
}
|
|
|
|
acl.ForEach(ace => WriteObject(ace));
|
|
}
|
|
}
|
|
}
|