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}