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

PowerShell: преобразование строки IP-адресов, разделенных запятыми, в объект IPAddress

Я работаю с Get-DhcpServerv4Scope командлет, и я хочу вывести несколько областей в переменную с -scopeid переключатель.

Get-DhcpServerv4Scope -scopeid 10.1.0.0,10.1.1.0 

Однако если я это сделаю:

$IP = "10.2.0.0,10.1.0.0"
Get-DhcpServerv4Scope -scopeid $IP

Я получаю сообщение об ошибке:

Get-DhcpServerv4Scope: не удается обработать преобразование аргумента для параметра ScopeId. Невозможно преобразовать значение «10.2.0.0,10.1.0.0» в тип «System.Net.IPAddress []». Ошибка: «Невозможно преобразовать значение« 10.2.0.0,10.1.0.0 »в тип« System.Net.IPAddress ». Ошибка:« Указан неверный IP-адрес ».

Кто-нибудь знает, как сделать это преобразование?

Редактировать: Вот сценарий, в который я пытаюсь это уместить. Я хотел бы иметь способ направить этот скрипт на сервер, и он перестроит все области. прямо сейчас я вывожу области в файл с разделителями табуляции, затем копирую и вставляю их в Get-dhcpv4scope чтобы хранить все области в одной переменной. Я открыт для любых предложений:

#GetScopes
$ScopeExclusions = Get-DhcpServerv4ExclusionRange
[string]$ScopesCSV=Get-DhcpServerv4Scope | Select ScopeID | convertto-
csv -notypeinformation
$ScopesCSV.replace('" ', ',').replace('"', '').replace('ScopeId,', '') 
| out-file c:\users\aturner\desktop\csv.txt
**Copy contents from file to clipboard**
$Scopes=Get-DhcpServerv4Scope -scopeid *PasteScopeCSVListHere* | select 
ScopeId,Name,Description,SubnetMask,StartRange,EndRange,LeaseDuration

#Delete Scopes
$Scopes | % { Remove-DhcpServerv4Scope -ScopeId $_.scopeid -force}

#Rebuild Scopes
$Scopes | % {Add-DhcpServerv4Scope -Name $_.name -Description 
$_.description -SubnetMask $_.SubnetMask -StartRange $_.StartRange -
EndRange $_.EndRange -LeaseDuration 8.00:00:00 }
$ScopeExclusions | % {Add-DHCPServerv4ExclusionRange -ScopeID $_.ScopeID -
StartRange $_.StartRange -EndRange $_.EndRange}

Новый код:

#GetScopes
$ScopeExclusions = Get-DhcpServerv4ExclusionRange
[string]$ScopesArray=Get-DhcpServerv4Scope | Select ScopeID | convertto-csv -notypeinformation
$ScopesCSV=$ScopesArray.replace('" ', ',').replace('"', '').replace('ScopeId,', '') 
$ScopeReservations = Get-DhcpServerv4Scope | Get-DhcpServerv4Reservation | select *
$Scopes=Get-DhcpServerv4Scope -scopeid $ScopesCSV.Split(',') | select ScopeId,Name,Description,SubnetMask,StartRange,EndRange,LeaseDuration

#Delete Scopes
$Scopes | % { Remove-DhcpServerv4Scope -ScopeId $_.scopeid -force}

#Rebuild Scopes
$Scopes | % {Add-DhcpServerv4Scope -Name $_.name -Description $_.description -SubnetMask $_.SubnetMask -StartRange $_.StartRange -EndRange $_.EndRange -LeaseDuration 8.00:00:00 }
$ScopeReservations | % {Add-DhcpServerv4Reservation -ScopeID $_.ScopeID -IPAddress $_.IPAddress -ClientId $_.ClientID -Description $_.Description -Name $_.Name -Type $_.Type}
New 
$IPobj = $IP | ConvertFrom-Csv -Delimiter "," -Header "ip1", "ip2"
Get-DhcpServerv4Scope -scopeid $IPobj.ip1, $IPobj.ip2

Однако ваша главная проблема в том, что $IP является строкой, а когда вы вручную передаете 10.1.0.0,10.1.1.0 в качестве параметров, вы фактически передаете 2 строки.

Вам было бы лучше создать $IP как массив:

$IP = @("10.2.0.0", "10.1.0.0")
Get-DhcpServerv4Scope -scopeid $IP[0],$IP[1]

Таким образом вы можете выполнить скрипт / цикл по массиву, если у вас несколько областей.

Адам спросил, как это сделать динамически, и хотя я не знаю, откуда мы получаем «10.2.0.0» и «10.1.0.0», вам просто нужно продолжать заполнять $IP массив со всеми идентификаторами областей, которые необходимо проверить, затем выполните цикл следующим образом:

foreach ($scopeid in $IP) { Get-DhcpServerv4Scope -scopeid $scopeid }

