Resolving IP Address from hostname with PowerShell - 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

Related

Import a CSV, run port connection, then export to new csv

I have a Sources.csv which has columns "Source," "Host" and "Port" (Source is just the name of the device I'm trying to connect to). My goal is to go line-by-line through this CSV, run a connection test to the IP and Port, then export to a new csv file to include these same columns as well as a new column "Reachable." This is what I have so far, but my csv file is filling up with all sorts of information that doesn't seem to make sense... So I'm curious if anyone can point me in the right direction:
$path = '.\Sources.csv'
$csv = Import-Csv -Path $path
Foreach($line in $csv){
$TCPTest = Test-NetConnection $line.host -Port $line.port
$Test = #{DataSource=$line.source; IP=$line.host; Port=$line.port;
Reachable=$TCPTest.TcpTestSucceeded}
$Test | Export-Csv -Path .\SourceChecks.csv -append
}
Santango's answer works all the way back to PowerShell version 1 (I think).
If you can accept a dependency on PowerShell Version 3 (released in 2012), there is another option:
$sourcesPath = '.\Sources.csv'
$sources = Import-Csv $sourcesPath
$sources | ForEach {
$reachable = Test-NetConnection $_.host -Port $_.port -InformationLevel Quiet
[PSCustomObject]#{
Source = $_.Source
Host = $_.Host
Port = $_.Port
Reachable = $reachable
}
} |
Export-Csv newpathtocsv.csv
You can handle this using calculated properties with Select-Object:
$path = '.\Sources.csv'
Import-Csv -Path $path | Select-Object *, #{
Name = 'Reachable'
Expression = {Test-NetConnection $_.Host -Port $_.Port -InformationLevel Quiet}
} | Export-Csv newpathtocsv.csv -NoTypeInformation
Using -InformationLevel Quiet on Test-NetConnection so the cmdlet returns a boolean:
If you set this parameter to Quiet, the cmdlet returns basic information. For example, for a ping test, this cmdlet returns a Boolean value that indicates whether the attempt to ping a host or port is successful.
You can also add -WarningAction Ignore if you wish to not see the warning messages displayed to the console.
It's worth noting that Test-NetConnection is quite slow if you have many target hosts and ports to test connectivity. If you're looking to speed up this process you can give this function a try. It leverages the async capabilities from the .NET TcpClient Class.
An example, using the following CSV as input:
Host,Port
google.com,80
google.com,8080
cisco.com,80
cisco.com,443
amazon.com,80
amazon.com,389
amazon.com,636
Output would become:
PS /> Import-Csv $path | Test-TCPConnectionAsync -TimeOut 10
Source Destionation Port Success
------ ------------ ---- -------
sourceComputerName google.com 80 True
sourceComputerName cisco.com 443 True
sourceComputerName cisco.com 80 True
sourceComputerName amazon.com 80 True
sourceComputerName google.com 8080 False
sourceComputerName amazon.com 389 False
sourceComputerName amazon.com 636 False

How to Expand a property in a variable

