Quantcast
Channel: DNS – PowerShell for Windows Admins
Viewing all 24 articles
Browse latest View live

PowerShell for DNS

$
0
0

I’ve blogged on a number of occasions on how to use the DNS WMI provider.

Life just got easier with the release of DnsShell.  Its a PowerShell 2.0 module containing cmdlets for working with DNS.

Underneath the covers there is a lot of WMI involved.

The module is still a work in progress but already includes useful functionality.  I’ll be giving it a try out soon.

The module can be down loaded from http://code.msdn.microsoft.com/dnsshell

Technorati Tags: ,,

PowerShell UG Meeting: DNS

$
0
0


When: Tuesday, Jun 29, 2010 7:30 PM (BST)


Where: Live Meeting webcast

*~*~*~*~*~*~*~*~*~*

Meeting will cover DNS, DNS best practice analyser, DNS WMI provider and DNSShell cmdlets from codeplex

Notes


Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Troubleshooting
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
    https://www.livemeeting.com/cc/usergroups/join
  2. Copy and paste the required information:
    Meeting ID: NPP98R
    Entry Code: Dj\J_)4}g
    Location: https://www.livemeeting.com/cc/usergroups

If you still cannot enter the meeting, contact support

Notice
Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.

PowerShell UG – June meeting slides and recording

$
0
0

Thanks to everyone how joined the Live Meeting this evening – especially for the questions :-)

The slides and demo script are available for download from:

http://cid-43cfa46a74cf3e96.office.live.com/browse.aspx/PowerShell%20User%20Group/2010%20June

 

The recording of the session is available from:

Richard Siddaway has invited you to view a Microsoft Office Live Meeting recording.
View Recording
Recording Details
    Subject: PowerShell and DNS
    Recording URL: https://www.livemeeting.com/cc/usergroups/view
    Recording ID: NPP98R
    Attendee Key: Dj\J_)4}g

Scripting Guy Blog

WMI and Network Adapters: 5

$
0
0

Does a machine have problems communicating on the network? Then one troubleshooting step is to check the DNS servers it is using

001
002
003
004
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName "." |
where {$_.DNSServerSearchOrder} |
select Description, IPAddress, DNSServerSearchOrder

Get the instances of the NetworkAdapterConfiguration class for the computer and filter out those that don’t have a DNSServerSearchOrder set.  Display the results.

If you get nothing back then no NICs have DNS settings

DNS cmdlets in PowerShell 3

$
0
0

There are a number of modules related to DNS

ModuleType Name
———- —-
Manifest DnsClient
Manifest DnsConfig
Binary DnsLookup
Manifest DnsNrpt

If we start with the DnsClient module we get these functions and cmdlets

Add-DnsClientNrptRule
Clear-DNSClientCache
Get-DNSClient
Get-DNSClientCache
Get-DnsClientEffectiveNrptPolicy
Get-DnsClientNrptGlobal
Get-DnsClientNrptRule
Get-DNSGlobalSettings
Get-DNSServerAddress
Remove-DnsClientNrptRule
Set-DNSClient
Set-DnsClientNrptGlobal
Set-DnsClientNrptRule
Set-DNSGlobalSettings
Resolve-DnsName

Knowing which DNS server the client is using

PS> Get-DNSServerAddress | select ElementName, Name

ElementName Name
———– —-
Virtual Wireless 192.168.2.1
isatap.{E962BF88-1194-44A8-B30B-A65A4772C812} 192.168.2.1
Virtual LAN 10.10.54.201
isatap.{EA0AB201-1381-4643-A67D-72C9C8860860} 10.10.54.201
Loopback Pseudo-Interface 1 fec0:0:0:ffff::1
Loopback Pseudo-Interface 1 fec0:0:0:ffff::2
Loopback Pseudo-Interface 1 fec0:0:0:ffff::3

and what the client has cached

Get-DNSClientCache | select Name, data

