Home > Blockchain >  Powershell - latest lastLogon from multiple DCs
Powershell - latest lastLogon from multiple DCs

Time:12-24

I need to export some properties of all PCs of my domain to *.csv table. One of the necessary properties is lastLogOn. The problem is that i have two Domain Controllers, so I need to choose the latest lastLogOn from them.

I have one solution, but it takes really a lot of time (about ~ 1 min) to give me a final array of computers. Here it is:

function getComputers([string]$dc) {
    return Get-ADComputer -SearchBase ‘DC=mydomain,DC=com’ -Server $dc -Filter * `
    -Properties name, samAccountName, DistinguishedName, lastLogOn, OperatingSystem | `
    Sort samAccountName
}
function getComputersFromsBothDCs {
    $compsDC1 = getComputers 'dc1'
    $compsDC2 = getComputers 'dc2'
    $comps = @()
    for ($i = 0; $i -le $compsDC1.Length - 1; $i  ) {
        $comp1 = $compsDC1[$i]
        $comp2 = $compsDC2[$i]
        if ($comp1.lastLogOn -ge $comp2.lastLogOn) {
            $comps  = $comp1
        } else {
            $comps  = $comp2
        }
    }
    return $comps
}

$comps = getComputersFromsBothDCs
# Then export and some other stuff

Function getComputers takes about 1 second per 1 DC, main problem is in choosing the PC with latest lastLogon.

Are there any faster solutions?

CodePudding user response:

Give this a try, should run faster. To consider, this script will only find computers that have the lastLogon property set, it will also add a new property (LastLogonDate) which is the conversion of lastLogon FromFileTime.

$AllDCs = Get-ADDomainController -Filter * # Get all DCs in the Domain
$logons = [System.Collections.Generic.Dictionary[string,object]]::new()

$params = @{
    LDAPFilter = '(LastLogon=*)' # Only find computers that have this Property
    SearchBase = 'DC=mydomain,DC=com'
    Properties = @(
        'Name'
        'samAccountName'
        'DistinguishedName'
        'lastLogon'
        'OperatingSystem'
    )
}

foreach($DC in $AllDCs)
{
    $params.Server = $DC
    # Find all computers using this target DC
    $computerList = Get-ADComputer @params |
    Select-Object @(
        $params.Properties
        @{
            Name = 'LastLogonDate'
            Expression = { [datetime]::FromFileTime($_.LastLogon) }
        }
    )
    
    foreach($computer in $computerList)
    {
        if($logons[$computer.samAccountName].lastLogonDate -lt $computer.lastLogonDate)
        {
            # On first loop iteration should be always entering this
            # condition:
            # $null -lt $true # => True
            # Assuming $computer.LastLogon is always a populated attribute
            # which also explains my LDAPFilter = '(LastLogon=*)' from before

            $logons[$computer.samAccountName] = $computer
        }
    }
}

$logons.Values # => Is your export

CodePudding user response:

we can follow the following method to obtain the computer with latest Lastlogon value

(1)- Get the list of ADComputers from both DCs and save the result in a single variable

$DCs = ("DC01,"Dc02")
$ComputersList = @()

foreach ($DC in $DCs){
    $ComputersList  = Get-ADComputer -filter {Enabled -eq $true } -Properties lastlogon,OperatingSystem -Server $DC | where {$_.lastlogon -ne $null} | Sort-Object -Property SamAccountName
}

(2) - Group the objects by SamAccountName attribute and sort the grouped result per "lastlogon" attribute then selecting the latest value only

$LatestList = $ComputersList | Group-Object -Property SamAccountName | % {$_.group | Sort-Object -Property lastlogon | select -Last 1}
  • Related