PowerShell: Konversi string IP yang dipisahkan koma ke objek IPAddress

3

Saya bekerja dengan Get-DhcpServerv4Scopecmdlet dan saya ingin menarik beberapa cakupan ke dalam variabel dengan -scopeidsakelar.

Get-DhcpServerv4Scope -scopeid 10.1.0.0,10.1.1.0 

Namun jika saya lakukan:

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

Saya mendapatkan kesalahan:

Get-DhcpServerv4Scope: Tidak dapat memproses transformasi argumen pada parameter 'ScopeId'. Tidak dapat mengonversi nilai "10.2.0.0,10.1.0.0" untuk mengetik "System.Net.IPAddress []". Kesalahan: "Tidak dapat mengonversi nilai" 10.2.0.0,10.1.0.0 "untuk mengetik" System.Net.IPAddress ". Kesalahan:" Alamat IP yang tidak valid telah ditentukan. ""

Adakah yang tahu cara melakukan konversi ini?

Sunting: Ini skrip yang saya coba selami ini. Saya ingin memiliki cara untuk mengarahkan skrip ini di server dan itu membangun kembali semua cakupan. saat ini saya mengeluarkan lingkup dalam file yang dibatasi tab, lalu salin & tempel ke dalam Get-dhcpv4scopeuntuk menyimpan semua cakupan dalam satu variabel. Saya terbuka untuk saran:

#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}

Kode Baru:

#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 
Adam Turner
sumber

Jawaban:

4
$IPobj = $IP | ConvertFrom-Csv -Delimiter "," -Header "ip1", "ip2"
Get-DhcpServerv4Scope -scopeid $IPobj.ip1, $IPobj.ip2

Namun masalah utama Anda $IPadalah string, sedangkan ketika Anda secara manual melewatkan 10.1.0.0,10.1.1.0 sebagai parameter Anda sebenarnya melewati 2 string.

Anda akan lebih baik membuat $IPsebagai array:

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

Dengan cara ini Anda dapat skrip / loop melalui array jika Anda memiliki beberapa cakupan.

Adam bertanya bagaimana melakukan ini secara dinamis dan meskipun saya tidak tahu dari mana kita mendapatkan "10.2.0.0" dan "10.1.0.0", Anda hanya perlu terus mengisi $IParray dengan semua ID lingkup yang perlu Anda periksa , lalu loop sebagai berikut:

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

Kode di atas melewati setiap entri $IP, sementara menyimpannya $scopeiddan menggunakannya sebagai parameter untuk memanggil Get-DhcpServerv4Scopecmdlet.

Pedro Perez
sumber
Adakah cara untuk menangani ini secara dinamis? Saya ingin menggunakan ini terhadap berbagai DHCP server dengan berbagai cakupan.
Adam Turner
Iya tentu saja. Anda dapat mengisi array dengan cakupan yang lebih banyak sesuai kebutuhan, maka kita dapat mengulangi foreach dan memanggil Get-DhcpServerv4Scope untuk masing-masing;) - bagaimana Anda mempelajari id lingkup? secara manual? atau apakah Anda mendapatkannya dari file / cmdlet lain / etc? Either way, saya akan memperbarui jawabannya dengan loop juga.
Pedro Perez
Saya memperbarui posting untuk menunjukkan kode lengkap yang saya gunakan sekarang. Saya ingin mengganti keseluruhan bagian "buat CSV dari subnet, C&P menjadi -subnetid switch" dengan pendekatan otomatis.
Adam Turner
Gunakan foreach ($ scope in (Get-DhcpServerv4Scope | Select ScopeID)) untuk menggunakan $ scope sebagai parameter pada "Get-DhcpServerv4Scope -scopeid PasteScopeCSVListHere " dan menyimpan output ke $ Scopes, tapi pastikan $ Scopes adalah array, jadi di dalam Foreach yang sama gunakan $ Scopes + = $ scope untuk mengisi array :)
Pedro Perez
3

Ada pemain asli [ipaddress]yang harus membuat ini sangat mudah.

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

Saya tidak memiliki sistem pengujian dengan DHCP yang berjalan saat ini, tetapi saya kira Anda bahkan mungkin tidak memerlukan [ipaddress] dan hanya bisa bertahan .Split(',')karena Powershell harus cukup pintar untuk mengambil string IP individu dan konversikan untuk Anda seperti yang terjadi pada cuplikan kode pertama Anda.

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

