Public/Clear-OrphanSIDs.ps1

Function Clear-OrphanSIDs
{   
<#
        .SYNOPSIS
        Function Clear-OrphanSIDs is an advanced function which can reomve the orphaned SID from file/folders ACL.
        .DESCRIPTION
        Function Clear-OrphanSIDs is an advanced function which can reomve the orphaned SID from file/folders ACL.
        .PARAMETER Path
        Indicates the path of the specified file or folder.
        .PARAMETER Recurse
        Indicates check the child items of the specified folder.
        .EXAMPLE
        Clear-OrphanSIDs -path C:\acls.txt
         
        Remove orphaned SIDs from C:\acls.txt
        .EXAMPLE
        Clear-OrphanSIDs -Path C:\test -Recurse
         
        Remove orphaned SIDs from all the files/folders ACL of C:\test
        .LINK
        Windows PowerShell Advanced Function
        http://technet.microsoft.com/en-us/library/dd315326.aspx
        .LINK
        Get-Acl
        http://technet.microsoft.com/en-us/library/hh849802.aspx
        .LINK
        Set-Acl
        http://technet.microsoft.com/en-us/library/hh849810.aspx
    #>


    [CmdletBinding()]
    Param
    (
        #Define parameters
        [Parameter(Mandatory=$true,Position=1)]
        [String]$Path,        
        [Parameter(Mandatory=$false,Position=2)]
        [Switch]$Recurse
    )
    #Try to get the object ,and define a flag to record the count of orphaned SIDs
    Try
    {
        if(Test-Path -Path $Path)
        { 
            $count = 0
            #If the object is a folder and the "-recurse" is chosen ,then get all of the folder childitem,meanwhile store the path into an array folders
            if ($Recurse) 
            {        
                 $folders = Get-ChildItem -Path $path -Recurse 
                 #For-Each loop to get the ACL in the folders and check the orphaned SIDs
                 ForEach ($folder in $folders)
                {
                       $PSPath = $folder.fullname 
                       DeleteSID($PSPath)    
                }
            }
            else
            #The object is a file or the "-recurse" is not chosen,check the orphaned SIDs .
            {
                $PSPath =$path
                DeleteSID($PSPath)    
            }    
        }
        else
        {
            Write-Error "The path is incorrect"
        }
    }    
    catch
    {
         Write-Error $Error
    }
}  #END function

Function DeleteSID([string]$path)
{  
      try
      {
           #This function is used to delete the orphaned SID
           $acl = Get-Acl -Path $Path
           foreach($acc in $acl.access )
           {
               $value = $acc.IdentityReference.Value
               if($value -match "S-1-5-*")
               {
                   $ACL.RemoveAccessRule($acc) | Out-Null
                   Set-Acl -Path $Path -AclObject $acl -ErrorAction Stop
                   Write-Host "Remove SID: $value form $Path "
               }
           }
      }
       catch
       {
           Write-Error $Error
       }
}#END function