if I go
$c = Resolve-DnsName facebook.com -Type TXT -Server '8.8.8.8'
When I enter $c I get
Name Type TTL Section Strings
---- ---- --- ------- -------
facebook.com TXT 7200 Answer {v=spf1 redirect=_spf.facebook.com}
facebook.com TXT 7200 Answer {google-site-verification=A2WZWCNQHrGV_TW
wKh6KHY90tY0SHZo_RnyMJoDaG0s}
facebook.com TXT 7200 Answer {google-site-verification=wdH5DTJTc9AYNwV
unSVFeK0hYDGUIEOGb-RReU6pJlY}
How do I expand $c.strings ?
I know I can get the expanded strings and lose the rest with
Resolve-DnsName facebook.com -Type TXT -Server '8.8.8.8' | Select-Object -ExpandProperty strings
How do I get the entire answer expanded ?
You can use a calculated property to redefine the Strings property from string[] to string:
Resolve-DnsName google.com -Type TXT -Server '8.8.8.8' |
Select-Object Name, Type, TTL, Section, #{ N = 'Strings'; E = { [string] $_.Strings }} |
Format-Table
This would result in:
Name Type TTL Section Strings
---- ---- --- ------- -------
google.com TXT 3600 Answer docusign=05958488-....
google.com TXT 3600 Answer google-site-verifi....
google.com TXT 3600 Answer docusign=1b0a6754-....
google.com TXT 3600 Answer google-site-verifi....
google.com TXT 3600 Answer globalsign-smime-d....
google.com TXT 3600 Answer MS=E4A68B9AB2BB967....
google.com TXT 3600 Answer apple-domain-verif....
google.com TXT 3600 Answer v=spf1 include:_sp....
google.com TXT 3600 Answer facebook-domain-ve....
If there where more than one string in the Strings property, using above code would join the strings with $OFS (Out Field Separator), by default a space:
Name Type TTL Section Strings
---- ---- --- ------- -------
google.com TXT 3339 Answer docusign=4752-4e... docusign=4752-4e...
If you want a multi-line string instead, you could use Out-String, however that would require first to .Trim() the output and also use -Wrap on Format-Table to be displayed correctly.
An example of how the code would look like using a hardcoded value (docusign=05958488):
Resolve-DnsName google.com -Type TXT -Server '8.8.8.8' |
Select-Object Name, Type, TTL, Section, #{
Name = 'Strings'
Expression = { ('docusign=05958488', 'docusign=05958488' | Out-String).Trim() }
} | Format-Table -Wrap
You could also use the -join operator to concatenate the strings with a CRLF (`r`n) to get a multi-line string:
Resolve-DnsName google.com -Type TXT -Server '8.8.8.8' |
Select-Object Name, Type, TTL, Section, #{
Name = 'Strings'
Expression = { 'docusign=05958488', 'docusign=05958488' -join "`r`n" }
} | Format-Table -Wrap
Both examples result in:
Name Type TTL Section Strings
---- ---- --- ------- -------
google.com TXT 3574 Answer docusign=05958488
docusign=05958488
google.com TXT 3574 Answer docusign=05958488
docusign=05958488
google.com TXT 3574 Answer docusign=05958488
docusign=05958488
If you want a solution that could handle both cases, Strings having only one value and Strings having multiple values, you could use something like this:
$result = Resolve-DnsName google.com -Type TXT -Server '8.8.8.8'
# Add random values to Strings for testing
$result.ForEach({ $_.Strings += Get-Random })
# Code logic
$result = foreach($element in $result) {
$out = [ordered]#{
Name = $element.Name
Type = $element.Type
TTL = $element.TTL
Section = $element.Section
}
foreach($e in $element.Strings) {
$out.Strings = $e
# output one object per string
[pscustomobject] $out
}
}
$result | Format-Table
Above logic would be creating a new object per element in the Strings property. The output would be:
TTL Section Name Type Strings
--- ------- ---- ---- -------
3444 Answer google.com TXT apple-domain-verificatio...
3444 Answer google.com TXT 1419241945
3444 Answer google.com TXT MS=E4A68B9AB2BB9670BCE15...
3444 Answer google.com TXT 463070462
3444 Answer google.com TXT facebook-domain-verifica...
3444 Answer google.com TXT 958788674
3444 Answer google.com TXT google-site-verification...
3444 Answer google.com TXT 1623605637

how to format Powershell output in specific way?

