Tuesday, April 28, 2015

Script Sharing - Advance functions to make managing file security easier

Hey everyone! 

I recently started trying to get a little bit more 'official' and started learning how to write Advance Functions and I wanted to share 4 functions that I believe are quite useful, and hope that someone might find helpful. 

Function #1:
function Enable-AclInheritanceOnFolder
{
    <#
      .SYNOPSIS
      This function will turn on inheritance on the folder
      .DESCRIPTION
      This function will turn inheritance on the folder provided, currenth path if no path is provided.
      .EXAMPLE
      Enable-AclInheritanceOnFolder -path 'C:\TestPath'
      .PARAMETER Path
      The path of the folder where the ACL should be added.
    #>
    [CmdletBinding()]
[OutputType([int])]
Param
(
        #Path
        [Parameter(Mandatory=$false,
            ValueFromPipeline=$True,
            ValueFromPipelineByPropertyName=$True,
            HelpMessage='What is the path where inheritance should be enabled?')]
        [Alias('Location')]
        [ValidateLength(3,250)]
        [string]$path
)
    begin
    {
        if($path.Length -eq 0)
        {
            Write-Verbose "No Path provided, assigning current location to path."
            $currentPath = (Get-Item .\).FullName
        }
        else
        {
            $currentPath = $path
        }
    }
    Process
    {
        try
        {
            Write-Verbose "Getting folder IO object for $currentPath"
            $folderInfo = New-Object IO.DirectoryInfo($currentPath)
            Write-Verbose "Getting the Folder Access Control List."
            $folderACLs = $folderInfo.GetAccessControl()    
            Write-Verbose "Enabling Inheritance in ACL Object."
            $folderACLs.SetAccessRuleProtection($false,$false)
            Write-Verbose "Attempting to save the changes."
            $folderInfo.SetAccessControl($folderACLs)
        }
        catch
        {
            Write-Verbose "There was an error adding the permissions."
            Write-Error $Error[0]
        }

        
    }
}

Function #2 
function Disable-AclInheritanceOnFolder
{
    <#
      .SYNOPSIS
      This function will turn off inheritance on the folder
      .DESCRIPTION
      This function will turn off inheritance on the folder provided, currenth path if no path is provided. 
      It will also require that you specify if the current rules should be kept and converted or if they 
      should be removed.
      .EXAMPLE
      Disable-AclInheritanceOnFolder -path 'C:\TestPath' -ConvertRules $true|$false
      .EXAMPLE
      Disable-AclInheritanceOnFolder -ConvertRules $true|$false
      .PARAMETER Path
      The path of the folder where the ACL should be added.
      .PARAMETER ConvertRules
      Bool to know if the current rules should be converted and kept or removed from the folder.
      If you remove the rules you might be loose access to the folder, be sure to take ownership of the
      folder first.
    #>
    [CmdletBinding()]
[OutputType([int])]
Param
(
        #Path
        [Parameter(Mandatory=$false,
            ValueFromPipeline=$True,
            ValueFromPipelineByPropertyName=$True,
            HelpMessage='What is the path where inheritance should be disabled?')]
        [Alias('Location')]
        [ValidateLength(3,250)]
        [string]$path,
        #PreserveInheritance
        [Parameter(Mandatory=$True,
            ValueFromPipeline=$True,
            ValueFromPipelineByPropertyName=$True,
            HelpMessage='Should the current rules be removed or converted?')]
        [Alias('PreserveInheritance')]
        [bool]$RemoveCurrentRules
)
    begin
    {
        if($path.Length -eq 0)
        {
            Write-Verbose "No Path provided, assigning current location to path."
            $currentPath = (Get-Item .\).FullName
        }
        else
        {
            $currentPath = $path
        }
    }
    Process
    {
        try
        {
            Write-Verbose "Getting folder IO object for $currentPath"
            $folderInfo = New-Object IO.DirectoryInfo($currentPath)
            Write-Verbose "Getting the Folder Access Control List."
            $folderACLs = $folderInfo.GetAccessControl()    
            Write-Verbose "Enabling Inheritance in ACL Object."
            $folderACLs.SetAccessRuleProtection($true,$true)
            Write-Verbose "Attempting to save the changes."
            $folderInfo.SetAccessControl($folderACLs)
        }
        catch
        {
            Write-Verbose "There was an error adding the permissions."
            Write-Error $Error[0]
        }

        
    }
}