Name data
—- —-
server02 192.168.2.1
server02 10.10.54.201
server02 192.168.1.6
server02.manticore.org 192.168.2.1
server02.manticore.org 10.10.54.201
server02.manticore.org 192.168.1.6
watson.telemetry.microsoft.com

final one for the moment – is a replacement for nslookup

PS> Resolve-DnsName exch07

IP4Address : 10.10.54.130
Name : exch07.Manticore.org
Type : A
CharacterSet : Unicode
Section : Answer
DataLength : 4
TTL : 1200

Get Global Catalog from DNS

$
0
0

One option for finding global catalog servers is often overlooked – DNS.  In an AD environment DNS stores the SRV records that advertise the services domain controllers can deliver

$dnsserver = "dc02"            
Get-WmiObject -Namespace 'root\MicrosoftDNS' -Class  MicrosoftDNS_SRVType `
-ComputerName $dnsserver -Filter "ContainerName = 'Manticore.org'" |             
Where {$_.OwnerName -like "_gc*"} |            
select TextRepresentation

We are interested in the ‘root\MicrosoftDNS’ name space and the MicrosoftDNS_SRVType records. We want the manticore.org zone and all records where the Ownername is like “_gc*”

The results look like this

_gc._tcp.Site1._sites.Manticore.org IN SRV 0 100 3268 dc02.manticore.org.

_gc._tcp.Site1._sites.Manticore.org IN SRV 0 100 3268 server02.manticore.org.  
_gc._tcp.Manticore.org IN SRV 0 100 3268 dc02.manticore.org.                                                     
_gc._tcp.Manticore.org IN SRV 0 100 3268 server02.manticore.org. 

Finding the primary name of a DNS alias record

$
0
0

A forum question asked how to find the primary name from an alias or CNAME record.

Get-WmiObject -Namespace 'root\MicrosoftDNS' -Class MicrosoftDNS_CNAMEType `
-Filter "ContainerName = 'Manticore.org'" -ComputerName server02  |             
select @{N='Alias'; E={$_.Ownername}}, Primaryname            

 

use the MicrosoftDNS_CNAMEType class. Filter on the domain ie containername.  ComputerName holds the DNS server name.

Change OwnerName to Alias in a select calculated field


DnsClient module: #1 Get-DnsClientServerAddress

$
0
0

Started to investigate the DnsClient module.  First cmdlet to catch my eye was Get-DnsClientServerAddress.

Always good to know a way to find the DNS server.

PS> Get-DnsClientServerAddress

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
————–               ——— ——- —————
Bluetooth Network Connection        19 IPv4    {}
Bluetooth Network Connection        19 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}
WiFi                                12 IPv4    {192.168.1.1}
WiFi                                12 IPv6    {}
isatap.tiscali.co.uk                14 IPv4    {192.168.1.1}
isatap.tiscali.co.uk                14 IPv6    {}
Ethernet                            13 IPv4    {}
Ethernet                            13 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}
Loopback Pseudo-Interface 1          1 IPv4    {}
Loopback Pseudo-Interface 1          1 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}
Teredo Tunneling Pseudo-I…        15 IPv4    {}
Teredo Tunneling Pseudo-I…        15 IPv6    {}

Now thats OK but I’d like a bit more information – especially the adapter and IP version.  We can get that data using Get-NetAdapter from the NetAdapter module.

Get-DnsClientServerAddress |             
where {$_.ServerAddresses -and $_.InterfaceAlias -notlike "Loop*" }|            
foreach {            
 $nic = $_            
 Get-NetAdapter -IncludeHidden -InterfaceIndex $($nic.InterfaceIndex) |            
 Add-Member -MemberType NoteProperty -Name ServerAddresses -Value $($nic.ServerAddresses) -PassThru |            
 Add-Member -MemberType NoteProperty -Name AddressFamily -Value $(if ($nic.AddressFamily -eq 2){"IPv4"}else{"IPv6"} ) -PassThru|            
 select Name, InterfaceDescription, ifIndex, Status, MacAddress, LinkSpeed, AddressFamily, ServerAddresses             
 }

 