I need to scan my network for specific processes on servers. I've done this script:
28..31 | ForEach-Object { Get-Process -ComputerName "192.168.0.$_" -Name svc* }
Now how can I format output so it shows on which IP address found process shown? Thank you.
I suggest switching to PowerShell's remoting, because:
it provides a framework for executing any command remotely - rather than relying on individual cmdlets to support a -ComputerName parameter and uses a firewall-friendly transport.
it will continue to be supported in PowerShell [Core] v6+, where the cmdlet-individual -ComputerName parameters aren't supported anymore; this obsolete remoting method uses an older, less firewall-friendly form of remoting that the - obsolete since v3 - WMI cmdlets also use (the latter were replaced by the CIM cmdlets).
It is therefore better to consistently use the firewall-friendly PowerShell remoting with its generic remoting commands (Invoke-Command, Enter-PSSession, ...).
If you use Invoke-Command to target (multiple) remote computers, the objects returned automatically contain and display the name of the originating computer, via the automatically added .PSComputerName property:
# Create the array of IP addresses to target:
$ips = 28..31 -replace '^', '192.168.0.'
# Use a *single* Invoke-Command call to target *all* computers at once.
# Note: The results will typically *not* reflect the input order of
# given IPs / computer names.
Invoke-Command -ComputerName $ips { Get-Process -Name svc* }
You'll see output such as the following - note the PSComputerName column:
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName PSComputerName
------- ------ ----- ----- ------ -- -- ----------- --------------
1013 18 7464 13732 52.72 8 0 svchost 192.168.0.30
...
Note that you can suppress automatic display of the .PSComputerName property with Invoke-Command's -HideComputerName parameter.
However, the property is still available programmatically, which allows you to do the following:
Invoke-Command -ComputerName $ips { Get-Process -Name svc* } -HideComputerName |
Format-Table -GroupBy PSComputerName
This yields display output grouped by computer name / IP:
PSComputerName: 192.168.0.30
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
1013 18 7464 13732 52.72 8 0 svchost
...
PSComputerName: 192.168.0.28
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
1007 17 7112 12632 65.45 11 0 svchost
...
If you wanted to sort by IP address before grouping, you could insert | Sort-Object { [version] $_.PSComputerName }[1] before the Format-Table call.
For sorting by computer names, just
| Sort-Object PSComputerName would do.
[1] Casting to [version] is a trick to ensure proper sorting of IP addresses; IP address strings can be interpreted as [version] (System.Version) instances, and such instances are directly comparable, using the numeric values of the version components (first by .MajorVersion, then by .MinorVersion, ...)
here's one way to do the job. [grin] what it does ...
builds the ip final octet range
sets the IPv4 base octets
builds the list of processes to search for
sets the "no response" text
iterates thru the 4th octet range
builds the IPv4 address
checks to see if it is online/responding
if so, gets the hostname
for my version of PoSh [win7, ps5.1] the Get-Process cmdlet will NOT accept an ip address. a hostname is required.
corrects for the damaged hostname returned when one uses ATT for inet service
creates an ordered hashtable to use for building the property list
builds the various props as needed
converts the hashtable to a PSCustomObject
sends that to the $Results collection
shows it on screen
sends it to a CSV file
here's the code ...
$4thOctetRange = 64..66
$IpBase = '192.168.1'
$ProcessList = #(
'AutoHotKey'
'BetterNotBeThere'
'DisplayFusion'
'Foobar2000'
)
$NoResponse = '__n/a__'
$Results = foreach ($4OR_Item in $4thOctetRange)
{
$Ip = '{0}.{1}' -f $IpBase, $4OR_Item
$Online = Test-Connection -ComputerName $Ip -Count 1 -Quiet
if ($Online)
{
# getting the hostname is REQUIRED by my version of Get-Process
# it will not accept an IP address
# version info = win7, ps5.1
# this may need adjusting for your returned hostname
# mine shows Hostname.attlocal.net
# that is not valid with any query i make, so i removed all after the 1st dot
$HostName = ([System.Net.Dns]::GetHostByAddress($Ip)).HostName.Split('.')[0]
}
else
{
$HostName = $NoResponse
}
$TempProps = [ordered]#{}
$TempProps.Add('IpAddress', $Ip)
$TempProps.Add('Online', $Online)
$TempProps.Add('HostName', $HostName)
foreach ($PL_Item in $ProcessList)
{
if ($TempProps['Online'])
{
# if the process aint found, the "SilentlyContinue" forces a $Null
# the "[bool]" then coerces that to a "False"
$TempProps.Add($PL_Item, [bool](Get-Process -ComputerName $HostName -Name $PL_Item -ErrorAction SilentlyContinue))
}
else
{
$TempProps.Add($PL_Item, $NoResponse)
}
}
# send the object out to the $Results collection
[PSCustomObject]$TempProps
}
# send to screen
$Results
# send to CSV file
$Results |
Export-Csv -LiteralPath "$env:TEMP\Senator14_RemoteProcessFinder.csv" -NoTypeInformation
truncated screen output ...
IpAddress : 192.168.1.65
Online : True
HostName : ZK_01
AutoHotKey : True
BetterNotBeThere : False
DisplayFusion : True
Foobar2000 : True
IpAddress : 192.168.1.66
Online : False
HostName : __n/a__
AutoHotKey : __n/a__
BetterNotBeThere : __n/a__
DisplayFusion : __n/a__
Foobar2000 : __n/a__
csv file content ...
"IpAddress","Online","HostName","AutoHotKey","BetterNotBeThere","DisplayFusion","Foobar2000"
"192.168.1.64","False","__n/a__","__n/a__","__n/a__","__n/a__","__n/a__"
"192.168.1.65","True","ZK_01","True","False","True","True"
"192.168.1.66","False","__n/a__","__n/a__","__n/a__","__n/a__","__n/a__"

