首先我要说的是,我根本不擅长编写脚本或排除故障,因此我来到这里:)
我正在尝试查找 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
我做错了什么?或者我应该在脚本中添加/删除什么才能使其运行?
谢谢,
答案1
我究竟做错了什么?
反引号 ` 是行继续符,您收到的第一个错误“一元运算符后缺少表达式”似乎是 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
,而这对你没有帮助?
我对其进行了一些修剪,并重新命名,得到了以下更清晰、更简单的结构:
- 设置。
- 获取计算机
- 对于每台计算机,获取具有静态地址的网络接口。
- 对于每个接口,获取 IP 地址。
- 对于每个 IP 地址,通过查找来识别 IPv4 地址
.
显示计算机名称和此 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。
注意:它不会显示任何无法联系的计算机的名称,但原始计算机也不会显示。
答案2
您需要注意网页如何分割您的代码。这是我修改过的版本,如果您不想测试每台计算机,它可以通过 OU 运行,并且在运行时会提供更多信息。
############################################################################
##
## 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
我已经在我的项目中使用它来重建 AD 域控制器,以便找到需要 DNS 更改的静态 IP,并且它 100% 有效!