I restricted the output to those interfaces that had DNS server addresses. Used the interface to get the adapter – notice the use of –IncludeHidden – and then used Add-Member to add the addresses and Address family to the data.

These may be CDXML cmdlets but they work the same as any other cmdlet

DnsClient module: #2 DnsClient & Cache

$
0
0

The DnsClient module has a number of Get- cmdlets

Get-DnsClient | Format-List InterfaceAlias, ConnectionSpecificSuffix, Register*, UseSuffix*

An example of the output is

InterfaceAlias                 : Ethernet
ConnectionSpecificSuffix       :
RegisterThisConnectionsAddress : True
UseSuffixWhenRegistering       : False

Of more interest when trouble shooting is Get-DnsClientCache

PS> Get-DnsClientCache | select -f 1 | fl

Entry      : 14.54.10.10.in-addr.arpa
RecordName : 14.54.10.10.in-addr.arpa.
RecordType : PTR
Status     : Success
Section    : Answer
TimeToLive : 86400
DataLength : 4
Data       : Win7test

You get a number of ways to interrogate the cache

PS> Get-Command Get-DnsClientCache  -Syntax

Get-DnsClientCache [[-Entry] <string[]>] [-Name <string[]>] [-Type <Type[]>] [-Status <Status[]>]
[-Section<Section[]>] [-TimeToLive <uint32[]>] [-DataLength <uint16[]>] [-Data <string[]>]
[-CimSession <CimSession[]>][-ThrottleLimit <int>] [-AsJob] [<CommonParameters>]

Its another CIM based cmdlet so you can use CimSessions to access remote machines. Very useful if you think the machine isn’t resolving DNS names properly

Creating DNS PTR records

$
0
0

When I was writing the DNS chapter of PowerShell in Practice I couldn’t get the CreateInstanceFromPropertyData method on the MicrosoftDNS_PTRType class to work. Revisiting DNS for AD management in a Month of lunches this time round I have access to the CIM cmdlets so can put the parameter names in. This gives usage like this. I’ve shown Invoke-WmiMethod and Invoke-CimMethod so you can see the parameter names:

Invoke-WmiMethod -Namespace root\MicrosoftDNS -Class MicrosoftDNS_PTRType `
-Name CreateInstanceFromPropertyData `
-ArgumentList “175.168.192.in-addr.arpa”, ‘server02′, ’55.175.168.192.in-addr.arpa’,
“ADMLServer02.admldns.test”

Invoke-CimMethod -Namespace root\MicrosoftDNS -ClassName MicrosoftDNS_PTRType `
-MethodName CreateInstanceFromPropertyData `
-Arguments @{Containername = “175.168.192.in-addr.arpa”;
DnsServerName = ‘server02′; OwnerName = ’55.175.168.192.in-addr.arpa’;
PTRDomainName =”ADMLServer02.admldns.test”}

If you have access to Windows 2012 then you are better off using the cmdlet

