Exception calling “GetHostEntry” with “1” argument

2019-08-18 05:53发布

问题:

The FQDN for this machine:

thufir@dur:~$ 
thufir@dur:~$ hostname --fqdn
dur.bounceme.net
thufir@dur:~$ 

Yes...working directly with powershell gives the FQDN of dur.bounceme.net okay:

thufir@dur:~/powershell$ 
thufir@dur:~/powershell$ pwsh
PowerShell v6.0.1
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/pscore6-docs
Type 'help' to get help.

PS /home/thufir/powershell> 
PS /home/thufir/powershell> [System.Net.Dns]::GetHostByName((hostname)).HostName                                        
dur.bounceme.net
PS /home/thufir/powershell> 

but what if I want to iterate over an array? How do I get the FQDN to show as dur.bounceme.net?

thufir@dur:~/powershell$ 
thufir@dur:~/powershell$ ./hostname.ps1 
dur.bounceme.net
beginning loop
google.com
Exception calling "GetHostEntry" with "1" argument(s): "No such device or address"
At /home/thufir/powershell/hostname.ps1:14 char:3
+   $fqdn = [System.Net.Dns]::GetHostEntry($i).HostName
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ExtendedSocketException

google.com
localhost
end
thufir@dur:~/powershell$ 

script:

#!/usr/bin/pwsh -Command


#hostname is a reserved variable name?

[System.Net.Dns]::GetHostByName((hostname)).HostName


"beginning loop"

$hosts = ("google.com", "hostname", "localhost")

foreach($i in $hosts) {
  $fqdn = [System.Net.Dns]::GetHostEntry($i).HostName
  write-host $fqdn
}


"end"

I've tried removing quote marks from around hostname and prepending the dollar sign $. This is a reserved word?

Bonus points for explaining the terminology involved.

回答1:

You are using hostname as a string and that string is not in your hosts file, like localhost is, it will fail.

If you are after default localhost names, then they are:

'127.0.0.1'
$env:COMPUTERNAME
'localhost'

So, you shoud do this

$TargetHosts = ('stackoverflow.com','google.com', $env:COMPUTERNAME,'localhost','127.0.0.1')

foreach($TargetHost in $TargetHosts) 
{ ( $fqdn = [Net.Dns]::GetHostEntry($TargetHost).Hostname ) }

stackoverflow.com
google.com
WS01
WS01
WS01

See also this post about use the native Resolve-DnsName cmdlet vs the .NET libraries.

Why not just use the built-in DNS cmdlets? Or is there a particular reason you are traveling down the raw .Net path? Code project, homework assignment, curiosity?

powershell how to resolve name to IP address using Windows method



回答2:

It seems that there is confusion about what hostname does and what's the difference between a command and a string. Let's see the first part that works:

[System.Net.Dns]::GetHostByName((hostname)).HostName

Powershell parses this as

Run command hostname, 
Call GetHostByName(), pass hostname's output as a parameter to the call
from that result, show the HostName attribute

Whilst in the foreach loop, the parameters are passed as strings. Thus in the hostname case:

$i <-- hostname
[System.Net.Dns]::GetHostEntry($i).HostName

is being parsed as

Call GetHostEntry("hostname")
from that result, show the HostName attribute