Windows

在域中查找具有靜態 IP 的電腦 - PowerShell

  • November 20, 2013

首先讓我說我在編寫腳本或對其進行故障排除方面一點也不擅長,因此我在這裡:)

我正在嘗試查找 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 地址,只需.在地址中查找 a 。

為什麼要複製地址,建立一個結果列表,然後從列表中選擇所有內容,而您可以在找到地址時列印它?

你甚至關心網關地址嗎?

當您處於此時正在處理 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。

請注意,它不會向您顯示它無法聯繫的任何電腦的名稱,但原始電腦也不會顯示。

引用自:https://serverfault.com/questions/544116