Add-DnsServerResourceRecordPtr –Name ‘54’ `
–ZoneName “175.168.192.in-addr.arpa” `
–PtrDomainName ‘ADMLServer01.admldns.test’ `
–ComputerName server02

Which ever method you use – you can easily create PTR records

DNS zone types

$
0
0

I was looking at the DNS zones for a project I’m working on. I needed to discover the conditional forwarder zone and hence the IP address of the DNS server to which the forwarding was occurring.

The zone I wanted had a ZoneType of 4 which puzzled me.

I remembered showing code to create a conditional forwarder in PowerShell in Practice (www.manning.com/siddaway)

$ip = “192.168.40.1”
$zone = [WMIClass]”\\dc02\root\MicrosoftDNS:MicrosoftDNS_Zone”
$zone.Create(“conditional.com”, 3, $true, $null, $ip)

When creating a conditional forwarder you use 3 for the zone type but when reading the zone you get a 4 as the zone type. Other zone types have similar differences

Primary zone (forward or reverse lookup) = create as type 0 and read as type 1

Stub zone = create as type 2 and read as type 3

This is another of the oddities that make WMI so much fun to work with. Easy when you know what’s happening but confusing when you don’t – just like so much with WMI. Does the W stand for Weird? :-)

The Windows Server 2012 DNS cmdlets make this sooooo much easier.

Have you been talking to strangers?

$
0
0

Want to know the machines to which your machine has been connecting?

 

Try looking in the client DNS cache:

 

Get-DnsClientCache

 

will show a wealth of useful data.  All in the form:

£> Get-DnsClientCache | where Entry -like ‘*www.intelliweather.net*’ | fl *
TTL                   : 39
Caption               :
Description           :
ElementName           :
InstanceID            :
Data                  : cache1.intelliweather.net
DataLength            : 8
Entry                 : www.intelliweather.net
Name                  : www.intelliweather.net
Section               : 1
Status                : 0
TimeToLive            : 39
Type                  : 5
PSComputerName        :
CimClass              : ROOT/StandardCimv2:MSFT_DNSClientCache
CimInstanceProperties : {Caption, Description, ElementName, InstanceID…}
CimSystemProperties   : Microsoft.Management.Infrastructure.CimSystemProperties

TTL                   : 39
Caption               :
Description           :
ElementName           :
InstanceID            :
Data                  : 38.114.169.29
DataLength            : 4
Entry                 : www.intelliweather.net
Name                  : cache1.intelliweather.net
Section               : 1
Status                : 0
TimeToLive            : 39
Type                  : 1
PSComputerName        :
CimClass              : ROOT/StandardCimv2:MSFT_DNSClientCache
CimInstanceProperties : {Caption, Description, ElementName, InstanceID…}
CimSystemProperties   : Microsoft.Management.Infrastructure.CimSystemProperties

 

 

What is interesting is the Time To Live settings on some of the records:

£> Get-DnsClientCache | sort TTL -Descending | group TTL -NoElement

Count Name
—– —-
7 74538
1 70203
1 64639
1 53300
1 53299
1 16441
2 9308
1 2579
1 2573
3 2475
6 2469
2 2327
2 1986
1 1890
1 1089
1 999
2 899
2 891
2 878
3 728
1 724
6 711
1 631
1 458
1 412
1 363
1 133
15 0

 

Some of those records will be around for a long time!

DNS client settings

$
0
0

Following yesterdays post there are a couple of other cmdlets worth looking at if you want to dig into the DNS settings on your client machines.

Get-DnsClient wil show you the DNS relsted settings for all of your network interfaces by default.  To investigate a single interface

 

£> Get-DnsClient -InterfaceAlias vEthernet* | fl
InterfaceAlias                     : vEthernet (External01)
InterfaceIndex                     : 20
ConnectionSpecificSuffix           :
ConnectionSpecificSuffixSearchList : {}
RegisterThisConnectionsAddress     : True
UseSuffixWhenRegistering           : False

InterfaceAlias                     : vEthernet (Internal01)
InterfaceIndex                     : 16
ConnectionSpecificSuffix           :
ConnectionSpecificSuffixSearchList : {}
RegisterThisConnectionsAddress     : True
UseSuffixWhenRegistering           : False

 

You can also see the DNS servers a particular interface will use:

£> Get-DnsClientServerAddress -InterfaceAlias vEthernet*

InterfaceAlias               Interface Address ServerAddresses
Index     Family
————–               ——— ——- —————
vEthernet (External01)              20 IPv4    {192.168.0.1}
vEthernet (External01)              20 IPv6    {}
vEthernet (Internal01)              16 IPv4    {}
vEthernet (Internal01)              16 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}

Parsing ipconfig /displaydns

$
0
0

 

A recent question on the forum asked how you could get the contents on Windows 7 machines and earlier.

On later machines – Windows 8 and above –  its easy because you can use Get-DnsClientCache from the DnsClient module. This module is based on CIM classes that aren’t present on Windows 7 and earlier systems.

You can use ipconfig /displaydns to display the data but it looks like this

Record Name . . . . . : ns-nw.noaa.gov
Record Type . . . . . : 1
Time To Live  . . . . : 81966
Data Length . . . . . : 4
Section . . . . . . . : Additional
A (Host) Record . . . : 161.55.32.2

so you need to parse the strings into a format that you can work with.

This is one solution

$props = [ordered]@{
RecordName = “”
RecordType = “”
Section    = “”
TimeToLive = 0
DataLength = 0
Data       = “”
}

$recs = @()

$cache = ipconfig /displaydns
for($i=0; $i -le ($cache.Count -1); $i++) {
if ($cache[$i] -like ‘*Record Name*’){
$rec = New-Object -TypeName psobject -Property $props
$rec.RecordName = ($cache[$i] -split -split “: “)[1]
$rec.Section = ($cache[$i+4] -split -split “: “)[1]
$rec.TimeToLive = ($cache[$i+2] -split -split “: “)[1]
$rec.DataLength = ($cache[$i+3] -split -split “: “)[1]

$irec = ($cache[$i+5] -split “: “)
$rec.RecordType = ($irec[0].TrimStart() -split ‘ ‘)[0]
$rec.Data = $irec[1]

$recs += $rec
}
else {
continue
}
}

$recs | Format-Table –AutoSize

Create an ordered hash table of output properties and an empty array to hold the results.

Get the output of  ipconfig /displaydns into $cache which will be an array of strings

Loop through $cache

if the record is like *Record Name*’ then process that record and the next five records to give the results.  The actual data record is split twice to give the record type and the data – otherwise you’ll have to translate the numeric values in the Record Type line.

The results are put into an object which is added to the output array.

Continue looping through $cache until you meet the next line with a Record Name or end of file.

Finally display the results.

This works but is messy – I’m going to investigate alternatives


Parsing ipconfig /displaydns with regular expressions

$
0
0

In yesterdays post I used a series of split operations to parse the strings produced by ipconfig /displaydns

 

Regular expressions should give a more power full way to perform this task. Not being a big fan of regular expressions I tend not to use them but for the sake of experimentation I thought I’d try and figure out a set of regex to use.

 

This is as far as I’ve got

 

$props = [ordered]@{
RecordName = “”
RecordType = “”
Section    = “”
TimeToLive = 0
DataLength = 0
Data       = “”
}

$recs = @()

$cache = ipconfig /displaydns
for($i=0; $i -le ($cache.Count -1); $i++) {
if ($cache[$i] -like ‘*Record Name*’){
$rec = New-Object -TypeName psobject -Property $props
$rec.RecordName = $cache[$i] -replace “(\s*\w*){2}(\s\.){5}(\s\:\s)”, “”
$rec.Section = $cache[$i+4] -replace “\s*\w*(\s\.){7}(\s\:\s)”, “”
$rec.TimeToLive = $cache[$i+2] -replace “(\s*\w*){3}\s(\s\.){4}(\s\:\s)”, “”
$rec.DataLength = $cache[$i+3] -replace “(\s*\w*){2}(\s\.){5}(\s\:\s)”, “”

$irec = ($cache[$i+5] -split “: “)
$rec.RecordType = ($irec[0].TrimStart() -split ‘ ‘)[0]
$rec.Data = $irec[1]

$recs += $rec
}
else {
continue
}
}

$recs | Format-Table –AutoSize

 

I still need to work out how to process the data and record type using regular expressions

Error handling for DNS lookups

$
0
0

Interesting question on the forum regarding the Resolve-DNSname cmdlet. This is part of the DNSclient module introduced with Windows 8.

If the DNS record is found everything is good

£> Resolve-DnsName W12R2DSC -Server server02 | ft -a

Name                   Type TTL  Section IPAddress
—-                   —- —  ——- ———
W12R2DSC.Manticore.org A    1200 Answer  10.10.54.204

If the record isn’t found you get an error

£> Resolve-DnsName W12R2DSC3 -Server server02
Resolve-DnsName : W12R2DSC3 : DNS name does not exist
At line:1 char:1
+ Resolve-DnsName W12R2DSC3 -Server server02
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ResourceUnavailable: (W12R2DSC3:String) [Resolve-DnsName], Win32Exception
+ FullyQualifiedErrorId : DNS_ERROR_RCODE_NAME_ERROR,Microsoft.DnsClient.Commands.ResolveDnsName

If you want to gracefully handle that error you use try-catch

$computer = ‘W12R2DSC3′
try {
Resolve-DnsName $computer -Server server02 -ErrorAction Stop
}
catch {
Write-Warning -Message “Record not found for $computer”
}

NSlookup in PowerShell

$
0
0

nslookup.exe is a command line executable that is used to discover the IP address of a remote machine from its FQDN. The results look something like this:

PS> nslookup powershell.org
DNS request timed out.
timeout was 2 seconds.
Server:  UnKnown
Address:  192.168.0.1

Non-authoritative answer:
DNS request timed out.
timeout was 2 seconds.
Name:    powershell.org
Addresses:  104.28.15.25
104.28.14.25

The output is text – not the most useful of things to use.

One option if you want to perform lookups in PowerShell is to write your self a script

$ns = (nslookup.exe powershell.org )[-4..-3]
$lookup = [PSCustomObject]@{
Name = ($ns[0] -split ‘:’)[1].Trim()
Address = ($ns[1] -split ‘:’)[1].Trim()
}
$lookup

Run nslookup and take the 3rd and 4th lines from the end of the output. Then create an output object where the text in the array is split at the : the second element is used and trimmed of blank spaces.

If you like using .NET static methods you can do this:

PS> [System.Net.DNS]::GetHostEntry(‘powershell.org’)

HostName       Aliases AddressList
——–       ——- ———–
powershell.org {}      {104.28.15.25, 104.28.14.25}

Best of all is the use the Resolve-DnsName cmdlet from the DnsClient module that’s present in Windows 8 and later

PS> Resolve-DnsName -Name ‘powershell.org’ | ft -a

Name           Type TTL Section IPAddress
—-           —- — ——- ———
powershell.org A    300 Answer  104.28.15.25

Create a reverse lookup zone

$
0
0

I needed to create a DNS reverse lookup zone for my test environment. With Windows Server 2012 R2 I’ve got cmdlets available for managing DNS servers – the DnsServer module. You need to install the DNS role or the DNS RSAT tools to get access to the module.

 

To create a new reverse lookup zone

Add-DnsServerPrimaryZone -DynamicUpdate Secure -NetworkId ‘10.10.54.0/24′ -ReplicationScope Domain

 

Use the netorkId to define the subnet the zone spans. Setting DynamicUpdate to Secure ensures I have an AD integrated zone and I’ve set the replication scope to the domain.

 

Doesn’t get any easier

Creating DNS records

$
0
0

Following on from my previous post about creating a reverse lookup zone in DNS here’s a function to create records in that zone.

The function takes an IP address and name (of host) and uses Add-DnsServerResourceRecordA  to add the record to the forward lookup zone – I use my default AD zone.

The function then splits the IP address. Uses the last octet for the name in the reverse record. Creates the reverse lookup zone from the first 3 octets – notice how the range parameter is used in a decreasing way to specify the order of the octets – to create the reverse lookup zone. The host name and zone are used to create the FQDN of the host.

Add-DnsServerResourceRecordPtr  is used to create the reverse (PTR) record.

function new-dnsrecord {
[CmdletBinding()]
param (
[string]$name,
[string]$ipaddress,
[string]$zone = ‘Manticore.org’
)

Add-DnsServerResourceRecordA -Name $name -ZoneName $zone -AllowUpdateAny -IPv4Address $ipaddress

$octs = $ipaddress -split ‘\.’

$revname = “$($octs[3])”
$revzone = “$($octs[2..0] -join ‘.’).in-addr.arpa”
$fqdn = “$name.$zone”

Add-DnsServerResourceRecordPtr -Name $revname -ZoneName $revzone -AllowUpdateAny -PtrDomainName $fqdn

}

Viewing all 24 articles
Browse latest View live