PowerShell:将以逗号分隔的 IP 字符串转换为 IPAddress 对象

PowerShell:将以逗号分隔的 IP 字符串转换为 IPAddress 对象

我正在使用Get-DhcpServerv4Scopecmdlet,并希望使用-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 

答案1

$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]

这样,如果您有多个范围,您就可以编写脚本/循环遍历数组。

Adam 询问如何动态地做到这一点,虽然我不知道我们从哪里获得“10.2.0.0”和“10.1.0.0”,但您只需要继续用$IP您需要检查的所有范围 ID 填充数组,然后按如下方式循环:

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

上述代码遍历中的每个条目$IP,将其临时存储在其中$scopeid并将其用作参数来调用cmdlet Get-DhcpServerv4Scope

答案2

有本地[ipaddress]演员阵容,这应该很容易。

$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(',')

答案3

让我们回答眼前的问题:为什么你的第一个例子有效,而第二个例子无效。让我们先来看一下为什么第一个例子有效。这涉及到 PowerShell 的不同解析模式

你的第一个例子(作品):

Get-DhcpServerv4Scope -scopeid 10.1.0.0,10.1.1.0

在您的第一个示例中,PowerShell 位于命令解析模式因为您的行以命令开头。在命令模式下,PowerShell 会自动为您引用命令的参数,因为在您的 shell 中工作时一直引用所有内容会非常烦人!这意味着它会为您引用未加引号的 IP 地址值,将它们转换为字符串,并且 ','(逗号运算符)将两个字符串组合成一个数组。由于参数是 IPAddress[](IPAddress 对象的数组),它会尝试将您的字符串转换为 IPAddress,并且它会成功,因为它们是数组中的单独条目,并且 IPAddress 知道如何解析该格式的 1 个字符串并使用它创建一个 IPAddress 对象。至少,我 90% 确定这 3 个因素(逗号/数组运算符、命令解析模式和转换)的组合是其有效的原因。

注意:更具体地说,命令模式可以称为参数模式(如命令的参数),另一种模式称为表达式模式。在我较旧的 PowerShell 书中,我只看到它被称为命令模式,但当前文档讨论了参数模式。

来自文档:

在参数模式中,每个值都被视为可扩展字符串,除非它以以下特殊字符之一开头:美元符号 ($)、at 符号 (@)、单引号 (')、双引号 (") 或左括号 (()。

你的第二个例子:

$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 地址,而不能处理用逗号分隔的字符串。

可以按照 Pedro 的建议将该行调整为数组,从而更正此部分。例如:

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

然后可以直接传递:

Get-DhcpServerv4Scope -ScopeId $IP

但是,您没有指定是否只打算处理某些范围。我没有看到关于您编辑 CSV 以排除某些范围(或在您的代码中)的评论,因此在这种情况下您可以跳过所有这些,只需调用 Get-DhcpServerv4Scope 而不使用任何 -ScopeId 参数,它将返回所有范围。然后您可以将所有这些内容跳过到 CSV 并返回工作。

我不清楚重建范围的原因,因为看起来您可能会丢弃现有的 8 天租约(如果它们与之前的租约相同,那么可能首先将它们设置为非常短),并且如果服务器在拥有这些租约的客户端到期之前重新分配它,则可能会发生地址冲突。也许我遗漏了什么。只要小心处理您的最终目标是什么,祝您好运!

相关内容