В настоящее время у меня есть 8 доменов. Используя следующий код ...DirectorySearcher получить все контроллеры домена для списка доменов
$listOfDCs = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers
ForEach ($DC in $listOfDCs)
{
Write-Host $DC
}
Я получаю 32 контроллера для одного домена. Любая идея, как я могу извлечь контроллеры для других доменов?
Примечание: Я хочу избежать использования командлетов квеста как можно больше.
Причиной этого является значение свойства lastlogon для каждого постоянного тока в домене. Я просто пытаюсь схватить последнюю. Вот рабочий код у меня есть для этого, но это не тянет последний один ...
$SamAccountName = "JohnDoe"
$domainSearchProperties = @('SamAccountName','LastLogon', 'DistinguishedName')
$domainDisplayOutputProperties = @('SamAccountName','LastLogon')
$domainConnector = 'www.myplayground.com'
$domainName = 'MyPlayground'
$outputFile = 'C:\Scripts\Tests\testresults.csv'
Function SearchSingleDomainAndExportContents
{
Param ([String]$SamAccountName, [String]$LocalOutputFileWithPath, [String[]]$domainSearchProperties, [String[]]$domainDisplayOutputProperties, [String]$domainConnector, [String]$domainName)
Write-Host "Starting sub-process to search with SamAccountName $SamAccountName in $domainName"
$searchDomainResultsTable = powershell -command {
Param ([String]$SamAccountName, [String]$LocalOutputFileWithPath, [String[]]$domainSearchProperties, [String[]]$domainDisplayOutputProperties, [String]$domainConnector, [String]$domainName)
$domain = "LDAP://$domainConnector"
$adDomain = New-Object System.DirectoryServices.DirectoryEntry($domain)
$adSearcher = New-Object System.DirectoryServices.DirectorySearcher($adDomain)
$adSearcher.Filter = "(&(objectCategory=User)(samAccountType:1.2.840.113556.1.4.803:=805306368)(sAMAccountName=$SamAccountName))"
$adSearcher.PageSize=1000
$adSearcher.PropertiesToLoad.AddRange($domainSearchProperties) | out-Null
$userRecords = $adSearcher.FindAll() | Where-Object {($_.DistinguishedName -notlike "*Retired*")}
$adSearcher.Dispose() | Out-Null
[System.GC]::Collect() | Out-Null
# The AD results are converted to an array of hashtables.
$userPropertiesTable = @()
foreach($record in $userRecords) {
$hashUserProperty = @{}
foreach($userProperty in $domainSearchProperties){
if (($userProperty -eq 'objectGUID') -or ($userProperty -eq 'objectSid') -or ($userProperty -eq 'msExchMasterAccountSid')) {
if ($record.Properties[$userProperty]) {
$hashUserProperty.$userProperty = $record.Properties[$userProperty][0]
} else {
$hashUserProperty.$userProperty = $null
}
} Else {
if ($record.Properties[$userProperty]) {
$hashUserProperty.$userProperty = ($record.Properties[$userProperty] -join '; ').trim('; ')
} else {
$hashUserProperty.$userProperty = $null
}
} #end Else
} #end ForEach
$userPropertiesTable += New-Object PSObject -Property $hashUserProperty
} #end ForEach
[System.GC]::Collect() | Out-Null
# Fixes the property values to be a readable format before exporting to csv file
$listOfBadDateValues = '9223372036854775807', '9223372036854770000', '0'
$maxDateValue = '12/31/1600 5:00 PM'
$valuesToFix = @('lastLogonTimestamp', 'AccountExpires', 'LastLogon', 'pwdLastSet', 'objectGUID', 'objectSid', 'msExchMasterAccountSid')
$valuesToFixCounter = 0
$valuesToFixFound = @($false, $false, $false, $false, $false, $false, $false)
ForEach ($valueToFix in $valuesToFix)
{
if ($domainDisplayOutputProperties -contains $valueToFix)
{
$valuesToFixFound[$valuesToFixCounter] = $true
}
$valuesToFixCounter++
}
$tableFixedValues = $userPropertiesTable | % {
if ($valuesToFixFound[0]) {
if ($_.lastLogonTimestamp) {
$_.lastLogonTimestamp = ([datetime]::FromFileTime($_.lastLogonTimestamp)).ToString('g')
}
}; if ($valuesToFixFound[1]) {
if (($_.AccountExpires) -and ($listOfBadDateValues -contains $_.AccountExpires)) {
$_.AccountExpires = ""
} else {
if (([datetime]::FromFileTime($_.AccountExpires)).ToString('g') -eq $maxDateValue) {
$_.AccountExpires = ""
} Else {
$_.AccountExpires = ([datetime]::FromFileTime($_.AccountExpires)).ToString('g')
}
}
}; if ($valuesToFixFound[2]) {
if (($_.LastLogon) -and ($listOfBadDateValues -contains $_.LastLogon)) {
$_.LastLogon = ""
} else {
if (([datetime]::FromFileTime($_.LastLogon)).ToString('g') -eq $maxDateValue) {
$_.LastLogon = ""
} Else {
$_.LastLogon = ([datetime]::FromFileTime($_.LastLogon)).ToString('g')
}
}
}; if ($valuesToFixFound[3]) {
if (($_.pwdLastSet) -and ($listOfBadDateValues -contains $_.pwdLastSet)) {
$_.pwdLastSet = ""
} else {
if (([datetime]::FromFileTime($_.pwdLastSet)).ToString('g') -eq $maxDateValue) {
$_.pwdLastSet = ""
} Else {
$_.pwdLastSet = ([datetime]::FromFileTime($_.pwdLastSet)).ToString('g')
}
}
}; if ($valuesToFixFound[4]) {
if ($_.objectGUID) {
$_.objectGUID = ([guid]$_.objectGUID).Guid
} Else {
$_.objectGUID = ""
}
}; if ($valuesToFixFound[5]) {
if ($_.objectSid) {
$_.objectSid = (New-Object Security.Principal.SecurityIdentifier($_.objectSid, 0)).Value
} Else {
$_.objectSid = ""
}
}; if ($valuesToFixFound[6]) {
if ($_.msExchMasterAccountSid) {
$_.msExchMasterAccountSid = (New-Object Security.Principal.SecurityIdentifier($_.msExchMasterAccountSid, 0)).Value
} Else {
$_.msExchMasterAccountSid = ""
}
};$_}
[System.GC]::Collect() | Out-Null
$sortedUserPropertiesTable = $tableFixedValues | Select-Object $domainDisplayOutputProperties
$finalDomainUserPropertiesTable = $sortedUserPropertiesTable | Select-Object -Property @{Name="Domain Name";Expression={$domainName}}, *
[System.GC]::Collect() | Out-Null
return $finalDomainUserPropertiesTable
} -args $SamAccountName, $LocalOutputFileWithPath, $domainSearchProperties, $domainDisplayOutputProperties, $domainConnector, $domainName
[System.GC]::Collect() | Out-Null
Write-Host "Search Complete."
Write-Host ""
$searchDomainResultsTable | Export-Csv $outputFile -NoTypeInformation -Force
}
Это будет извлекать данные только из 1 постоянного тока. Проблема с этим заключается в том, что существуют другие dc, где lastlogon содержит более позднюю дату, и это тот, который я за ним. Поэтому мне нужно запросить все dc, а затем просто экспортировать последнюю дату lastlogon для этого SamAccountName.
Почему бы не просто используйте атрибут lastLogonTimestamp? –
у него на самом деле гораздо более ранняя дата, чем LastLogon. Например ... 'LastLogon для этого dc в этом домене = 2/8/2016 10:00 am',' последний LastLogon для всех dc в этом домене = 2/10/2016 11:00 am', 'lastLogonTimestamp для этого dc в этом домене = 2/1/2016 9:00 am', –
См. [«Атрибут LastLogonTimeStamp» - «Что он предназначен и как он работает»] (https://blogs.technet.microsoft.com/askds/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works /) для получения дополнительной информации об атрибуте lastLogonTimestamp. С этим пониманием, почему вы не можете его использовать? –