我正在使用Get-DhcpServerv4Scope
cmdlet,并希望使用-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 天租约(如果它们与之前的租约相同,那么可能首先将它们设置为非常短),并且如果服务器在拥有这些租约的客户端到期之前重新分配它,则可能会发生地址冲突。也许我遗漏了什么。只要小心处理您的最终目标是什么,祝您好运!