Public/Objects/Get-ADComputers.ps1
|
function Get-ADComputers { [CmdletBinding()] param( [string]$ObjectType = "Computers", [string]$ExportPath = $script:Config.ExportPath ) try { Write-Log "Retrieving computer accounts..." -Level Info Show-ProgressHelper -Activity "AD Inventory" -Status "Initializing computer retrieval..." $properties = @( 'Name', 'DistinguishedName', 'OperatingSystem', 'OperatingSystemVersion', 'OperatingSystemServicePack', 'Enabled', 'LastLogonDate', 'Created', 'Modified', 'DNSHostName', 'ServicePrincipalNames', # Added for role detection 'Description', 'Location', 'primaryGroupID' # To differentiate workstations/servers ) $allComputers = Invoke-WithRetry -ScriptBlock { Get-ADComputer -Filter * -Properties $properties -ErrorAction Stop } $computers = Get-ADObjects -ObjectType $ObjectType -Objects $allComputers -ProcessingScript { param($computer) try { # Determine computer type and roles $computerType = switch ($computer.primaryGroupID) { 515 { "Server" } 516 { "Workstation" } default { "Unknown" } } # Parse SPNs to detect roles $roles = @() foreach ($spn in $computer.ServicePrincipalNames) { switch -Regex ($spn) { 'DNS|host' { $roles += "DNS Server" } 'DHCP' { $roles += "DHCP Server" } 'CA' { $roles += "Certificate Authority" } 'MSSQL' { $roles += "SQL Server" } 'IISW3SVC' { $roles += "Web Server" } 'exchangeMDB' { $roles += "Exchange Server" } 'WSMAN' { $roles += "Windows Management" } 'FTP' { $roles += "FTP Server" } 'LDAP' { $roles += "Domain Controller" } 'RPCSS' { $roles += "RPC Server" } 'BITS' { $roles += "BITS Server" } } } $roles = $roles | Select-Object -Unique # Check if it's a file server (attempt to get shares) if ($computerType -eq "Server") { try { $shares = Get-WmiObject -Class Win32_Share -ComputerName $computer.DNSHostName -ErrorAction Stop if ($shares | Where-Object { $_.Type -eq 0 }) { $roles += "File Server" } } catch { Write-Log "Unable to query shares on $($computer.Name): $($_.Exception.Message)" -Level Warning } } # Get additional server features if possible if ($computerType -eq "Server") { try { $serverFeatures = Invoke-Command -ComputerName $computer.DNSHostName -ScriptBlock { Get-WindowsFeature | Where-Object Installed } -ErrorAction Stop foreach ($feature in $serverFeatures) { $roles += "Windows Feature: $($feature.Name)" } } catch { Write-Log "Unable to query Windows features on $($computer.Name): $($_.Exception.Message)" -Level Warning } } [PSCustomObject]@{ Name = $computer.Name DNSHostName = $computer.DNSHostName ComputerType = $computerType OperatingSystem = $computer.OperatingSystem OperatingSystemVersion = $computer.OperatingSystemVersion OperatingSystemServicePack = $computer.OperatingSystemServicePack Roles = $roles Enabled = $computer.Enabled LastLogonDate = $computer.LastLogonDate Created = $computer.Created Modified = $computer.Modified Description = $computer.Description Location = $computer.Location DistinguishedName = $computer.DistinguishedName DomainJoined = $true # If it's in AD, it's domain-joined AccessStatus = "Success" } } catch { Write-Log "Error processing computer $($computer.Name): $($_.Exception.Message)" -Level Warning [PSCustomObject]@{ Name = $computer.Name DNSHostName = $null ComputerType = "Unknown" OperatingSystem = $null OperatingSystemVersion = $null OperatingSystemServicePack = $null Roles = @() Enabled = $null LastLogonDate = $null Created = $null Modified = $null Description = $null Location = $null DistinguishedName = $computer.DistinguishedName DomainJoined = $null AccessStatus = "Access Error: $($_.Exception.Message)" } } } # Generate and display statistics $stats = Get-CollectionStatistics -Data $computers -ObjectType $ObjectType -IncludeAccessStatus $stats.DisplayStatistics() # Export data Export-ADData -ObjectType $ObjectType -Data $computers -ExportPath $ExportPath return $computers } catch { Write-Log "Error retrieving computers: $($_.Exception.Message)" -Level Error Show-ErrorBox "Unable to retrieve computer accounts. Check permissions." } } |