Приведенный выше код проходит через каждую запись в $IP, временно сохраняя его в $scopeid и используя его как параметр для вызова Get-DhcpServerv4Scope командлет.

Есть родной [ipaddress] cast, который должен сделать это довольно легко.

$csvIPs = "10.2.0.0,10.1.0.0"
$IP = $csvIPs.Split(',') | %{ [ipaddress]$_ }
Get-DhcpServerv4Scope -scopeid $IP

У меня нет тестовой системы с запущенным DHCP, но я предполагаю, что вам может даже не понадобиться приведение [ipaddress], и вы можете просто обойтись .Split(',') потому что Powershell должен быть достаточно умен, чтобы брать отдельные строки IP и преобразовывать их за вас, как это было в вашем первом фрагменте кода.

$IP = "10.2.0.0,10.1.0.0"
Get-DhcpServerv4Scope -scopeid $IP.Split(',')

Давайте ответим на ближайший вопрос: почему ваш первый пример работает, а второй - нет. Начнем с того, почему первый ДЕЙСТВИТЕЛЬНО работает. Он включает в себя различные Режимы разбора.

Ваш первый пример (работает):

Get-DhcpServerv4Scope -scopeid 10.1.0.0,10.1.1.0

В вашем первом примере PowerShell находится в Командный режим анализа потому что ваша строка начинается с команды. В командном режиме PowerShell автоматически цитирует аргументы команды за вас, так как все время цитировать все при работе в вашей оболочке было бы действительно раздражающим! Это означает, что он цитирует для вас значения вашего IP-адреса без кавычек, превращая их в строки, а ',' (оператор запятой) объединяет две строки в массив. Поскольку параметром является IPAddress [] (массив объекта IPAddress), он пытается преобразовать ваши строки в IPAddress, и это успешно, поскольку они являются отдельными записями в массиве, а IPAddress знает, как проанализировать 1 строку в этом формате и создает IPAddress объект с ним. По крайней мере, я на 90% уверен, что сочетание этих трех вещей (запятая / оператор массива, режим синтаксического анализа команд и приведение типов) - вот почему это работает.

ПРИМЕЧАНИЕ. Более конкретно, командный режим может называться режимом аргументов (как в аргументах команды), а другой режим - режимом выражения. В моей старой книге PowerShell я видел, что это называется командным режимом, но в текущем документе говорится о режиме аргументов.

Из документа:

В режиме аргументов каждое значение обрабатывается как расширяемая строка, если оно не начинается одним из следующих специальных символов: знак доллара ($), знак (@), одинарная кавычка ('), двойная кавычка (") или открывающая скобка (().

Ваш второй пример:

$IP = "10.2.0.0,10.1.0.0"
Get-DhcpServerv4Scope -scopeid $IP

В первой строке вы просто создаете строку, "10.2.0.0,10.1.0.0". PowerShell позволит вам сделать эту строку так, как вы хотите, и оставит ее в покое. Даже если вы опустите двойные кавычки, вы заметите, что PowerShell не будет делать то же, что и Пример 1 ... и это потому, что он находится в Режим выражения и не будет автоматически цитировать ваши строки в этом режиме. Когда я пытаюсь это сделать, мне ничего не назначают. Вы, наверное, тоже это видели.

Во второй строке вашего примера PowerShell ничего особенного не собирается делать - это просто строка, в которой есть запятая - она ​​не будет проверять и изменять вашу строку, она просто передаст ее, где она не сможет выполнить синтаксический анализ в IPAddress, потому что это недопустимая форма, и какой бы метод синтаксического анализа IPAddress не имел, может обрабатывать только один IP-адрес, а не их строку, разделенную запятыми.

Эту часть можно исправить, настроив линию, как предложил Педро, в массив. например.:

$IP = @("10.2.0.0","10.1.0.0")

Затем его можно передать напрямую:

Get-DhcpServerv4Scope -ScopeId $IP

Однако вы не указали, собираетесь ли вы обрабатывать только некоторые области. Я не вижу комментариев о том, что вы редактируете свой CSV, чтобы исключить определенные области (или в своем коде), поэтому вы могли бы вместо этого пропустить ВСЕ это в этом случае и просто вызвать Get-DhcpServerv4Scope без аргумента -ScopeId, и он вернет все объемы. Затем вы можете пропустить все это в CSV и вернуться к работе.

Мне неясна причина перестройки области, так как кажется, что вы потенциально отказываетесь от существующих 8-дневных договоров аренды (если они имеют такие же, как и раньше, возможно, сначала они были настроены как довольно короткие) и могли получить адрес конфликтует, если сервер переназначает его до истечения срока аренды клиентов. Может я что-то упускаю. Просто позаботьтесь о том, что ваша конечная цель уже здесь, и удачи!