<#================================================================================================ NAME: AD-PortScan.ps1 AUTHOR: Marty J. Piccinich DATE CREATED: 9/15/2009 VERSION: 1.1 HISTORY: 1.0 9/15/2009 - Created 1.1 10/23/2009 - Added comment header PARAMETERS: Comma separated list of ports to scan. EXAMPLE: AD-PortScan 23,80,110,445 The above example would scan hosts to see if telnet, http, pop, and smb ports are open. DESCRIPTION: Queries Active Directory (currently logged into) for all computer objects, pings the computer first, then attempts TCP connection to specified ports. * Gets computer objects from Active Directory using DirectorySearcher * Checks if the host is alive with Net.NetworkInformation.Ping * Looks up the IP address with Net.Dns.GetHostEntry * Attempts to connect to ports specified in array with Net.Sockets.TcpClient.BeginConnect NOTES: For more details, see the blog post: http://praetorianprefect.com/archives/2009/09/whos-being-promiscuous-in-your-active-directory/ IMPORTANT: You have a royalty-free right to use, modify, reproduce, and distribute this script file in any way you find useful, provided that you agree that the creator, owner above has no warranty, obligations, or liability for such use. ================================================================================================#> Param ( $PortList ) $ErrorActionPreference = "SilentlyContinue" $PingTest = New-Object System.Net.NetworkInformation.Ping $Filter = "(&(ObjectCategory=computer))" $Searcher = New-Object System.DirectoryServices.DirectorySearcher($Filter) ForEach ($Comp in $Searcher.Findall()) { $CompName = $Comp.properties.item("Name") if ($PingTest.Send($CompName).Status -eq "Success") { $HostEntry = [Net.Dns]::GetHostEntry($CompName) foreach ($ip in $HostEntry.AddressList) { write-host "Checking: $CompName on $ip" foreach ($tcpport in $PortList) { $TCPclient = new-Object system.Net.Sockets.TcpClient $Connection = $TCPclient.BeginConnect($ip,$tcpport,$null,$null) $TimeOut = $Connection.AsyncWaitHandle.WaitOne(3000,$false) ## 3 second timeout can be modified if(!$TimeOut) { $TCPclient.Close() write-host " OK: Port $tcpport is closed." } else { try { $TCPclient.EndConnect($Connection) | out-Null $TCPclient.Close() ## Next line outputs that the port is closed. I prefer to see output processing; comment for outputting only open ports. Write-Host " " -nonewline; write-host "Host: $CompName has port $tcpport open!" -foregroundcolor red -backgroundcolor yellow } catch { ## Machine actively refused the connection. The port is not open but $TimeOut was still was true. ## Uncomment next line to output the error for this. ## write-host $_ write-host " OK: Port $tcpport is closed." } } $TCPclient = $null } } } else { write-host "Could not ping host $CompName, machine not queried." } }