Hi all so I’m just trying to brush up on some PS today as I for the second day in a row I haven’t been called into the field. Yay!
Here’s my idea, create a script that will ping IP’s and return hostname/ip/connection. Something simple to build on is what I’m looking to do. I’m probably going about it the wrong way but here’s what I have so far.
$list = 20..25 | foreach {"192.168.5.$_."} | Out-File C:\iplist.txt
$read = Get-Content C:\iplist.txt
$Dnsresult = Foreach ($R in $read)
{
[System.Net.Dns]::GetHostEntry($R)
}
$test = $read | foreach-object { Test-Connection -ComputerName $_ -Quiet -Count 1
$Object = [pscustomobject]@{"IP"=$read;"Connection"=$test;"Hostname"=$r}
}
$object
And this is the result I’m getting.
PS C:\Windows\system32> C:\PC\Scripts\ConnectTestTool.ps1
Exception calling "GetHostEntry" with "1" argument(s): "No such host is known"
At C:\PC\Scripts\ConnectTestTool.ps1:5 char:2
+ [System.Net.Dns]::GetHostEntry($R)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SocketException
Exception calling "GetHostEntry" with "1" argument(s): "No such host is known"
At C:\PC\Scripts\ConnectTestTool.ps1:5 char:2
+ [System.Net.Dns]::GetHostEntry($R)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SocketException
IP Connection Hostname
-- ---------- --------
{192.168.5.170, 192.168.5.171, 192.168.5.172} {False, True, False} 192.168.5.172
As for the DNS error I understand that I have to put a string in gethostentry. I ran it this way and it works. So how to add quotes around my variable? What method do I need to use for that?
PS C:\Windows\system32> [System.Net.Dns]::GetHostEntry("192.168.5.171")
HostName Aliases AddressList
-------- ------- -----------
Tech01.FQDN {} {192.168.5.171}
For as much as I’ve read here this is the same concept, and should be displaying nice and neat in one line after another. Is it because I’m using a hashtable for pscustomobject? Also I know I’m gonna get yelled at but I’m still on V.3 (not my choice) and I have to write my code to be basically compatible with V.2 Thanks for taking the time guys.
5 Spice ups
Add your entries to an arraylist
$array = New-object System.Collections.ArrayList
#stuffstuff
$array.add([pscustomobject]@{"IP"=$read;"Connection"=$test;"Hostname"=$r})
psophos
(M Boyle)
June 14, 2016, 7:18pm
3
Totally untested:
$list = 20..25 | foreach {
"192.168.5.$_."
} | Out-File C:\iplist.txt
$ipList = Get-Content C:\iplist.txt
foreach ($entry in $ipList) {
$dnsName = [System.Net.Dns]::GetHostEntry($entry)
if(Test-Connection -ComputerName $_ -Quiet -Count 1) {
$up = 'True'
} else {
$up = 'False'
}
$object = [pscustomobject]@{
"IP" = $entry
"Connection" = $up
"Hostname" = $dnsName
}
$object
}
It’s not a quote issue. It’s just the fact that your [System.Net.Dns]::Gethostentry() method does not find a valid dns entry for the IP you gave him. It throws an error.
You should put this part in a try / catch to avoid the error message.
If I could simplify the script a little bit:
$ipList = 20..25 | foreach {
"192.168.5.$_."
}
foreach ($entry in $ipList) {
Try {
$dnsName = [System.Net.Dns]::GetHostEntry($entry)
}
Catch {
$dnsName = "None"
}
[pscustomobject]@{
"IP" = $entry
"Connection" = Test-Connection -ComputerName $entry -Quiet -Count 1
"Hostname" = $dnsName
}
}
There’s no need to save the list to a file and then read it back in, so got rid of that. Added the Try/Catch as was suggested earlier and there’s no need to test “Test-Connection” for $true or $false only to return $true or $false, it already does that for you.
And if you really want to condense the code:
ForEach ($Octet in (20..25))
{
$Entry = "192.168.5.$Octet"
[PSCustomObject]@{
"IP" = $Entry
"Connection" = Test-Connection -ComputerName $Entry -Quiet -Count 1
"Hostname" = Try { [System.Net.Dns]::GetHostEntry($Entry) } Catch { "None" }
}
}
2 Spice ups
And if you really want to go nuts:
@(20..25) | Select @{Name="IP";Expression={ "192.168.5.$_" }},@{Name="Connection";Expression={ Test-Connection -ComputerName "192.168.5.$_" -Quiet -Count 1 }},@{Name="HostName";Expression={ Try { [System.Net.Dns]::GetHostEntry($Entry) } Catch { "None" } }}
2 Spice ups
Nicolas1847:
It’s not a quote issue. It’s just the fact that your [System.Net.Dns]::Gethostentry() method does not find a valid dns entry for the IP you gave him. It throws an error.
You should put this part in a try / catch to avoid the error message.
And I was thinking the same thing, but if you look at the third box using just the IP address as a string (unless I’m incorrect that “ThisIsAString” because it’s enclosed in double quotes) returns a hostname in that range. So I know one of them should return a hostname. Also sorry just noticed I changed the range from 20…25 to 170…172 while testing. So 171 should return tech01 as the host name.
Martin9700:
There’s no need to save the list to a file and then read it back in, so got rid of that. Added the Try/Catch as was suggested earlier and there’s no need to test “Test-Connection” for $true or $false only to return $true or $false, it already does that for you.
Actually I plan on turning this into a tool once I get the code to do what I want it to. BTW thanks for teaching me that Martin. So the list would serve eventually as a way to not have to keep entering the range. I’m thinking of having it save the file as the name of the site so it can be reused or something like that.
My actual question for this is more the how to get pscustomobject to display the way I want it to. Right now it pulls each object as a property which if I call the object.property I want it’s closer to what I’m trying to achieve. I hope that makes sense. I don’t understand the part about testing test-connection as I’m using the quiet parameter to return a Boolean value for that reason. And thanks for the suggestions I’ll use the try/catch for error handling.
Hmm. I’m afraid it doesn’t. Have you tried one of the other scripts? How does that output differ from what you’re looking for? Maybe you could post an example of the final results you’re looking for.
The article I linked to is what I’m basing my output on. Here’s a screenshot.
@martin9700
And how do any of the scripts above NOT giving you that? Are we just fundamentally not understanding what [PSCustomObject] is?
That has to be it. The first one you posted gives me the output. However it’s pulling system.net.iphostentry instead of the hostname. Please help me understand where my code is going wrong.
Ok, now I understand. So [System.Net.DNS]::GetEntry() returns an object with a few properties. The only one we care about is Hostname, so I’ve modified the code to get that. I’ve also added saving the IP back to a file with a little twist:
$ipList = 20..25 | ForEach { "192.168.5.$_" }
$ipListPath = Join-Path -Path (Split-Path $MyInvocation.MyCommand.Path) -ChildPath "ipList.txt"
$ipList | Out-File $ipListPath
ForEach ($IP in $ipList)
{
[PSCustomObject]@{
"IP" = $IP
"Connection" = Test-Connection -ComputerName $IP -Quiet -Count 1
"Hostname" = Try { [System.Net.Dns]::GetHostEntry($IP).HostName } Catch { "None" }
}
}
That whole “Join-Path” thing will create a path to ipList.txt in the same folder that you run the script from. No matter WHERE you run the script from. I hate hard coded paths