web-dev-qa-db-ja.com

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に貼り付け、すべてのスコープを1つの変数に格納します。私はどんな提案にも開いています:

#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 
3
Adam Turner
$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に格納し、それをパラメーターとして使用してGet-DhcpServerv4Scopeコマンドレットを呼び出します。

4
Pedro Perez

これをかなり簡単にするネイティブ_[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
Ryan Bolger

差し迫った質問に答えましょう。最初の例が機能するのに2番目の例が機能しないのはなぜですか。最初のものが機能する理由から始めましょう。 PowerShellのさまざまな 解析モード が含まれます。

最初の例(動作):

Get-DhcpServerv4Scope -scopeid 10.1.0.0,10.1.1.0

最初の例では、行がコマンドで始まっているため、PowerShellはCommand Parsing Modeです。コマンドモードでは、PowerShellはコマンドの引数を自動的に引用します。これは、シェルで作業するときは常にすべてを引用するのは面倒です。これは、引用符で囲まれていないIPアドレス値を引用して文字列に変換し、 '、'(カンマ演算子)が2つの文字列を配列に結合していることを意味します。パラメータはIPAddress [](IPAddressオブジェクトの配列)であるため、文字列をIPAddressにキャストしようとしますが、それらは配列内の個別のエントリであり、IPAddressはその形式で1つの文字列を解析してIPAddressを作成する方法を知っているためです。それとオブジェクト。少なくとも、これら3つの要素(コンマ/配列演算子、コマンド解析モード、およびキャスト)の組み合わせが90%確実に機能する理由です。

注:より具体的には、コマンドモードは引数モードと呼ばれ(コマンドの引数と同様)、他のモードは式モードと呼ばれます。以前のPowerShellの本では、コマンドモードと呼ばれているのを見ただけですが、現在のドキュメントでは引数モードについて説明しています。

ドキュメントから:

引数モードでは、ドル記号($)、アットマーク(@)、単一引用符( ')、二重引用符( ")、または特殊文字のいずれかで始まらない限り、各値は拡張可能な文字列として扱われます。左括弧(()。

2番目の例:

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

最初の行では、"10.2.0.0,10.1.0.0"という文字列を作成しています。 PowerShellはその文字列を好きなように作成し、そのままにしておきます。二重引用符を省略した場合でも、PowerShellが例1と同じことを行わないことに気づくでしょう。これは、Expression Modeにあり、 ' tこのモードでは、文字列を自動的に引用します。それを試しても何も割り当てられません。あなたもおそらくそれを見たでしょう。

例の2行目では、特別なPowerShellが実行することは何もありません-たまたまコンマが含まれているのは文字列だけです-文字列を検査して変更するのではなく、渡すだけです。は有効な形式ではないため、IPAddressへの解析に失敗します。IPAddressが持つ解析メソッドは、単一のIPアドレスしか処理できず、それらのコンマ区切りの文字列は処理できません。

この部分は、ペドロがアレイに提案したようにラインを調整することで修正できます。例えば。:

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

その後、直接渡すことができます。

Get-DhcpServerv4Scope -ScopeId $IP

ただし、一部のスコープのみを処理するかどうかを指定していません。 CSVを編集して特定のスコープ(またはコード)を除外するコメントはありません。その場合は、代わりにこのすべてをスキップして、-ScopeId引数なしでGet-DhcpServerv4Scopeを呼び出すだけで、すべてが返されます。スコープ。これをすべてスキップしてCSVに戻し、作業を戻すことができます。

既存の8日間のリースを破棄する可能性があるため(以前のものと同じである場合、最初はかなり短く設定されている可能性があります)、アドレスを取得できるため、スコープを再構築する理由はわかりませんこれらのリースを持つクライアントが期限切れになる前にサーバーがサーバーを再割り当てすると、競合が発生します。多分私は何かが欠けています。あなたの最終目標がここにあることに注意してください、そして幸運を!

2
Joshua McKinnon