Localiza computadores no domínio com IPs estáticos - PowerShell

4

deixe-me começar por dizer que não sou bom em escrever scripts ou resolvê-los, por isso estou aqui:)

Estou tentando encontrar todos os computadores em uma rede de domínio do Windows que estão usando endereços IP estáticos, fiz uma pequena pesquisa on-line e descobri este script do PowerShell que é o seguinte:

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

Eu tentei executar isso no meu servidor do Active Directory, o problema é, o script dá um erro durante a execução da seguinte forma:

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

Eu segui meu caminho para remover o "-" do script e, em vez disso, recebi este erro:

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

O que estou fazendo de errado? ou o que devo adicionar / remover do script para executá-lo?

Obrigado,

    
por Noor Khaldi 06.10.2013 / 13:13

2 respostas

7

What am I doing wrong?

O backtick 'é o caractere de continuação de linha, e o primeiro erro que você obtém de' expressão ausente após o operador unário 'parece ser o PowerShell não vendo a linha -Query como parte da linha anterior.

Possivelmente você está perdendo o 'no final da linha anterior em sua cópia do script, ou ele foi substituído por um apóstrofo por algum capricho de código / copiar / colar / código do editor, ou algo assim.

or what should I add/remove from the script to make it run?

Remova a maior parte, é complicado e feio e redundante para o que você deseja.

Por que ele está pesquisando Win32_NetworkAdapterConfiguration coisas e chamando ints ? Isso é tão enganoso.

Por que está levando o IPAddress , chamando-o de addr , chamando-o de ip e chamando-o de IP ?

Por que está levando o GatewayAddress , chamando-o gw_addr , depois gw e, em seguida, Gateway ?

O teste para -eq $null parece desnecessário, se você tentar usar foreach em uma sequência vazia, ele funcionará como esperado (ignore-o).

Usando regexes para pegar endereços IPv4 em vez de endereços IPv6 - útil, mas waffly. Endereços IPv6 usam : para delimitá-los, e os endereços IPv4 usam . , portanto, se você se importar apenas com endereços IPv4, basta procurar por . no endereço.

Por que copiar o endereço, criar uma lista de resultados e, em seguida, selecionar tudo o que está fora da lista, quando você pode simplesmente imprimir o endereço como o encontrou?

Você ainda se importa com o endereço do gateway?

Por que testar se o endereço IP está vazio quando você está em um bloco que está processando o endereço IP neste ponto, portanto, não pode ser nulo neste ponto?

Por que a coisa toda é uma corrente usando get-computers % { code } | select results , quando isso não ajuda você?

Recortei um pouco e renomei as coisas, chegando à seguinte estrutura mais clara e simples:

  1. Configuração.
  2. Obtenha os computadores
  3. Para cada computador, obtenha as interfaces de rede com endereços estáticos.
  4. Para cada interface, obtenha os endereços IP.
  5. Para cada endereço IP, identifique os IPv4 procurando .
  6. Exibe o nome do computador e este endereço 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 } 
                }
        } 
    }
    

Eu não testei isso completamente, mas funciona contra um computador para mostrar apenas o nome e os IPs estáticos.

N.B. ele não mostrará nenhum nome de computador que ele não possa contatar, mas nem o original.

    
por 06.10.2013 / 19:15
0

Você precisa ter cuidado com a forma como a página da Web reduz seu código. Aqui está a minha versão modificada, que funciona pela UO, caso você não queira que todos os computadores sejam testados e tenha um pouco mais de informações durante a execução.

############################################################################ 
## 
##  Script, that returns list of computers with first statically configured 
##  IP Address and Default Gateway. 
##  Requires Active Directory Module 
## 
##  Version: 1.0 
##  Author: [email protected] 
##  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

Eu usei isso no meu projeto para reconstruir controladores de domínio do AD para encontrar IPs estáticos que precisam de alterações de DNS e funcionam 100%!

    
por 20.11.2013 / 22:55