Function #3
function Add-AclToFolder
{
    <#
      .SYNOPSIS
      This function will add an Group to a folder's ACL.
      .DESCRIPTION
      This function will add the given SecurityGroup or user name to the specified folder.
      .EXAMPLE
      Add-ACL -Path 'C:\TestPath' -securityGroup 'DL-SECURITYGROUP-NAME'
      .PARAMETER Path
      The path of the folder where the ACL should be added.
      .PARAMETER securityGroup
      The security group name
      .PARAMETER AccessLevel
      The access level that you wish to give to the group. Choose between ReadAndExecute, Modify, FullControl
    #>
    [CmdletBinding()]
[OutputType([int])]
Param
(
        #Path
        [Parameter(Mandatory=$false,
            ValueFromPipeline=$True,
            ValueFromPipelineByPropertyName=$True,
            HelpMessage='What is the path where this group should be added?')]
        [Alias('Location')]
        [ValidateLength(3,250)]
        [string]$path,
#securityGroup
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage='What is the name of the group?')]
[Alias('group')]
[ValidateLength(3,50)]
[string]$securityGroup,  
        #AccessLevel
        [Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage='Access Level: ReadAndExecute, Modify, FullControl')]
[Alias('acl')]
[ValidateLength(3,15)]
[string]$accessLevel
)
    begin
    {
        Write-Verbose "Starting Add-AclToFolder Function."   
        if($path.Length -eq 0)
        {
            Write-Verbose "No path was provided. We are getting the current path."
            $currentPath = (Get-Item .\).FullName
        }
        else
        {
            $currentPath = $path
        }
    }
    Process
    {

        #region Add-ACL
        Write-Verbose "Process has started."
        try
        {
            Write-Verbose "Getting folder IO object for $currentPath"
            $folderInfo = New-Object IO.DirectoryInfo($currentPath)
            Write-Verbose "Getting the Folder Access Control List."
            $folderACLs = $folderInfo.GetAccessControl()    
            Write-Verbose "Creating new Security.AccessControl.FileSystemAccessRule."
            Write-Verbose "Security Group: $securityGroup"
            Write-Verbose "Access Level: $accessLevel"
            $newACL = New-Object System.Security.AccessControl.FileSystemAccessRule("$($securityGroup)",$accessLevel,"ContainerInherit, ObjectInherit", "None", "Allow")
            Write-Verbose "Adding the new Rule to the ACL object."
            $folderACLs.AddAccessRule($newACL)
            Write-Verbose "Attempting to save the changes."
            $folderInfo.SetAccessControl($folderACLs)
        }
        catch
        {
            Write-Verbose "There was an error adding the permissions."
            Write-Error $Error[0]
        }
    }
}

Function #4 
function Remove-AclFromFolder
{
    <#
      .SYNOPSIS
      This function will remove an Group or User from a folder's ACL.
      .DESCRIPTION
      This function will remove an Group or User from a folder's ACL. If no path is provided the script will use the current path.
      .EXAMPLE
      Remove-AclFromFolder -Path 'C:\TestPath' -securityGroup 'DL-SECURITYGROUP-NAME'
      .EXAMPLE
      Remove-AclFromFolder -securityGroup 'DL-SECURITYGROUP-NAME'
      .PARAMETER Path
      The path of the folder where the ACL should be removed.
    #>
    [CmdletBinding()]
[OutputType([int])]
Param
(
        #Path
        [Parameter(Mandatory=$false,
            ValueFromPipeline=$True,
            ValueFromPipelineByPropertyName=$True,
            HelpMessage='What is the path where th group should be removed from?')]
        [Alias('Location')]
        [ValidateLength(3,250)]
        [string]$path,
#securityGroup
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage='What is the name of the group?')]
[Alias('group')]
[ValidateLength(3,50)]
[string]$securityGroup
)
    begin
    {
        Write-Verbose "Starting Add-AclToFolder Function."   
        if($path.Length -eq 0)
        {
            Write-Verbose "No path was provided. We are getting the current path."
            $currentPath = (Get-Item .\).FullName
        }
        else
        {
            $currentPath = $path
        }
    }
    Process
    {

        #region Add-ACL
        Write-Verbose "Process has started."
        try
        {
            Write-Verbose "Getting folder IO object for $currentPath"
            $folderInfo = New-Object IO.DirectoryInfo($currentPath)
            Write-Verbose "Getting the Folder Access Control List."
            $folderACLs = $folderInfo.GetAccessControl()    
            Write-Verbose "Finding the rule to remove."
            $aclToRemove = $folderACLs.Access | ?{$_.IdentityReference -match $securityGroup}
            Write-Verbose "Removing $($aclToRemove.identityreference) from the ACL Object"
            $folderACLs.RemoveAccessRule($aclToRemove)
            Write-Verbose "Attempting to save the changes."
            $folderInfo.SetAccessControl($folderACLs)
        }
        catch
        {
            Write-Verbose "There was an error modifying the permissions."
            Write-Error $Error[0]
        }
    }
}

I believe that I been able to properly document the functions so there shouldn't be any confusion, but do let me know if you find any issues, comments or complaints. 

Kind regards, 
Me.

No comments:

Post a Comment