Monday, July 31, 2017

Testing connectivity to your domain controller

In the distant past there was a useful client side tool for checking connectivity between clients and domain controllers (netdiag.exe). According to microsoft's command line reference guide, it is available in windows 8 and 2012, but in reality the command does not exist on any windows machine I have checked beyond 2003. Trying to run an older version won't work either due to some incompatibility. So, alternatives are required to do checks. One thing you would typically want to check between a client and a domain controller is port connectivity.  Below, I will show a simple script that tests most of the ports.  Some may not be open in your environment (like 636,3269 for ldaps).  Some ports are dynamic, so I haven't included trying to check these.

To begin with, you should know what domain controller your workstation has logged into.  This machine logon establishes the "secure channel" between your machine and the domain.  You can use an old tool that is still around called nltest. 

C:\Windows>nltest /sc_query:contoso.com
Flags: 30 HAS_IP  HAS_TIMESERV
Trusted DC Name \\DC1.contoso.com
Trusted DC Connection Status Status = 0 0x0 NERR_Success
The command completed successfully
This output shows the status of your secure channel, and the name of the domain controller you are querying.  You will need to provide the name of the domain you are connected to.  FQDN domain name or NETBIOS domain name should work fine.

This script will provide two functions, one port checker and one function to run to test your connection.  Run Test-DomainControllerPorts with your domain name (or leave it blank for auto detect).  The script returns the name of the DC that you are connected to, along with 2 arrays of ports that are open and another of ports that aren't responding.

function tcpt ([string]$serv, [string]$p) {
 $result = $false
 try {
  $conn = new-object system.net.sockets.tcpclient($serv,$p)
  if ($conn.connected) { $result = $true } else { result = $false }
  $conn.close()
 } catch {
  $result =  $false
 }
 $conn = $null
 return $result
}
function test-DomainControllerPorts {
 param (
  $domainname = (gwmi win32_computersystem).domain
 )
 $secureChannelDC = (nltest /sc_query:$domainname |
  where {$_ -match "Trusted DC Name"}).split("\\") |
  where {$_ -match $domainname}
 $secureChanneldc = $securechanneldc.trim()
 $functionalports = @()
 $nonFunctionalPorts = @()
 $portsToCheck = ("53", "88", "137", "139", "389", "445", "464", "3268", "636", "3269")
 foreach ($port in $portsToCheck) {
  $portstat = tcpt $secureChannelDC $port
  if ($portstat) {
   $functionalports += $port
  } else {
   $nonfunctionalPorts += $port
  }
 }
 $result = new-object PSObject
 add-member -inp $result NoteProperty DomainController $secureChannelDC
 add-member -inp $result NoteProperty OpenPorts $functionalports
 add-member -inp $result NoteProperty UnOpenPorts $nonfunctionalports
 out-default -inp $result
}

Sunday, July 2, 2017

AD: Simple way to remove all members of a group

No loops required, use the -clear parameter in set-aduser.

Set-adgroup -identity "name of group" -clear member

The time required to execute will vary depending on number of people in the group.

Saturday, May 6, 2017

Some of my coding on Github

1) From Columbia AI course assignment for search algorithms, n-puzzle solver in python 3.  My first attempt at python programming.
2) From Columbia AI course assignment in CSP's, suduko solver using AC3 and backtracking, written in Python3.
3) Arabic typing website code.  (Live site at: http://makinghijrah.com/arabic-typing/)

Wednesday, April 19, 2017

Download all enterprise CA crl's from active directory

This script will look for all published crl's in the configuration partition, download them, and write them to binary files.  To further examine the files, you can open them up in windows (standard certificate viewing tools), or use the PSPKI module to dig into the data.


$debase = new-object directoryservices.directoryentry("LDAP://RootDSE")
$configpartition = $debase.configurationNamingContext[0]
$de = new-object directoryservices.directoryentry(` "LDAP://CN=CDP,CN=Public Key Services,CN=Services," + $configpartition)
$ds = new-object directoryservices.directorysearcher($de)
$ds.filter = "(objectclass=cRLDistributionPoint)"
$ds.propertiestoload.add("certificaterevocationlist")|out-null
$crls = $ds.findall()
foreach ($crl in $crls) {
$CAcert = $crl.path.replace("LDAP://CN=","")
$CAcert = $CAcert.substring(0,$CAcert.indexof(","))
$file = $CACert + ".crl"
set-content $file  ([byte[]]($crl.properties.certificaterevocationlist[0])) ` -encoding Byte
}

Download all files from IIS web directory listing (non-recursive)

This simple code should be able to dig out all file names from inside the A HREF tags where the file name consists of letters, numbers, a few special characters, spaces, file path forward slashes and periods; and ends with an extension of 2-4 characters.  Each entry will be downloaded, however, take note that the A HREF data will contain a relative path to the item, including the directory structure.  The webclient downloadfile method's second parameter wants a path name, including file name, for the destination.  If the full path doesn't exist, the file may just get put in the current directory.

$wc = new-object net.webclient

$sitename = "http://somesite/somedirectory"

$weblisting = $wc.downloadstring($sitename)

$items = select-string '"[a-zA-Z0-9/._-() ]*\.[a-zA-Z0-9]{2,4}"' `
   -input $weblisting -allmatches|
   foreach {$_.matches.value.replace('"','')}



foreach ($item in $items) {

 $wc.downloadfile($sitename + $item, ".\" + $item)

}