Назад | Перейти на главную страницу

Поиск компьютеров в домене со статическими IP-адресами - PowerShell

позвольте мне начать с того, что я совсем не умею писать сценарии или устранять их, поэтому я здесь :)

Я пытаюсь найти все компьютеры в сети домена Windows, которые используют статические IP-адреса, я провел небольшое исследование в Интернете и обнаружил этот сценарий PowerShell это выглядит следующим образом:

param ( 
    [string]$LDAPFilter = '(name=*)', 
    [switch]$Verbose 
) 
Get-ADComputer -LDAPFilter $LDAPFilter | 
% ` 
{  
    $name = $_.DNSHostName; 
    if ($Verbose.IsPresent) 
      { Write-Host -ForegroundColor Yellow "Connecting to $name..." }  
    $ints = Get-WmiObject -ErrorAction SilentlyContinue -ComputerName $name ` 
      -Query "select IPAddress, DefaultIPGateway from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE and DHCPEnabled=FALSE"; 
    if ($ints -ne $null) 
        { 
            foreach ($int in $ints) 
            { 
                foreach ($addr in $int.IPAddress) 
                { 
                    $ip = $null 
                    if ($addr -match "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}") 
                    { 
                        $ip = $addr 
                        $gw = $null 
                        foreach ($gw_addr in $int.DefaultIPGateway) 
                        { 
                            if ($gw_addr -match "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}") 
                            { 
                                $gw = $gw_addr 
                                break 
                            } 
                        } 
                        if ($ip -ne $null) 
                        { 
                            $info = New-Object PSObject -Property ` 
                            @{ 
                                Name = $name 
                                IP = $ip 
                                Gateway = $gw 
                            } 
                            $info 
                            if ($Verbose.IsPresent) 
                                { Write-Host -ForegroundColor Yellow $info } 
                        } 
                    } 
                } 
            } 
        } 
} | 
Select-Object Name, IP, Gateway

Я попытался запустить это на своем сервере Active Directory, проблема в том, что скрипт выдает ошибку при выполнении, как показано ниже:

Missing expression after unary operator '-'.
At C:\Users\Administrator.MyDomain\Desktop\ComputersWithStaticIP.ps1:24 char:8
+       - <<<< Query "select IPAddress, DefaultIPGateway from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE an
d DHCPEnabled=FALSE";
    + CategoryInfo          : ParserError: (-:String) [], ParseException
    + FullyQualifiedErrorId : MissingExpressionAfterOperator

Я проследил свой способ удаления "-" из скрипта, а затем получил вместо этого следующую ошибку:

ForEach-Object : Cannot bind parameter 'Process'. Cannot convert the " " value
of type "System.String" to type "System.Management.Automation.ScriptBlock".
At C:\Users\Administrator.MyDomain\Desktop\ComputersWithStaticIP.ps1:18 char:2
+ % <<<<  `
    + CategoryInfo          : InvalidArgument: (:) [ForEach-Object], Parameter
   BindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerSh
   ell.Commands.ForEachObjectCommand

Что я делаю не так? или что мне добавить / убрать из скрипта, чтобы он запустился?

Спасибо,

Что я делаю не так?

Обратный апостроф `является символом продолжения строки, и первая ошибка, которую вы получаете 'пропущенное выражение после унарного оператора', похоже, заключается в том, что PowerShell не видит строку -Query как часть предыдущей строки.

Возможно, вам не хватает символа `в конце предыдущей строки в вашей копии скрипта, или он был заменен апострофом из-за какой-то причуды, связанной с искажением кода копирования / вставки / шрифта / редактора, или что-то в этом роде.

или что мне добавить / убрать из скрипта, чтобы он запустился?

Удалите большую часть этого, это запутанно, некрасиво и излишне для того, что вы хотите.

Почему он запрашивает Win32_NetworkAdapterConfiguration вещи и называя их ints? Это так вводящие в заблуждение.

Почему он принимает IPAddress, называя это addr, затем называя это ip, затем называя это IP?

Почему он принимает GatewayAddress, называя это gw_addr, затем gw, затем Gateway?

Тест на -eq $null кажется ненужным, если вы попытаетесь использовать foreach в пустой последовательности он будет работать должным образом (пропустите его).

Использование регулярных выражений для получения адресов IPv4 вместо адресов IPv6 - полезно, но бесполезно. IPv6-адреса используют : для их разграничения, а адреса IPv4 используют ., поэтому, если вам нужны только адреса IPv4, просто ищите . в адресе.

Зачем копировать адрес, составлять список результатов, а затем выбирать все из списка, когда можно просто распечатать адрес, как вы его нашли?

Вас вообще волнует адрес шлюза?

Зачем проверять, пуст ли IP-адрес, когда вы находитесь в блоке, обрабатывающем IP-адрес в этот момент, чтобы он не мог быть нулевым в этот момент?

Почему вся эта цепочка использует get-computers % { code } | select results, когда это тебе не поможет?

Я немного сократил его, переименовал и получил следующую более четкую и простую структуру:

  1. Настроить.
  2. Получите компьютеры
  3. Для каждого компьютера получите сетевые интерфейсы со статическими адресами.
  4. Для каждого интерфейса получите IP-адреса.
  5. Для каждого IP-адреса определите IPv4-адреса, выполнив поиск .
  6. Отобразите имя компьютера и этот IPv4-адрес.

    param ( 
    [string]$LDAPFilter = '(name=*)'
    )
    
    $wmiQuery = "select IPAddress, DefaultIPGateway from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE and DHCPEnabled=FALSE"
    
    $computers = (Get-ADComputer -LDAPFilter $LDAPFilter)
    foreach ($computer in $computers) { 
    
        $networkAdapters = (Get-WmiObject -ErrorAction SilentlyContinue -ComputerName $computer.DNSHostName -Query $wmiQuery) 
        foreach ($networkAdapter in $networkAdapters) { 
            foreach ($ip in $networkAdapter.IPAddress) 
            { 
                if ($ip -match "\.") 
                { 
                    Write-Host $($computer.DNSHostName), $ip } 
                }
        } 
    }
    

Я не тестировал это полностью, но он работает на одном компьютере, показывая только имя и статические IP-адреса.

N.B. он не покажет вам никаких имен компьютеров, с которыми не может связаться, но не будет и оригинального.

Вы должны быть осторожны с тем, как веб-страница сокращает ваш код. Вот моя модифицированная версия, которая работает OU на случай, если вы не хотите тестировать каждый компьютер, и имеет немного больше информации во время работы.

############################################################################ 
## 
##  Script, that returns list of computers with first statically configured 
##  IP Address and Default Gateway. 
##  Requires Active Directory Module 
## 
##  Version: 1.0 
##  Author: vladboro@hotmail.com 
##  Date: 07#23#2012 
## 
############################################################################ 

# %Debug Arguments%='"Value1" "-Verbose"'

param ( [string]$LDAPFilter = '(name=*)', [switch]$Verbose ) 

import-module ActiveDirectory

# $LDAPFilter = '(name=*)'
# $Verbose = $True

if ($Verbose.IsPresent) 
    {
    $VerboseModeString = "enabled."
    $VerboseModeVar = $True
    }
Else
    {
    $VerboseModeString = "not enabled."
    $VerboseModeVar = $False
    }

# $VerboseModeVar = $True

Write-Host "Verbose mode is $VerboseModeString" -ForegroundColor Magenta


# LDAP Paths:
$Singapore_OU =     "OU=Singapore,OU=APAC,OU=TopOU,DC=MyDomain,DC=com"
$BC_OU =        "OU=BC,OU=Australia,OU=APAC,OU=TopOU,DC=MyDomain,DC=com"
$MAL_OF_OU =        "OU=KL Office,OU=Malaysia,OU=APAC,OU=TopOU,DC=MyDomain,DC=com"
$HK_OU =    "OU=HK Warehouse,OU=Hong Kong,OU=APAC,OU=TopOU,DC=MyDomain,DC=com"

Get-ADComputer -SearchBase $HK_OU -LDAPFilter $LDAPFilter | % `
{  
    $name = $_.DNSHostName; 

    if ($VerboseModeVar) 
      { Write-Host -ForegroundColor Yellow "Connecting to $name..." }  
    $ints = Get-WmiObject -ErrorAction SilentlyContinue -ComputerName $name -Query "select IPAddress, DefaultIPGateway from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE and DHCPEnabled=FALSE"; 
    if ($ints -ne $null) 
        { 
            foreach ($int in $ints) 
            { 
                foreach ($addr in $int.IPAddress) 
                { 
                    $ip = $null 
                    if ($addr -match "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}") 
                    { 
                        $ip = $addr 
                        $gw = $null 
                        foreach ($gw_addr in $int.DefaultIPGateway) 
                        { 
                            if ($gw_addr -match "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}") 
                            { 
                                $gw = $gw_addr 
                                break 
                            } 
                        } 
                        if ($ip -ne $null) 
                        { 
                            $info = New-Object PSObject -Property `
                            @{ 
                                Name = $name 
                                IP = $ip 
                                Gateway = $gw 
                            } 
                            $info 
                            if ($Verbose.IsPresent) 
                                { Write-Host -ForegroundColor Yellow $info } 
                        } 
                    } 
                } 
            } 
        }
    else
        {
        if ($Verbose.IsPresent) 
            {
            Write-Host "--> Could not contact the computer $Name" -ForegroundColor Red
            }
        }

} | 
Select-Object Name, IP, Gateway

Я использовал это в своем проекте для восстановления контроллеров домена AD, чтобы найти статические IP-адреса, требующие изменения DNS, и он работает на 100%!