Select as many ips as possible inside 255 characters string

by Grzegorz Kulikowski

Imagine you have a lot of ips in array, but you want to divide them per 255 characters slices.  We join all them using a comma, and them replace comma by a semicolon

$ip4=1..30 | ForEach-Object { “192.168.1.$_” }
$ip4
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5
192.168.1.6
192.168.1.7
192.168.1.8
192.168.1.9
192.168.1.10
192.168.1.11
192.168.1.12
192.168.1.13
192.168.1.14
192.168.1.15
192.168.1.16
192.168.1.17
192.168.1.18
192.168.1.19
192.168.1.20
192.168.1.21
192.168.1.22
192.168.1.23
192.168.1.24
192.168.1.25
192.168.1.26
192.168.1.27
192.168.1.28
192.168.1.29
192.168.1.30
$ip4 -join ‘,’
192.168.1.1,192.168.1.2,192.168.1.3,192.168.1.4,192.168.1.5,192.168.1.6,192.168.1.7,192.168.1.8,192.168.1.9,192.168.1.10,192.168.1.11,192.168.1.12,192.168.1.13,192.168.1.14,192.168.1.15,192.168.1.16,192.168.1.17,192.168.1.18,192.168.1.19,192.168.1.20,192.168.1.21,192.168.1.22,192.168.1.23,192.168.1.24,192.168.1.25,192.168.1.26,192.168.1.27,192.168.1.28,192.168.1.29,192.168.1.30

$ip4 -join ‘,’ -replace ‘(\G.{216,255}),’,’$1;’
192.168.1.1,192.168.1.2,192.168.1.3,192.168.1.4,192.168.1.5,192.168.1.6,192.168.1.7,192.168.1.8,192.168.1.9,192.168.1.10,192.168.1.11,192.168.1.12,192.168.1.13,192.168.1.14,192.168.1.15,192.168.1.16,192.168.1.17,192.168.1.18,192.168.1.19,192.168.1.20;192.168.1.21,192.168.1.22,192.168.1.23,192.168.1.24,192.168.1.25,192.168.1.26,192.168.1.27,192.168.1.28,192.168.1.29,192.168.1.30
$ip4 -join ‘,’ -replace ‘(\G.{216,255}),’,’$1;’ -split ‘;’ |%{‘Next result’;$_}Next result
192.168.1.1,192.168.1.2,192.168.1.3,192.168.1.4,192.168.1.5,192.168.1.6,192.168.1.7,192.168.1.8,192.168.1.9,192.168.1.10,192.168.1.11,192.168.1.12,192.168.1.13,192.168.1.14,192.168.1.15,192.168.1.16,192.168.1.17,192.168.1.18,192.168.1.19,192.168.1.20
Next result
192.168.1.21,192.168.1.22,192.168.1.23,192.168.1.24,192.168.1.25,192.168.1.26,192.168.1.27,192.168.1.28,192.168.1.29,192.168.1.30

We are aiming for the commas

We will replace a comma with our first group from the match and put a semicolon. Then we will be splitting strings on semicolons  since we know that at position of the semicolon was the position that could hold the maximum amount of ips in 255 char string area.

And let’s say we are interested only first two batches in case we got more than 30 ips
$ip4 -join ‘,’ -replace ‘(\G.{216,255}),’,’$1;’ -split ‘;’
192.168.1.1,192.168.1.2,192.168.1.3,192.168.1.4,192.168.1.5,192.168.1.6,192.168.1.7,192.168.1.8,192.168.1.9,192.168.1.10,192.168.1.11,192.168.1.12,192.168.1.13,192.168.1.14,192.168.1.15,192.168.1.16,192.168.1.17,192.168.1.18,192.168.1.19,192.168.1.20
192.168.1.21,192.168.1.22,192.168.1.23,192.168.1.24,192.168.1.25,192.168.1.26,192.168.1.27,192.168.1.28,192.168.1.29,192.168.1.30,192.168.1.31,192.168.1.32,192.168.1.33,192.168.1.34,192.168.1.35,192.168.1.36,192.168.1.37,192.168.1.38,192.168.1.39
192.168.1.40,192.168.1.41,192.168.1.42,192.168.1.43,192.168.1.44,192.168.1.45,192.168.1.46,192.168.1.47,192.168.1.48,192.168.1.49,192.168.1.50,192.168.1.51,192.168.1.52,192.168.1.53,192.168.1.54,192.168.1.55,192.168.1.56,192.168.1.57,192.168.1.58
192.168.1.59,192.168.1.60,192.168.1.61,192.168.1.62,192.168.1.63,192.168.1.64,192.168.1.65,192.168.1.66,192.168.1.67,192.168.1.68,192.168.1.69,192.168.1.70,192.168.1.71,192.168.1.72,192.168.1.73,192.168.1.74,192.168.1.75,192.168.1.76,192.168.1.77
192.168.1.78,192.168.1.79,192.168.1.80

$first,$second,$null = $ip4 -join ‘,’ -replace ‘(\G.{216,255}),’,’$1;’ -split ‘;’

Puts first batch to $first, second batch to $second and the rest goes to null.
This will work also with ipv6, the replace part of regex is greedy, so in case you will be working with ip6 and later with ip4, it will still find the maximum amount of ips. that’s why it has 216-255 instead of 240-255

Gist:

Function Get-IPsFromString {
<#
.SYNOPSIS
Returns chunks of ips from given string limited to $MaxLength of characters from string
.DESCRIPTION
If we have 50 ips separated by commas, this function will retrieve as many batches of
ips as there can fit inside $maxlength of character from give string.
If you have to put in some form which is limited to 255 characters ips this function
will diving the ips between
By default is assumes tring limit of 255 characters and min of MaxLength-39 to handle
ipv4 and ipv6 addresses.
Ips are supposed to come as 1 string separated by commas like so:
1.1.1.1,1.1.1.2.1.1.1.3, etc..
.EXAMPLE
Generate 20 ips and group ips in batches of maximum 60 chars per batch.
PS C:\> (1..20 |%{"192.168.1.$_"}) -join ',' | Get-IPsFromString -MaxLength 60
192.168.1.1,192.168.1.2,192.168.1.3,192.168.1.4,192.168.1.5
192.168.1.6,192.168.1.7,192.168.1.8,192.168.1.9,192.168.1.10
192.168.1.11,192.168.1.12,192.168.1.13,192.168.1.14
192.168.1.15,192.168.1.16,192.168.1.17,192.168.1.18
192.168.1.19,192.168.1.20
.NOTES
Kudos to Chris Dent for helping me out with this.
#>
[cmdletbinding()]
param (
[Parameter(Mandatory,ValueFromPipeline = $True)]
[string]$IPs,
[int]$MaxLength=255
)
$IPs -join,-replace "(\G.{$($Maxlength39),$MaxLength}),",$1;’ -split ‘;’
}

You may also like

Leave a Reply

Chinese (Simplified)EnglishFrenchGermanHindiPolishSpanish
Streaming live on Twitch right now.
CURRENTLY OFFLINE