functions/Get-XdrIdentityConfigurationDirectoryServiceAccount.ps1
|
function Get-XdrIdentityConfigurationDirectoryServiceAccount { <# .SYNOPSIS Retrieves directory service accounts for Microsoft Defender for Identity. .DESCRIPTION Gets the directory service accounts (gMSA) configured for Microsoft Defender for Identity sensors. These accounts are used by MDI sensors to query Active Directory. This function includes caching support with a 30-minute TTL to reduce API calls. .PARAMETER PageSize The number of accounts to retrieve per page. Default is 20. .PARAMETER Skip The number of accounts to skip. Used for pagination. Default is 0. .PARAMETER All Retrieves all directory service accounts by automatically paging through all results. When specified, PageSize and Skip parameters are ignored. .PARAMETER Force Bypasses the cache and forces a fresh retrieval from the API. .EXAMPLE Get-XdrIdentityConfigurationDirectoryServiceAccount Retrieves the first 20 directory service accounts using cached data if available. .EXAMPLE Get-XdrIdentityConfigurationDirectoryServiceAccount -PageSize 50 -Skip 20 Retrieves 50 accounts, skipping the first 20 (for pagination). .EXAMPLE Get-XdrIdentityConfigurationDirectoryServiceAccount -All Retrieves all directory service accounts by automatically paging through all results. .EXAMPLE Get-XdrIdentityConfigurationDirectoryServiceAccount -Force Forces a fresh retrieval of directory service accounts, bypassing the cache. .EXAMPLE Get-XdrIdentityConfigurationDirectoryServiceAccount -All | Where-Object { $_.IsGroupManagedServiceAccount -eq $true } Retrieves all directory service accounts and filters for gMSAs. .OUTPUTS Object[] Returns an array of directory service account objects containing: - Id: User Principal Name of the account - AccountName: Account name without domain - DomainDnsName: Fully qualified domain name - AccountPassword: Always null for gMSA accounts - IsGroupManagedServiceAccount: Boolean indicating if account is a gMSA - IsSingleLabelAccountDomainName: Boolean for single-label domain configuration #> [OutputType([object[]])] [CmdletBinding(DefaultParameterSetName = 'Paged')] param ( [Parameter(ParameterSetName = 'Paged')] [ValidateRange(1, 100)] [int]$PageSize = 20, [Parameter(ParameterSetName = 'Paged')] [int]$Skip = 0, [Parameter(ParameterSetName = 'All', Mandatory)] [switch]$All, [Parameter()] [switch]$Force ) begin { Update-XdrConnectionSettings } process { # If All switch is specified, retrieve all accounts through pagination if ($All) { Write-Verbose "Retrieving all directory service accounts with pagination" # Use maximum page size for efficiency $pageSizeForAll = 100 $allResults = [System.Collections.Generic.List[object]]::new() $currentSkip = 0 $totalCount = $null do { Write-Verbose "Retrieving page: Skip=$currentSkip, PageSize=$pageSizeForAll" try { $Uri = "https://security.microsoft.com/apiproxy/aatp/odata/directoryServices?`$count=true&`$top=$pageSizeForAll&`$skip=$currentSkip" $result = Invoke-RestMethod -Uri $Uri -Method Get -ContentType "application/json" -WebSession $script:session -Headers $script:headers } catch { Write-Error "Failed to retrieve directory service accounts: $_" return } # Get total count from first request if ($null -eq $totalCount) { $totalCount = $result.'@odata.count' Write-Verbose "Total directory service accounts to retrieve: $totalCount" if ($totalCount -eq 0) { Write-Verbose "No directory service accounts found" return @() } } $pageData = $result.value if ($null -ne $pageData -and $pageData.Count -gt 0) { $allResults.AddRange([array]$pageData) Write-Verbose "Retrieved $($pageData.Count) directory service accounts (Total so far: $($allResults.Count))" } $currentSkip += $pageSizeForAll # Safety check to prevent infinite loops if ($null -eq $pageData -or $pageData.Count -eq 0) { Write-Verbose "No more data returned, stopping pagination" break } } while ($currentSkip -lt $totalCount) Write-Verbose "Completed retrieving all directory service accounts: $($allResults.Count) total" return $allResults.ToArray() } # Standard single-page retrieval with caching $cacheKeySuffix = "$PageSize-$Skip" $cacheKey = "XdrIdentityConfigurationDirectoryServiceAccount-$cacheKeySuffix" $currentCacheValue = Get-XdrCache -CacheKey $cacheKey -ErrorAction SilentlyContinue if (-not $Force -and $currentCacheValue.NotValidAfter -gt (Get-Date)) { Write-Verbose "Using cached XDR Identity directory service accounts" return $currentCacheValue.Value } elseif ($Force) { Write-Verbose "Force parameter specified, bypassing cache" Clear-XdrCache -CacheKey $cacheKey } else { Write-Verbose "XDR Identity directory service accounts cache is missing or expired" } try { $Uri = "https://security.microsoft.com/apiproxy/aatp/odata/directoryServices?`$count=true&`$top=$PageSize&`$skip=$Skip" Write-Verbose "Retrieving XDR Identity directory service accounts (PageSize: $PageSize, Skip: $Skip)" $result = Invoke-RestMethod -Uri $Uri -Method Get -ContentType "application/json" -WebSession $script:session -Headers $script:headers } catch { Write-Error "Failed to retrieve directory service accounts: $_" return } $accounts = $result.value if ($null -eq $accounts) { $accounts = @() } Write-Verbose "Retrieved $($accounts.Count) directory service account(s)" Set-XdrCache -CacheKey $cacheKey -Value $accounts -TTLMinutes 30 return $accounts } end { } } |