Resolve IP address from CNAME record with Powershell - powershell

My servers have recently moved from a simple www.example.com A 10.10.10.10 type structure to using CNAME abstraction....
www.example.com CNAME www1.example.com
www1.example.com A 10.10.10.10
Previously I could do a DNS lookup to get the A record using:
$myHostIp = Resolve-DnsName "www.example.com" A -DnsOnly | Select-Object -first 1
$myHostIp = $myHostIp.IP4Address
(this doesn't work with the CNAME records).
How do I get the (first) IP address associated with a CNAME record?
I tried:
$myHostIp = Resolve-DnsName "www.example.com" A -DnsOnly | Select-Object -first 1 -Property IP4Address
But I just get null.

When you query a CNAME with Resolve-DnsName -Type A, you get two responses. The first is the CNAME response, and the second is the A.
You can see clearly what happens like so:
PS> Resolve-DnsName -Name 'www.google.com' -Type A -DnsOnly | Format-List -Property *
QueryType : CNAME
Server : forcesafesearch.google.com
NameHost : forcesafesearch.google.com
Name : www.google.com
Type : CNAME
CharacterSet : Unicode
Section : Answer
DataLength : 8
TTL : 228
Address : 216.239.38.120
IPAddress : 216.239.38.120
QueryType : A
IP4Address : 216.239.38.120
Name : forcesafesearch.google.com
Type : A
CharacterSet : Unicode
Section : Answer
DataLength : 4
TTL : 228
You're getting a null because the first object does not contain a property called "IP4Address", and the value of properties which do not exist is null.
Try:
$myHostIp = Resolve-DnsName -Name 'www.example.com' -Type A -DnsOnly |
Where-Object QueryType -eq 'A' |
Select-Object -First 1 -ExpandProperty IP4Address

I found a solution.
Resolve-DnsName was returning two records in place of the 1 it had done previously - the first was for the CNAME record with a null IP address property, but the second was correctly populated, so I changed Select-Object -first for Select-Object -last.
I'll leave the question open to see if someone else has a smarter solution.

Related

Strange DNS record duplication with Powershell?

While recently working with the native Powershell DNS commandlets, specifically Get-DNSServerResourceRecord, I noticed something strange that does not make sense to me.
When I look into my zone using native DNS tools, LDAP query tools, or even ADSIedit, I see only a single DNS object representing a given hostname.
However, when I do the same with Powershell, I instead get two objects for a given host, one for the NETBIOS name, and the other for the FQDN. All other attributes are the same, including the IP.
For example, if I had a computer named computer1: This is what I see.
PS C:\> Get-DnsServerResourceRecord -ZoneName 'mydomain.local' -RRType A -ComputerName 'DNSServer1' | Where-Object {$_.hostname -like "Computer1*"} | fl *
DistinguishedName : DC=computer1.mydomain.local,DC=mydomain.local,cn=MicrosoftDNS,DC=DomainDnsZones,DC=mydomain,DC=local
HostName : COMPUTER1.mydomain.local
RecordClass : IN
RecordData : DnsServerResourceRecordA
RecordType : A
Timestamp :
TimeToLive : 01:00:00
Type : 1
PSComputerName :
CimClass : root/Microsoft/Windows/DNS:DnsServerResourceRecord
CimInstanceProperties : {DistinguishedName, HostName, RecordClass, RecordData...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties
DistinguishedName : DC=computer1,DC=mydomain.local,cn=MicrosoftDNS,DC=DomainDnsZones,dc=mydomain,dc=local
HostName : COMPUTER1
RecordClass : IN
RecordData : DnsServerResourceRecordA
RecordType : A
Timestamp :
TimeToLive : 01:00:00
Type : 1
PSComputerName :
CimClass : root/Microsoft/Windows/DNS:DnsServerResourceRecord
CimInstanceProperties : {DistinguishedName, HostName, RecordClass, RecordData...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties
I'm so confused at why Powershell is showing this and where it's actually pulling it from. I cannot locate those FQDN objects using native LDAP tools, even ADFind.
Is this some weird artifact/bug of the Powershell DNS cmdlets? Or does DNS records store dual entries for a given host, but only display one using native tools?
Neither make sense to me, as I would not expect a cmdlet to just make up DN values on the fly, and this doesn't occur for all host records.The latter does not seem possible as this is not occurring for all records in the zone. I have about 100 more records without the fqdn than with (10926 vs 10824).
EDIT If it helps, here is an ADFind query for the same object (and wildcard).
C:\temp>adfind -h dnsserver1 -domaindns -f "(&(name=computer1*))" name
AdFind V01.57.00cpp Joe Richards (support#joeware.net) November 2021
Using server: dnsserver1.mydomain.local:389
Directory: Windows Server 2016
Base DN: DC=DomainDnsZones,DC=ad,DC=ewsad,DC=net
dn:DC=computer1,DC=mydomain.local,CN=MicrosoftDNS,DC=DomainDnsZones,DC=mydomain,DC=local
>name: computer1
1 Objects returned
I can confirm this behavior.
In powershell, this returns 2 results for many of the computers (maybe all, I didn't check)
Get-DnsServerResourceRecord -ZoneName 'domain.com' -RRType A -ComputerName dnserver1 | where hostname -like Computer1*
DistinguishedName : DC=Computer1.domain.com,DC=domain.com,cn=MicrosoftDNS,DC=DomainDnsZones,DC=domain,DC=com
HostName : Computer1.domain.com
RecordClass : IN
RecordData : DnsServerResourceRecordA
RecordType : A
Timestamp : 12/8/2022 9:00:00 AM
TimeToLive : 00:20:00
Type : 1
PSComputerName :
CimClass : root/Microsoft/Windows/DNS:DnsServerResourceRecord
CimInstanceProperties : {DistinguishedName, HostName, RecordClass, RecordData...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties
DistinguishedName : DC=Computer1,DC=domain.com,cn=MicrosoftDNS,DC=DomainDnsZones,DC=domain,DC=com
HostName : Computer1
RecordClass : IN
RecordData : DnsServerResourceRecordA
RecordType : A
Timestamp : 12/8/2022 9:00:00 AM
TimeToLive : 00:20:00
Type : 1
PSComputerName :
CimClass : root/Microsoft/Windows/DNS:DnsServerResourceRecord
CimInstanceProperties : {DistinguishedName, HostName, RecordClass, RecordData...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties
But a dsquery results in one record.
dsquery computer -name computer1* -s dnsserver1
"CN=Computer1,OU=Computers,DC=domain,DC=com"
You can confirm only one of these is a real AD object.
$recordlist = Get-DnsServerResourceRecord -ZoneName 'domain.com' -RRType A -ComputerName dnserver1 | where hostname -like Computer1*
foreach($record in $recordlist){
Write-Host "Checking DN $($record.DistinguishedName)" -ForegroundColor Cyan
$found = $record.DistinguishedName |
Get-ADObject -ErrorAction SilentlyContinue
if($found){
Write-Host "Record found in AD" -ForegroundColor Green
}
else{
Write-Host "Record not in AD" -ForegroundColor DarkGray
}
}
So I must conclude thus far the evidence does indicate the Get-DnsServerResourceRecord is adding a duplicated record with the FQDN as well. Hopefully someone can find or knows why it was implemented in this manner.

PowerShell find firewall rule by port

What I want to do
I want to list all firewall rules involving some ports and list their display name but the only way I found for now displays only the port part and has no idea what the display name is.
First the basics
If we call Show-NetFirewallRule without argument, it lists all rules and each is formatted like that (notice DisplayName that is on "root" and LocalPort that is under Get-NetFirewallPortFilter):
Name : {96022E5F-666B-4E9E-8BD4-040498CEF1F5}
DisplayName : Google Chrome (mDNS-In)
Description : Inbound rule for Google Chrome to allow mDNS traffic.
DisplayGroup : Google Chrome
Group : Google Chrome
Enabled : True
Profile : Any
Platform :
Direction : Inbound
Action : Allow
EdgeTraversalPolicy : Block
LooseSourceMapping : False
LocalOnlyMapping : False
Owner :
PrimaryStatus : OK
Status : The rule was parsed successfully from the store. (65536)
EnforcementStatus : NotApplicable
PolicyStoreSource : PersistentStore
PolicyStoreSourceType : Local
RemoteDynamicKeywordAddresses :
$_ | Get-NetFirewallAddressFilter
LocalAddress : Any
RemoteAddress : Any
$_ | Get-NetFirewallServiceFilter
Service : Any
$_ | Get-NetFirewallApplicationFilter
Program : C:\Program Files\Google\Chrome\Application\chrome.exe
Package :
$_ | Get-NetFirewallInterfaceFilter
InterfaceAlias : Any
$_ | Get-NetFirewallInterfaceTypeFilter
InterfaceType : Any
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
$_ | Get-NetFirewallSecurityFilter
Authentication : NotRequired
Encryption : NotRequired
OverrideBlockRules : False
LocalUser : Any
RemoteUser : Any
RemoteMachine : Any
What I tried
The closer, I think, is
Show-NetFirewallRule | where {$_.LocalPort -eq "5353" -or $_.LocalPort -eq "5354"}
But it returns only Get-NetFirewallPortFilter part as said above:
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
$_ | Get-NetFirewallPortFilter
Protocol : UDP
LocalPort : 5353
RemotePort : Any
IcmpType : Any
DynamicTarget : Any
On same basis I tried:
Get-NetFirewallRule | where { $_.Get-NetFirewallPortFilter.LocalPort -Eq "5353" }
that displays a parse error, and all
Get-NetFirewallRule | where { $_.NetFirewallPortFilter.LocalPort -Eq "5353" }
Get-NetFirewallRule | where { ($_ | Get-NetFirewallAddressFilter).LocalPort -Eq "5353" }
Get-NetFirewallRule | where { ($_ | Get-NetFirewallAddressFilter).$_.LocalPort -Eq "5353" }
That gives no result.
Based on https://itluke.online/2018/11/27/how-to-display-firewall-rule-ports-with-powershell/, I tried:
Get-NetFirewallRule |
Format-Table -Property Name,
DisplayName,
DisplayGroup,
#{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}},
#{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}},
#{Name='RemotePort';Expression={($PSItem | Get-NetFirewallPortFilter).RemotePort}},
#{Name='RemoteAddress';Expression={($PSItem | Get-NetFirewallAddressFilter).RemoteAddress}} | where {$PSItem.LocalPort -eq "5353"}
But it seems doing nothing, and when I call it without the | where ... it is very slow, displaying approximatively 1 line per second. Note I tried also $_.LocalPort -eq "5353" and $_ -like "5353" in where.
I also tried
Get-NetFirewallRule | Get-NetFirewallPortFilter | Where-Object -Property { $_.LocalPort -Eq "5353" }
But is returns nothing (and is also very slow).
Workaround
For now I use a dirty "workaround", I call Show-NetFirewallRule > NetFirewallRule.txt and search manually in file, but I would like to have a script that does this automatically for me (and that is not very slow, since some commands that seems close to the answer are very slow).
The question
Anybody knows if/how can I achieve that ?
Thanks !
I believe you want to start with Get-NetFirewallPortFIlter, filter the results, and pass them to Get-NetFirewallRule. That should be much faster than looping on all results of Get-NetFirewallRule and testing each yourself.
Example (indented for readability, but can be a one-liner, of course):
Get-NetFirewallPortFilter |
Where-Object { $_.LocalPort -eq 5353 } |
Get-NetFirewallRule
Searched 717 rules and an equivalent 717 port filters in 1.2 seconds with 6 results.
If you'd like to show the port information alongside each rule, something like (this may or might not be optimal, but ...):
Get-NetFirewallPortFilter |
Where-Object { $_.LocalPort -eq 5353 } |
ForEach-Object {
"----"
"Rule"
"----"
$_ | Get-NetFirewallRule
"-----------"
"Port Filter"
"-----------"
$_
}
With the above, you'll still be looping over the filtered results rather than the entire set of rules.
This is what works for me:
Get-NetFirewallRule |Select-Object -First 20 -PipelineVariable Rule |
Get-NetFirewallPortFilter |Where-Object LocalPort -in 'RPCEPMap', 'Any' |
ForEach-Object { [pscustomobject]#{ name = $Rule.DisplayName; port = $_.LocalPort } }
But there are two tricky things here to deal with:
The common parameter -PipelineVariable is limited (see the information in the description along with the Note and the Caution) which I assume covers the reason why you can't remove the |Select-Object -First 20 part and place the -PipelineVariable Rule directly on the Get-NetFirewallRule cmdlet (but I don't fully understand the implication myself)
The Get-NetFirewallPortFilter cmdlet requires a CimInstance rather than e.g. a usual (PS)Object. This presumable explains why you can't replace the |Select-Object -First 20 with |Select-Object * know that former command actually places a reference to object output by Get-NetFirewallRule. See: Select-Object -First affects prior cmdlet in the pipeline
Update
as there appears to be a bug: "after some tests, it started to return always same name, of a "random" rule not involving port(s) I am searching for"
This is probably because the CimInstances run asynchronously and the refences in the -PipelineVariable are probably being overwritten (even with NetFirewallRule -ThrottleLimit 1 -OutBuffer 1). This means that this probably can't piped correctly.
Anyways, this (doing a filter on each specific rule instance) also appears to work for me:
Get-NetFirewallRule |ForEach-Object {
$Ports = $_ |Get-NetFirewallPortFilter |Where-Object LocalPort -in 'RPCEPMap', 'Any'
if ($Ports) { $_ |Select-Object DisplayName, #{n='LocalPort';e={$Ports.LocalPort} } }
}
Trying to parse something like "1000-2000" in localport. This fails with multiple false outcomes in the same rule.
$target = 8555
get-netfirewallportfilter |
? { $_.localport -match '-' } |
? { $_.localport | foreach { if ($_ -match '-') { $beg,$end = $_ -split '-';
[int]$beg -le $target -and [int]$end -ge $target }}} |
select instanceid,#{n='localport';e={"$($_.localport)"}}
instanceid localport
---------- ---------
NVS-FrameServer-In-TCP-NoScope 554 8554-8558
{E7D045E7-643F-4A91-94FF-63518836FA72} 5353 7200-17210 8889
{9823D038-1960-4767-9290-B36AA995FBB3} 5000 7000 7100 50000 7200-17210 8888
{123BF547-E50B-4A9D-A9E7-0FAE15D9C665} 7200-17210
IIS-WebServerRole-FTP-Passive-In-TCP 1024-65535
{25931D39-0705-4E63-A10C-E5F16BD17E0A} 7200-17210
{D6E50A26-B3A7-4683-A9FC-8485ED2B38BA} 5000 7000 7100 50000 7200-17210 8888
{B88115EB-F6B6-48D2-B194-723414C249B5} 5353 7200-17210 8889

Select-Object Cmdlet Returns Different Formatted Results for Get-NetIPConfiguration (different type)

I was trying to get the IP config details for my physical network adapter, while excluding all virtual network adapter. My script is as below:
$NetAdaptIndex = Get-NetAdapter -Physical | Select -Property InterfaceIndex -ExpandProperty InterfaceIndex
## Get Ip address, Gateway and DNS details as per configuration
$IPAddressConfig = foreach ($II in $NetAdaptIndex) {
Write-Host $II -ForegroundColor Yellow
Get-NetIPConfiguration |
Where-Object { $_.InterfaceIndex -eq $II} |
Select-Object InterfaceAlias, InterfaceDescription, InterfaceIndex, Ipv4Address, IPv4DefaultGateway, DNSServer
}
When I call the variable, I get the following results where the IPv4Address, IPv4DefaultGateway, and DNSServer are not returned in a string format.
PS C:\WINDOWS\system32> $IPAddressConfig
InterfaceAlias : WiFi 2
InterfaceDescription : D-Link DWA-171 Wireless AC Dual Band Adapter
InterfaceIndex : 46
IPv4Address : {192.168.0.103}
IPv4DefaultGateway : {MSFT_NetRoute (InstanceID = ":8:8:8:9:55?#55;C?8;#B8:8;55;")}
DNSServer : {MSFT_DNSClientServerAddress (Name = "46", CreationClassName = "", SystemCreationClassName = "", SystemName = "23"), MSFT_DNSClientServerAddress (Name = "46", CreationClassName = "", SystemCreationClassName = "", SystemName = "2")}
InterfaceAlias : Ethernet
InterfaceDescription : Broadcom NetLink (TM) Gigabit Ethernet
InterfaceIndex : 10
IPv4Address : {169.254.149.208}
IPv4DefaultGateway :
DNSServer : {MSFT_DNSClientServerAddress (Name = "10", CreationClassName = "", SystemCreationClassName = "", SystemName = "23"), MSFT_DNSClientServerAddress (Name = "10", CreationClassName = "", SystemCreationClassName = "", SystemName = "2")}
But if I were to manually remove the Select-Object code, it returns a correctly formatted results.
Get-NetIPConfiguration |
Where-Object { $_.InterfaceIndex -eq 46}
Observe how the IPv4Address, IPv4DefaultGateway, and DNSServer has returned the correctly formatted result.
InterfaceAlias : WiFi 2
InterfaceIndex : 46
InterfaceDescription : D-Link DWA-171 Wireless AC Dual Band Adapter
NetProfile.Name : <removed>
IPv6Address : <removed>
IPv4Address : 192.168.0.103
IPv6DefaultGateway : <removed>
IPv4DefaultGateway : 192.168.0.1
DNSServer : 2001:f40:0:3::12:68
2001:4860:4860::8888
1.1.1.1
8.8.8.8
My question is why is this happening? And is there any method that I can use to convert them to the correct format? The latter format are the one that I want.
Everything in the PowerShell is an object. The objects can get quite complex with multiple nested properties.
PS > (Get-NetIPConfiguration | Select-Object DNSServer)[0]
DNSServer
---------
{MSFT_DNSClientServerAddress (Name = "11", CreationClassName = "", SystemCreationClassName = "", SystemName = "23"), MSFT_DNSClientServerAddress (Name = "11", CreationClassName = "", Syste...
PS > (Get-NetIPConfiguration | Select-Object -ExpandProperty DNSServer)[0]
InterfaceAlias Interface Address ServerAddresses
Index Family
-------------- --------- ------- ---------------
LAN 11 IPv6 {}
To make your life easier, PowerShell formats objects when they're displayed on screen. Formatting rules are stored in the xml files: Formatting File Overview. For the NetTCPIP module, the file would be C:\Windows\System32\WindowsPowerShell\v1.0\Modules\NetTCPIP\Tcpip.Format.ps1xml. Here is the DNSServer item formatting code:
<ListItem>
<Label>DNSServer</Label>
<ItemSelectionCondition>
<ScriptBlock>
($_.DNSServer.Count -ne 0) -and
(($_.NetIPv4Interface.ConnectionState -eq "Connected") -or
($_.NetIPv6Interface.ConnectionState -eq "Connected"))
</ScriptBlock>
</ItemSelectionCondition>
<ScriptBlock>
$output = "";
foreach($Server in $_.DNSServer) {
foreach($Address in $Server.ServerAddresses) {
$output += $Address + "`n";
}
};
$output.Trim("`n");
</ScriptBlock>
</ListItem>
What formatting gets applied is controlled by the PSTypeNames property which exists on every object:
PS > (Get-NetIPConfiguration)[0].PSTypeNames
NetIPConfiguration
System.Object
When you use Select-Object, it modifies that property, so the resulting object loses its formatting:
PS > (Get-NetIPConfiguration | Select-Object DNSServer)[0].PSTypeNames
Selected.NetIPConfiguration
System.Management.Automation.PSCustomObject
System.Object
Alas, simply setting it back wouldn't work (object doesn't have correct structure for this), but you can emulate it by using calculated property:
Get-NetIPConfiguration | Select-Object InterfaceAlias, InterfaceDescription, InterfaceIndex, Ipv4Address, IPv4DefaultGateway, #{ n='DNSServer' ; e={$_.DNSServer.ServerAddresses -join "`n"}}
This will squash DNSServer to string, so you wouldn't be able to reuse it properly later, though. Perhaps, just outputting ServerAddresses collection would be more convenient and it would look the same:
Get-NetIPConfiguration | Select-Object InterfaceAlias, InterfaceDescription, InterfaceIndex, Ipv4Address, IPv4DefaultGateway, #{ n='DNSServer' ; e={#($_.DNSServer.ServerAddresses)}}
I've omitted to include that I'm piping the whole output to a ConvertTo-HTML cmdlet as not to make the question goes out of scope. But since I'm converting the output to HTML, it means that there is more than 1 way to skin the cat. I do not need to force the DNSServer object to be changed back to its previous formatting.
So, instead of joining the DNSServer with a ', ', I've joined it with a <br> tag instead.
Select-Object InterfaceAlias, InterfaceDescription, InterfaceIndex, #{n='IPv4 Address';e={$_.IPv4Address.IPAddress}}, #{n='IPv4 Default Gateway';e={$_.IPv4DefaultGateway.NextHop}}, #{n='DNS Server';e={$_.DNSServer.ServerAddresses -split " " -join "<br>"}}
Since ConvertTo-HTML translated the <> symbol to < and > respectively, I've added the following code to translate < and > back to <>.
$IPAddressConfigTemp = $IPAddressConfig | ConvertTo-Html -fragment -As List -PreContent "<h2>IP Address Configuration Details</h2>"
$IPAddressConfigHTML = $IPAddressConfigTemp -replace "<", "<" -replace ">", ">" -replace "'", "'"
The partial result of the code looks somewhat like this:
<table>
<tr><td>DNS Server:</td><td>2001:f40:0:3::12:68<br>2001:4860:4860::8888<br>1.1.1.1<br>8.8.8.8</td></tr>
</table>
It's not the most elegant solution, but it at least fits into what I would like to achieve. So, since I'm using calculated property to reach the final solution, I've selected #beatcracker's reply as the correct answer. It helps that his answer answered the whys and helped me to learn further.
Using Select-Object with the -Property parameter results in a new object with a new type (Selected.NetIPConfiguration, pipe to Get-Member to see this).
Formatting in PowerShell is based on types, so the formatting is seeing the new type and not applying the formatting from the old type.
You could conceivably apply a new typename (using the PSTypeNames property), and copy the formatting instructions from the old typename (NetIPConfiguration) to the new one.
Note that the difference in formatting doesn't imply any difference in the property values, it's purely cosmetic.

Filter for the last loopback adapter in powershell

I'm writing/editing/hacking a powershell script to add loopback adapters.
Once I've added the new loopback adapter, I need to get a handle on it. I currently do this:
$nic = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "Description='Microsoft Loopback Adapter'"
But this only works if there aren't currently any loopback adapters. If I already have one, then add another, then this will return the first one. What I want is the last (or most recent) one in this list I want to get back the "Microsoft Loopback adapter #2", the time after I want "Microsoft Loopback adapter #3", etc...
DHCPEnabled : False
IPAddress : {192.168.1.90}
ServiceName : msloop
Description : Microsoft Loopback Adapter
Index : 17
DHCPEnabled : True
IPAddress : {169.254.115.94, fe80::bc90:a8ba:b435:735e}
DefaultIPGateway :
DNSDomain :
ServiceName : msloop
Description : Microsoft Loopback Adapter #2
Index : 18
Is this possible in powershell at all?
Based on your result, I find that filtering on the ServiceName would be more reliable:
Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "ServiceName='msloop'" |
Sort-Object Index |
Select-Object -Last 1
Try something like this:
Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "Description='Microsoft Loopback Adapter'" | Sort-Object Index -descending | Select-Object -first 1
Get all instances where Description is 'Microsoft Loopback Adapter', sort them by Index value descending and select the top one.

Resolving IP Address from hostname with PowerShell

I am trying to get the ipaddress from a hostname using Powershell, but I really can't figure out how.
Any help?
You can get all the IP addresses with GetHostAddresses like this:
$ips = [System.Net.Dns]::GetHostAddresses("yourhosthere")
You can iterate over them like so:
[System.Net.Dns]::GetHostAddresses("yourhosthere") | foreach {echo $_.IPAddressToString }
A server may have more than one IP, so this will return an array of IPs.
this is nice and simple and gets all the nodes.
$ip = Resolve-DNSName google.com
$ip
also try inputting an ip instead of a domain name and check out those results too!
Use Resolve-DnsName cmdlet.
Resolve-DnsName computername | FT Name, IPAddress -HideTableHeaders | Out-File -Append c:\filename.txt
PS C:\> Resolve-DnsName stackoverflow.com
Name Type TTL Section IPAddress
---- ---- --- ------- ---------
stackoverflow.com A 130 Answer 151.101.65.69
stackoverflow.com A 130 Answer 151.101.129.69
stackoverflow.com A 130 Answer 151.101.193.69
stackoverflow.com A 130 Answer 151.101.1.69
PS C:\> Resolve-DnsName stackoverflow.com | Format-Table Name, IPAddress -HideTableHeaders
stackoverflow.com 151.101.65.69
stackoverflow.com 151.101.1.69
stackoverflow.com 151.101.193.69
stackoverflow.com 151.101.129.69
PS C:\> Resolve-DnsName -Type A google.com
Name Type TTL Section IPAddress
---- ---- --- ------- ---------
google.com A 16 Answer 216.58.193.78
PS C:\> Resolve-DnsName -Type AAAA google.com
Name Type TTL Section IPAddress
---- ---- --- ------- ---------
google.com AAAA 223 Answer 2607:f8b0:400e:c04::64
You could use vcsjones's solution, but this might cause problems with further ping/tracert commands, since the result is an array of addresses and you need only one.
To select the proper address, Send an ICMP echo request and read the Address property of the echo reply:
$ping = New-Object System.Net.NetworkInformation.Ping
$ip = $($ping.Send("yourhosthere").Address).IPAddressToString
Though the remarks from the documentation say:
The Address returned by any of the Send overloads can originate from a malicious remote computer. Do not connect to the remote computer using this address. Use DNS to determine the IP address of the machine to which you want to connect.
Working one liner if you want a single result from the collection:
$ipAddy = [System.Net.Dns]::GetHostAddresses("yahoo.com")[0].IPAddressToString;
hth
If you know part of the subnet (i.e. 10.3 in this example), then this will grab any addresses that are in the given subnet:
PS C:\> [System.Net.Dns]::GetHostAddresses("MyPC") | foreach { $_.IPAddressToString | findstr "10.3."}
This worked well for my purpose
$ping = ping -4 $env:COMPUTERNAME
$ip = $ping.Item(2)
$ip = $ip.Substring(11,11)
$computername = $env:computername
[System.Net.Dns]::GetHostAddresses($computername) | where {$_.AddressFamily -notlike "InterNetworkV6"} | foreach {echo $_.IPAddressToString }
The Test-Connection command seems to be a useful alternative, and it can either provide either a Win32_PingStatus object, or a boolean value.
Documentation:
https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.management/test-connection
You can use this code if you have a bunch of hosts in text file
$a = get-content "C:\Users\host.txt"(file path)
foreach ($i in $a )
{
$i + "`n" + "==========================";[System.Net.Dns]::GetHostAddresses($i)
}
The simplest way:
ping hostname
e.g.
ping dynlab938.meng.auth.gr
it will print:
Pinging dynlab938.meng.auth.gr [155.207.29.38] with 32 bytes of data
try
$address = 'HOST NAME'
Resolve-DnsName $address | Select-Object Name, IPAddress | Export-csv "C:\Temp\CompleteNSLookup.csv" -append -NoType