How to see the hostname when you ping the server?

I pinged the servers and it is working (it shows me the ip address that could be pinged) but I want it to show the hostname and the ip address.
I tried to incorporate [System.Net.Data.Dns]::GetHostName(), but I don't know where to put it. I am a beginner using PowerShell. I also tried to used -and, but it doesn't work.
I understand how to do it python I just don't know how to translate it to PowerShell.
$columnC = "n1-1mon-i3fp04","n1-1mon-i3fp06","n1-1mon-i3fp07","n1-r-1mon-i3fp09","n1-r-1mon-i3fp10","n1-1mon-i3fp08","n1-1mon-i3fp03","n1-1mon-i3fp02","n1-1mon-i3fp111"
$columnC | % $_ {$Device = Resolve-DnsName -Name $_
$Device.[System.Net.Data.Dns]::GetHostName()
if (test-connection $Device.("IPAddress")) {write-host Device.("IPAddress") "Ping succeeded." -foreground green}
else {write-host $Device.("IPAddress") "Ping failed." -foreground red}}
The result shows an error message like the syntax is wrong. I want it to show both ip address and the hostname.
[edit - Theo pointed out that GetHostByName has been deprecated in favor of GetHostEntry. when i tested that, it gave more consistent results, so i swapped them.]
this will get the ComputerName, HostName, and Online status. then save those into a custom object, send the object to the $Results collection, and - finally - show what is in the collection. [grin]
# fake reading in a text file
# in real life use Get-Content
$ComputerList = #'
BetterNotBeThere
LocalHost
10.0.0.1
127.0.0.1
'# -split [environment]::NewLine
$Results = foreach ($CL_Item in $ComputerList)
{
try
{
$HostName = [System.Net.Dns]::GetHostEntry($CL_Item).HostName
}
catch
{
$HostName = '__Not Found__'
}
[PSCustomObject]#{
ComputerName = $CL_Item
HostName = $HostName
Online = Test-Connection -ComputerName $CL_Item -Count 1 -Quiet
}
}
$Results
output ...
ComputerName HostName Online
------------ -------- ------
BetterNotBeThere __Not Found__ False
LocalHost [MySysName] True
10.0.0.1 __Not Found__ False
127.0.0.1 [MySysName] True

Powershell - Local Network scan (no domain)

Just wondering if anybody knows a way in powershell to scan the local network for Computers, resolving their name's and IP's.
I know a possibility with Get-ADComputer, but this network is not in a domain.
You can use the .net DNS class in powershell.
reference: http://msdn.microsoft.com/en-us/library/system.net.dns%28v=vs.110%29.aspx
example:
PS C:\> $dns = [system.net.dns]
PS C:\> $dns::GetHostEntry("198.252.206.16") | format-list
HostName : stackoverflow.com
Aliases : {}
AddressList : {198.252.206.16}
Scanning example if your network as a 192.168.1.0/24:
$results = #() ; 1..255 | % { $results += $dns::GetHostByAddress("192.168.1.$_") }