Using PowerShell to enumerate computers in your enterprise

I’ve created some PowerShell code to create a computer enumeration script (for discovery of new machines).
In our clients environment we have some challenges:
-Different types of domains, Active Directories and NT4 domains
-Name resolution, from the machine we use to run this kind of scripts, we have DNS and Netbios name resolution to some domains,
only Netbios or DNS to others and even NO name resolution to a few.
-Firewall issues, no LDAP to some Domain Controllers for example
-Authentication issues, some domains are not ‘trusting’ so we need to provide alternate credentials
So I decided to create some code to be able to do discovery using different methods, basically one using LDAP,
one using the good old WinNT provider and one using Psexec to run a dsquery on the Dc to discover machines:
I didn’t post the complete script because it’s embedded in a larger script that is very specific to the environment we are in…
Hopefully the pieces of script give you a place to start, you probably want to build some code around it to store the output in SQL,Excel,
whatever I guess…
The LDAP way (we prefer this for Active Directory Domains for speed and because it’s kind of more modern):
You can add all the AD Computer atrributes you like to store.
#logonuser is used so we can provide alternate credentials
#the password can be set in cleartext – in our production script we use a decrypted secure string from an encrypted file for security
#the connectstring can be a FQDN for a domain, host or an IPaddress for a Domain Controller to be flexible with name resolution 
$strCategory = "computer"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry("
If (!$objDomain.distinguishedName){"Error connecting to $connectstring using LDAP " ; exit}
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("(objectCategory=$strCategory)")
$objSearcher.PageSize = 50000
$colProplist = "name","pwdlastset","useraccountcontrol"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults) {
$MachineInfo = $objResult.Properties
$pwdlastset=$MachineInfo.PwdLastSet }

The WinNT way (we use a piece of VBscript in PowerShell because the WinNT provider through PowerShell doesn’t seem to be able to do this,
or at least I haven’t been able to figure it out yet 😉
We need this for NT4 domains and AD domains for which we don’t have LDAP access to the DCs
So to be clear this function is NOT PowerShell code, but it works (I’d like to replace this if anyone has the PoSh replacement code for this, please let me know!)
Function ListComputers
    Set Domain=GetObject("WinNT://contoso")
    list="Name,PwdAge,UserFlags" & vbNewLine
    For Each Member in Domain
    Set Computer=GetObject("WinNT://contoso/" & Member.Name & Chr(36) &",user")
    list = list & & "," & pwdAge & "," & UserFlags & vbnewline
End Function
Our last resort is to use a spawned psexec with a dsquery command for Domain Controllers that we don’t have much access to (only requires SMB TCP 445 opened)
We embed a command like following in PowerShell and then have to do some old fashioned string manipulation on the output, because it’s text, not Objects what you get back of course 😉
dsquery * domainroot -filter "(&(objectCategory=Computer)(objectClass=Computer)(sAMAccountName=*))" -attr cn pwdlastset useraccountcontrol -limit 0
Well please use my examples as you like, please let me know what you think!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s