use strict; use Net::DNS; use Win32::OLE; # Specify the domain name on the command line # or use the default. my $domain = $ARGV[0] || 'YourDomainName.com'; print "====Querying for Domain Controllers in $domain====\n"; my %dcinfo = DNS_SRV_Query($domain, "_ldap._tcp.dc._msdcs"); while (my ($n,$IP) = each %dcinfo){ print " DC: $n [$IP]\n"; } my $forest = $ARGV[0] || 'YourForestName.com'; print "====Querying for Global Catalog servers in $forest====\n"; %dcinfo = DNS_SRV_Query($forest, "_ldap._tcp.gc._msdcs"); while (my ($n,$IP) = each %dcinfo){ print " GC: $n [$IP]\n"; } print "====Querying FSMO, Infrastrasturcture master servers in $domain====\n"; FSMO_Query($domain); ########################## sub DNS_SRV_Query{ my ($name,$DNSPrefix) = @_; my %results; my $DNS = Net::DNS::Resolver->new(); my $query = $DNS->search("$DNSPrefix.$domain", "SRV") or die "DNS SRV query ($DNSPrefix.$domain) failed: ", $DNS->errorstring, "\n"; foreach my $rr ($query->answer) { next unless $rr->type eq "SRV"; my $query2 = $DNS->search($rr->target, "A"); if ($query2) { foreach my $rr2 ($query2->answer) { next unless $rr2->type eq "A"; $results{$rr->target} .= $rr2->address . " "; } } } return %results; } ###################################### sub FSMO_Query{ my $strDomain = shift or die "No domain name specified"; # e.g. emea.rallencorp.com $Win32::OLE::Warn = 3; my $objRootDSE = Win32::OLE->GetObject("LDAP://$strDomain/RootDSE"); my $strDomainDN = $objRootDSE->Get("defaultNamingContext"); my $strSchemaDN = $objRootDSE->Get("schemaNamingContext"); my $strConfigDN = $objRootDSE->Get("configurationNamingContext"); PrintMasterName($strDomainDN,"PDC Emulator"); PrintMasterName("cn=RID Manager\$,cn=system","RID Master", $strDomainDN); PrintMasterName($strSchemaDN,"Schema Master"); PrintMasterName("cn=Partitions","Domain Naming Master",$strConfigDN); PrintMasterName("cn=Infrastructure","Infrastructure Master",$strDomainDN); # PDC Emulator my $objPDCFsmo = Win32::OLE->GetObject("LDAP://" . $strDomainDN); print "PDC Emulator: ", $objPDCFsmo->fsmoroleowner,"\n"; my $PDC = $objPDCFsmo->fsmoroleowner; print "I think the PDC name is :" . ExtractName($PDC,$strDomain) . "\n"; # RID Master my $objRIDFsmo = Win32::OLE->GetObject("LDAP://cn=RID Manager\$,cn=system,$strDomainDN"); print "RID Master: ", $objRIDFsmo->fsmoroleowner, "\n"; print "I think the RID Master is :" . ExtractName($objRIDFsmo->fsmoroleowner,$strDomain) . "\n"; # Schema Master my $objSchemaFsmo = Win32::OLE->GetObject("LDAP://" . $strSchemaDN); print "Schema Master: ", $objSchemaFsmo->fsmoroleowner,"\n"; print "I think the Schema Master is :" . ExtractName($objSchemaFsmo->fsmoroleowner,$strDomain) . "\n"; # Infrastructure Master my $objInfraFsmo = Win32::OLE->GetObject("LDAP://cn=Infrastructure," . $strDomainDN); print "Infrastructure Master: ", $objInfraFsmo->fsmoroleowner,"\n"; # Domain Naming Master my $objDNFsmo = Win32::OLE->GetObject("LDAP://cn=Partitions," . $strConfigDN); print "Domain Naming Master: ", $objDNFsmo->fsmoroleowner,"\n"; print "I think the Domain Naming Master is :" . ExtractName($objDNFsmo->fsmoroleowner,$strDomain) . "\n"; } ##################################3 sub PrintMasterName{ my ($FetchDN, $Type, $SourceDN) = @_; my $obj = Win32::OLE->GetObject("LDAP://$FetchDN" . ($SourceDN ? ",$SourceDN" : "") ); # print "==$Type DN: ", $obj->fsmoroleowner, "\n"; print "==I think the $Type is :" . ExtractName($obj->fsmoroleowner,$domain) . "\n"; } ##################################3 sub ExtractName{ my $str=shift; my @dom = split /\./, shift; STRINGPIECE: for (split /,/, $str){ m/Settings$/i and next; m/Servers$/i and next; m/Sites$/i and next; m/Configuration$/i and next; for my $domain_piece(@dom){ m/$domain_piece/ and next STRINGPIECE; } m/CN=(\w+)/; return $1; # Passed all tests ! } }