Mari kita jawab pertanyaan langsung yang ada: mengapa contoh pertama Anda berhasil tetapi contoh kedua Anda tidak. Mari kita mulai dengan mengapa yang pertama TIDAK BERHASIL. Ini melibatkan Mode Parsing PowerShell yang berbeda .

Contoh Pertama Anda (berfungsi):

Get-DhcpServerv4Scope -scopeid 10.1.0.0,10.1.1.0

Dalam contoh pertama Anda, PowerShell dalam Mode Parsing Perintahkarena baris Anda dimulai dengan sebuah perintah. Dalam Mode Perintah, PowerShell akan secara otomatis mengutip argumen untuk sebuah perintah untuk Anda, karena mengutip semuanya saat bekerja di shell Anda akan sangat menjengkelkan! Ini berarti mengutip nilai alamat IP yang tidak dikutip untuk Anda, mengubahnya menjadi string dan ',' (operator Comma) menggabungkan dua string menjadi sebuah array. Karena Parameternya adalah IPAddress [] (array objek IPAddress), ia mencoba untuk melemparkan string Anda ke IPAddress, dan itu berhasil, karena mereka adalah entri individual dalam sebuah array dan IPAddress tahu cara mengurai 1 string dalam format itu dan membuat IPAddress keberatan dengan itu. Setidaknya, saya 90% yakin kombinasi dari 3 hal tersebut (operator koma / array, mode parsing perintah, dan casting) adalah alasannya.

CATATAN: Mode perintah yang lebih khusus dapat disebut mode argumen (seperti dalam argumen ke perintah), mode lainnya disebut mode ekspresi. Dalam buku PowerShell lama saya, saya hanya melihatnya disebut mode perintah, tetapi dokumen saat ini berbicara tentang mode argumen.

Dari dokumen:

Dalam mode argumen, setiap nilai diperlakukan sebagai string yang dapat diperluas kecuali jika dimulai dengan salah satu karakter khusus berikut: tanda dolar ($), pada tanda (@), tanda kutip tunggal ('), tanda kutip ganda ("), atau tanda kutip ganda ("), atau tanda kurung buka (().

Contoh Kedua Anda:

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

Di baris pertama, Anda hanya membuat string "10.2.0.0,10.1.0.0",. PowerShell akan membiarkan Anda membuat string itu seperti yang Anda inginkan dan membiarkannya sendiri. Bahkan jika Anda menghilangkan tanda kutip ganda, Anda akan melihat bahwa PowerShell tidak akan melakukan hal yang sama seperti Contoh 1 ... dan ini karena itu dalam Mode Ekspresi dan tidak akan mengutip secara otomatis string Anda untuk Anda dalam mode ini. Ketika saya mencoba itu saya tidak mendapatkan apa pun yang ditugaskan. Anda mungkin melihat itu juga.

Pada baris kedua dari contoh Anda, tidak ada PowerShell khusus yang akan dilakukan - itu hanya string yang kebetulan memiliki koma di dalamnya - itu tidak akan memeriksa dan memodifikasi string Anda, itu hanya akan meneruskannya, di mana ia akan gagal mem-parse ke dalam IPAddress karena itu bukan bentuk yang valid dan metode parse apa pun yang dimiliki IPAddress hanya dapat menangani alamat IP tunggal dan bukan string yang dipisahkan koma.

Bagian ini dapat diperbaiki dengan menyesuaikan garis seperti yang disarankan Pedro ke dalam larik. misalnya:

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

Kemudian dapat diteruskan langsung:

Get-DhcpServerv4Scope -ScopeId $IP

Namun, Anda tidak menentukan apakah Anda hanya ingin memproses beberapa cakupan. Saya tidak melihat komentar tentang Anda mengedit CSV Anda untuk mengecualikan lingkup tertentu (atau dalam kode Anda), jadi Anda bisa melewatkan SEMUA ini dalam kasus itu dan cukup panggil Get-DhcpServerv4Scope tanpa argumen -ScopeId dan itu akan mengembalikan semua lingkup . Anda kemudian dapat melewati semua ini ke CSV dan kembali bekerja.

Tidak jelas bagi saya alasan untuk membangun kembali ruang lingkup, karena sepertinya Anda berpotensi membuang sewa 8 hari yang ada (jika mereka memiliki yang sama seperti sebelumnya, mungkin mereka ditetapkan menjadi cukup pendek dulu) dan bisa mendapatkan alamat konflik jika server menetapkan ulang sebelum klien dengan sewa tersebut berakhir. Mungkin saya melewatkan sesuatu. Berhati-hatilah dengan apapun tujuan akhir Anda di sini, dan semoga sukses!

Joshua McKinnon
sumber