2015-01-20 4 views
1

У меня есть сценарий powershell, который выполняет некоторую команду на локальном или удаленном компьютере. Когда компьютер удален, команда вызывается через Invoke-Command, и пользователю предлагается ввести дополнительные учетные данные.Как проверить в Powershell, если IP-адрес или имя хоста является локальным хостом? Без домена DNS

Пользователь может ввести параметр сценария, который может быть: hostname, IP, 127.0.0.1, alias из файла hosts. Мне нужно проверить, является ли этот параметр для локальной или удаленной машины, чтобы вызвать локальную команду или Invoke-Command. я делал это так:

Function IsLocalhost { 
    Param([string] $srvname) 

    $script:AVLserverHost = $srvname.Split('\')[0] 
    #Write-Host ("HOST: " + $script:AVLserverHost) 

    if ((get-content env:computername) -eq $script:AVLserverHost) { 
     return $true; 
    } else { 
     $AddressList = @(([net.dns]::GetHostEntry($script:AVLserverHost)).AddressList) 
     $script:HostIp = $AddressList.IpAddressToString 

     $name = [System.Net.Dns]::gethostentry($script:HostIp) 
     if ((get-content env:computername) -eq $name.HostName) { 
      return $true 
     } 
    } 
    return $false 
} 

Но это работает только на домене DNS. Наши компьютеры находятся на рабочей группе или автономных компьютерах, которые мы можем подключать только по IP или псевдониму из файла hosts.

Так, как проверить в powershell (или код C#), если данный хост является локальным или нет, если хост не находится в домене DNS. Я бы хотел иметь true/false, если он локальный или нет, и его реальный IP-адрес, если было введено имя хоста или псевдоним хоста.

ответ

1

вы можете создать массив локальных IP-адресов, добавить localhost в массив и посмотреть, находится ли ваш параметр в массиве. вот ps2.0 совместимая версия для ipv4.

$LocalArray = @() 
$LocalArray += (gwmi Win32_NetworkAdapterConfiguration | ? {$_.IPAddress}) | select -expand ipaddress | select-string -notmatch ":" 
$LocalArray += 'localhost' 
$LocalArray += '127.0.0.1' 
$LocalArray += hostname 
$LocalArray -contains $IP 
+0

В IPv4 любой адрес из диапазон 127.0.0.0/8 (да, все 16 миллионов адресов) относится к localhost. –

+0

Спасибо за этот код, но он не охватывает все сценарии. На моем локальном хосте я могу редактировать файлы хостов следующим образом: 127.0.0.1 MyAlias1, 10.148.0.1 MyAlias2. Обе псевдонимы относятся к моему локальному хосту (10.148.0.1 - это мой фактический IP). Сценарий должен распознавать MyAlias1 и MyAlias2 как localhost. Может быть, скрипт мог читать файл hosts и расширять из него все псевдонимы, которые ссылаются на IP-адреса, которые уже находятся в $ LocalArray. – scar80

+0

Фактически $ LocalArray -contains $ IP не работает, потому что первые адреса, возвращаемые из gwmi, - это [Microsoft.PowerShell.Commands.MatchInfo ], и его нельзя сравнивать со строкой $ IP. Мне пришлось написать цикл foreach и преобразовать все элементы из $ LocalArray в строку. – scar80

0

совмещала @ код Ноева с другим примером того, как прочитать файл хостов и это окончательный код:

Function IsLocalhost { 
    Param([string] $srvname) 

    $script:AVLserverHost = $srvname.Split('\')[0] 

    #get list of localhost addresses 
    $localAddresses = @() 
    $localAddresses += (gwmi Win32_NetworkAdapterConfiguration | ? {$_.IPAddress}) | select -expand ipaddress | select-string -notmatch ":" 
    $localAddresses += 'localhost' 
    $localAddresses += '127.0.0.1' 
    $localAddresses += hostname 

    $hosts = "$env:windir\System32\drivers\etc\hosts" 

    [regex]$r="\S" #define a regex to return first NON-whitespace character 

    #strip out any lines beginning with # and blank lines 
    $HostsData = Get-Content $hosts | where { 
     (($r.Match($_)).value -ne "#") -and ($_ -notmatch "^\s+$") -and ($_.Length -gt 0) 
    } 

    $HostsData | foreach { 
     $_ -match "(?<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(?<HOSTNAME>\S+)" | Out-Null 
     $ip = $matches.ip 
     $hostname = $matches.hostname 

     if ($localAddresses -contains $ip) { 
      $localAddresses += $hostname 
     } 
    } 

    if ($localAddresses -contains $script:AVLserverHost) { 
     return $true; 
    } else { 
     $script:HostIp = (Test-Connection $script:AVLserverHost | Select-Object IPV4Address)[0].IPV4Address.IPAddressToString 
    } 
    return $false 
} 
1

Вы можете попробовать это:

function Is-LoopBackAddress([string] $Address) 
{ 
    $addressIPs = [Net.Dns]::GetHostAddresses($Address).IPAddressToString 

    $netInterfaces = [Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() 

    foreach ($netInterface in $netInterfaces) 
    { 
     $ipProperties = $netInterface.GetIPProperties() 

     foreach ($ip in $ipProperties.UnicastAddresses) 
     { 
      if ($addressIPs -contains $ip.Address.IPAddressToString) 
      { 
       return $true 
      } 
     } 
    } 

    return $false 
} 

Is-LoopBackAddress 'localhost' 
Смежные вопросы