Get-ADComputer -Filter * -Properties *
Only get the properties that you intend to use... it's more efficient. Retrieving all the properties of all computers in the domain when you don't really need all the properties is unnecessarily demanding on your domain controller. It's wasteful.
Get-ADComputer -Filter * -Properties OperatingSystem, LastLogonDate
is better, since you don't need all the properties. (The 'Name' property is always included.)
| FT Name, OperatingSystem, LastLogonDate -Autosize
Don't format output until the very end. In other words, Format-Table and Format-List should be the very final cmdlets in the entire chain of cmdlets that data is piped to.
Get-ADComputer -Filter * -Properties OperatingSystem, LastLogonDate |
Where { $_.LastLogonDate -GT (Get-Date).AddDays(-30) }
This is a little better, but there's still some inefficiency, since you are still retrieving a data set of all computers... you could let the domain controller do the filtering for you.
$LastMonth = $(((Get-Date).AddDays(-30)).ToFileTime())
Get-ADComputer -LDAPFilter "(lastLogonTimeStamp>=$LastMonth)" -Properties OperatingSystem,LastLogonDate
The reason why I used the lastLogonTimeStamp there (which is a "file time," not a .NET DateTime,) is because "LastLogonDate" is not a real LDAP attribute. LastLogonDate is simply PowerShell's helpful way of automatically converting the lastLogonTimestamp attribute for you. lastLogonTimestamp is the "real" LDAP attribute.
Allowing the domain controller to return a filtered set to you, instead of the full set of ALL computers, means there is less data going over the wire and less data for PowerShell to process.
Also note that you are going to have to deal with computers that:
- Have a (null) LastLogonDate
- Have a LastLogonDate of 1/1/1601, or the beginning of the epoch.