Thursday, September 21, 2017

Reverse CNAME lookup with dns cmdlets

In case you ever get the request to find any alias that points to a server (or list of servers), you can use the DNS commandlets to build a list of results on a zone by zone basis to further dig through.  This command will give you a rough list with 3 attributes:

Hostname = name of the dns record
ShortAlias = non-fqdn of the DNS record data (where the CNAME points to)
Alias = full DNS record data

I put the short name in there just in case the information provided to you is a short server name.

$zone = ""
$recs = get-DnsServerResourceRecord -zonename $zone -rrtype cname |
    select @{name="shortalias"; expr={
        $_.recorddata.hostnamealias -replace "\..*",""}}, @{name="alias";

This will give you the full list of cname data for the zone in an array of objects.  If what you are searching for is an array, just run it through a loop in one of two ways [example of matching short names against an array of names to search for]

foreach ($name in $list) {  $recs | where {$_.shortalias -match $name} }


foreach ($entry in $recs) { if ($list -contains $entry.shortalias) { $entry } }

Its not super clean, but it will display the records.  You can modify the loops to collect the data in an array.  You could even run an extra outer loop to hit multiple zones.  The $list can just be a copy and paste into powershell from excel or whatever the list comes in.

$list = "

Make sure when you paste, you don't end up with the " on a new line at the end like it shows above.  If you do that, the first loop example will dump out the whole $recs array on the last entry in $list.

If you don't have access to the Dns cmdlets, but you have rights to pull the zone with dnscmd, you can do something like this:

dnscmd /zoneprint | where {$_ -match "CNAME"} | 
  % {$resline = $_ -split "\s+"; ($resline[0], $resline[3]) }

You'll have to do something with the two values at the end, which are record name and record data.

Monday, August 28, 2017

VI editor for windows admins and its benefits for preformatting data

As someone with some linux background, I ended up using VI/VIM as my go to editor for any linux text editing.  While its a powerful, and some may say complicated, piece of software, if you learn a few of the basic commands and tricks it will be a very beneficial tool.  For windows, there are versions available, such as gvim.  I often find myself going back to it as a nice text editing tool when I receive text that needs some transformation work prior to using it in a script or some other data tool.

Let me give a few examples.

Example #1, you need a csv list of entries, however you have received a list with one item per line.

  1. Copy the text from the original source
  2. open gvim
  3. hit the insert key, to enter insert mode
  4. paste from the clip board
  5. hit esc, to enter command mode
  6. type (including the colon):     :1,$s/\n/\,/
  7. go to the very end of that line and remove the extra comma, ensure its highlighted, then type dl
  8. go to the edit menu, select all and copy
  9. paste it into whatever app you needed it in csv format

Let me explain a bit from the example above.  For most people when they think of text editors you are always in a mode where you are editing the text, and any special command will be a menu item or a keyboard shortcut of a combination of a special key (ctrl, alt, etc) and a letter or number.  VI uses different modes of operations, the two highlighted here are Command (this is what you start it when vi opens), and Insert (this is one of the text editing modes).  While in command mode, there are keyboard shortcuts for moving and editing text based on the cursor position, like in step number 7.  The d, followed by another modifier (lower case L in this example) says delete, in the direction specified (L) which deletes the highlighted character and moves left.  These same direction keys used in the delete command can be used on their own to move the cursor around.  Numbers can be put in front of them to make the move farther.  Another useful operation combined with the delete option is using the W key, this specifies word.  So when combined with the delete (typing:  dw) it deletes from the position of the cursor to the end of the current word.  You can again combine that with numbers, such as d3w, to delete from the current position 3 words to the right.

Now let me explain step #6 and the strange code in there.  When in command mode not all commands are executed by directly typing letters and numbers, sometimes the command needs to be entered from a special prompt, which is brought up by typing the colon.  So in the beginning of that text, the colon brings up this special prompt, and the next 2 parts of the command are a range.  1,$ means from line 1 to the end of the document.  The s/// command is substitution with regex support.  s/ starts the substitute command, the first area between the forward slashes is a regex of what you want to subtitute, and the next area between the forward slashes is the text you want to change it with.  Since its regex, you may need to use lots of backslashes for escaping text.  In this example  /\n/\,/ means match a newline (\n) and replace it with a comma.  Hit enter aft er that and it will execute.  If you are doing multiple matches on a single line, putting a g at the end, such as s///g switches to global match mode.  This command combined with regex is very powerful, and can be used to rearrange text by subset matching.  For cleaning up text, substitute is one of the main go to functions, so doing some research on that and regex's will make it incredibly powerful for you.

One more thing I want to highlight, in case you are using vim without a gui menu, saving a file is :w in command mode, and to exit vim :q.  As with other commands, these can be combined as :wq save and quit.

Insert mode is much more like your standard text editing experience where you move around and edit text.  When working in linux/unix shells, sometimes the arrow keys or backspace key may not work exactly as expected and instead throws some wierd codes into your text.  So if you end up in that situation, learn a bit about the movement, delete and replace commands in command mode.

In the future I may add some additional examples as I come across them.

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 /
Trusted DC Name \\
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$serv,$p)
  if ($conn.connected) { $result = $true } else { result = $false }
 } 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:

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)"
$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[]]($[0])) ` -encoding Byte