Tag Archives: Active Directory

Efficiently Retrieve Active Directory Group Members with PowerShell and Caching

Retrieving Active Directory group members can be a time-consuming process, especially for large groups. This can cause slowdowns in your PowerShell scripts and lead to poor performance. Fortunately, there’s a solution: PowerShell caching. In this post, I’ll show you how to optimize the process of retrieving AD group members with caching, resulting in faster script execution and improved performance.

The “Get-CachedADGroupMembers” Function

The “Get-CachedADGroupMembers” function takes the name of the AD group to retrieve members from.

$cache = @{}
function Get-CachedADGroupMembers {
    param($group_name)
    if ($cache -eq $null) {
        $cache = @{}
    }
    if ($cache.ContainsKey($group_name)) {
        return $cache[$group_name]
    } else {
        $data = ((Get-ADGroupMember -Identity $group_name -Recursive | %{
            if ($_.objectClass -eq "computer") {
                $_.SamAccountName
            } else {
                $_.SamAccountName | Get-ADUser -Properties samAccountName, employeeType 
            }
        } | select samAccountName,employeeType,enabled) | Where {$_.samAccountName -notin $excluded_users})
        $cache[$group_name] = $data
        return $data
    }
}

The function first checks if the $cache variable has been initialized. If it hasn’t, it initializes it as an empty hashtable. It then checks if the group_name exists in the hashtable. If it does, the function returns the cached data. If it doesn’t, the function retrieves the group members using the “Get-ADGroupMember” cmdlet and stores the results in the $data variable. The function then adds the $data variable to the $cache hashtable and returns the $data variable.

The function also uses a pipeline to filter out any members that are computers and to retrieve additional user properties using the “Get-ADUser” cmdlet. Finally, it uses the “Where” cmdlet to exclude any users in a specified list of excluded users.

Conclusion

By using PowerShell caching, you can significantly speed up the process of retrieving Active Directory group members, resulting in faster script execution and improved performance. The “Get-CachedADGroupMembers” function is a simple and effective way to implement caching in your PowerShell scripts. Give it a try and see how much time you can save!

Advertisement

PowerShell Script to Audit User Permissions and Identify Users with High Permission

Managing permissions and ensuring proper access control is critical to maintain the security of your organization’s resources. In this blog post, we introduce a PowerShell script that can audit user permissions on file shares and directories, calculate a permission score for each user, and help you identify users with the most permissive rights.

Script

The PowerShell script consists of the following main parts:

  1. A hashtable that defines important rights and their corresponding scores.
  2. A list of excluded users and shares that should not be considered in the audit process.
  3. A function called Get-ImportantDirectoryACLs that retrieves the Access Control List (ACL) for a given directory, filters out excluded users, and calculates a permission score for each user.
  4. A main script block that connects to a target server, retrieves the file shares and directories, and invokes the Get-ImportantDirectoryACLs function.

The script calculates the permission scores for each user based on the importance of their rights. In this example, we assign a score of 100 to the ‘TakeOwnership’ right, 90 to the ‘FullControl’ right, and lower scores to other important rights. The resulting CSV file will display the users with the highest scores at the top, making it easy to identify users with the most permissive rights.

$ImportantRights = @{
    'FullControl' = 100
    'Modify' = 80
    'ReadAndExecute' = 60
    'Write' = 40
    'CreateFiles' = 20
    'CreateDirectories' = 20
    'Delete' = 10
    'TakeOwnership' = 100
}
$ExcludedUsers = @('NT AUTHORITY\SYSTEM', 'BUILTIN\Administrators', 'NT SERVICE\TrustedInstaller', 'BUILTIN\Users', 'APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES')
$ExcludedShares = @("IPC$", "ADMIN$")

function Get-ImportantDirectoryACLs {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [string]$DirectoryPath,
        [Parameter(Mandatory)]
        [string[]]$ExcludedUsers
    )

    process {
        $ACL = Get-Acl $DirectoryPath
        Foreach ($AccessRule in $ACL.Access) {
            If (!$AccessRule.IsInherited) {
                $User = $($AccessRule.IdentityReference)
                if ($User -notin $ExcludedUsers) {
                    $TotalScore = 0
                    $Rights = @($AccessRule.FileSystemRights -split ",") | Where-Object { $ImportantRights.ContainsKey($_) }
                    Foreach ($Right in $Rights) {
                        $TotalScore += $ImportantRights[$Right]
                    }
                    if ($TotalScore -gt 0) {
                        [pscustomobject]@{
                            DirectoryPath = $DirectoryPath
                            IdentityReference = $AccessRule.IdentityReference
                            AccessControlType = $AccessRule.AccessControlType
                            FileSystemRights = $AccessRule.FileSystemRights
                            Score = $TotalScore
                        }
                    }
                }
            }
        }
    }
}

$Server = "ServerName"

$Cim = New-CimSession -ComputerName $Server
if ($Cim) {
    $Shares = Get-SmbShare -CimSession $Cim | Where-Object { $ExcludedShares -notcontains $_.Name } | ForEach-Object {
        "\\$($_.PSComputerName)\$($_.Name)"
    }
    $Directories = $Shares | ForEach-Object { Get-ChildItem $_ -Directory } | Select-Object -ExpandProperty FullName

    $ShareRights = $Shares | Get-ImportantDirectoryACLs -ExcludedUsers $ExcludedUsers
    $DirectoryRights = $Directories | Get-ImportantDirectoryACLs -ExcludedUsers $ExcludedUsers

    $Results = @($ShareRights) + @($DirectoryRights)

    # Sort results by Score in descending order
    $SortedResults = $Results | Sort-Object -Property Score -Descending

    # Export the sorted results to a CSV file
    $SortedResults | Export-Csv -Path "$Server.csv" -NoTypeInformation
}

How to Use It

  1. Copy the script to your PowerShell environment and save it as a .ps1 file.
  2. Replace “ServerName” in the $Server variable with the name of the server you want to audit.
  3. Run the script. It will generate a CSV file named ServerName.csv that contains the audit results.
  4. Review the CSV file to identify users with the highest permission scores.

Conclusion

Using PowerShell to audit user permissions and identify users with the most permissive rights is an efficient and effective way to manage access control in your organization. By assigning permission scores to important rights, you can quickly identify the users that may require further investigation. Remember to adapt the script to your environment and adjust the scores as needed to suit your organization’s security requirements.