Sunday, September 7, 2008

Creating secedit templates with PowerShell

This post provides a powershell script to create a secedit security template based on an existing NTFS filesystem permissions structure. This script uses the PowerShell get-childitem cmdlet combined with the get-acl cmdlet to provide the SDDL string, which is then processed to print out only explicit ACLs, after stripping out inherited ACE's in a very cheap and nasty regular expression matching way.

Using this script provides a basic DACL per-directory secedit template type view of a filesystem, excellent to move away from directly applying ACLs to the filesystem or just to provide point-in-time views of your NTFS security.

How good is powershell?


# -- CreateSecurityTemplate.ps1 -- #
#
# 06/09/2008, Wayne Martin, Initial version
#
#
# Description:
#   Given a starting directory, recursively list explicit ACLs in SDDL format for reproduction in a secedit security template
#
# Assumptions, this script works on the assumption that:
#   Only discretionary access control entries are used
#
# Limitations:
#   260 max_path length limitation is in place with get-childitem
#
# Arguments:
#  -p : Path     - The root folder to begin the search
#
# Example:
#   . .\CreateSecurityTemplate.ps1 -p c:\windows\temp

param ($path = "")

if ($path -eq "") {
    write-output "Please specify a root directory to begin the search, eg . .\CreateSecurityTemplate.ps1 -p c:\windows\temp"
    exit 2
} else {
    write-output "Processing $path"
}

$ErrorActionPreference = "SilentlyContinue"

$EXPLICIT_ACL_OVERWRITE = 2
$EXPLICIT_ACL_MERGE = 2

$PATTERN_SPLIT_ACL = "^\(|\)\(|\)$"
$PATTERN_NOT_INHERITED_ACE = ".;.*ID.*;"
$PATTERN_EMPTY_LINE = "^$"

$DALC_AUTOINHERIT_REQ = "D:AR"
$path

$objects = $null
$objects = get-childitem $path -Recurse | where{$_.PSIsContainer}    # Find directories

foreach ($object in $objects)          # For each directory
{
    if ($object -is [System.IO.DirectoryInfo])
    {
        $FullName = $object.FullName
        $acl = get-acl -path $FullName        # Get the ACL for this directory

        $sddl = $acl.sddl         # Get the ACL in SDDL string format
        $sddl = $sddl.remove(0, $sddl.indexof("("))
 
 # Split to each ACE, return only those that are not inherited and not an empty line
        $aces = [regex]::split($sddl,$PATTERN_SPLIT_ACL) | where{ $_ -notmatch $PATTERN_NOT_INHERITED_ACE } | where{ $_ -notmatch $PATTERN_EMPTY_LINE} 

        if ($aces.length -gt 1) {        # Are there any explicit aces on this directory?
            $newSDDL = "(" + [string]::join(")(", $aces) + ")"     # Yes, construct the new SDDL string
            write-output ("""" + $FullName + """,$EXPLICIT_ACL_OVERWRITE,""$DALC_AUTOINHERIT_REQ" + $newsddl + """")
        }
    }
}

exit 0

Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.

2 comments:

Reynold Hugh said...

Very Helpful Article!
Template Magician

Unknown said...

This is very helpful!

Thanks Wayne

Krushal

Post a Comment