позвольте мне начать с того, что я совсем не умею писать сценарии или устранять их, поэтому я здесь :)
Я пытаюсь найти все компьютеры в сети домена 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
, когда это тебе не поможет?
Я немного сократил его, переименовал и получил следующую более четкую и простую структуру:
.
Отобразите имя компьютера и этот 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%!