I am writing a function to convert a list of IP addresses from their dotted-decimal form to an unsigned integer in PowerShell. Here is my function:
function Convert-IPtoInteger() {
param(
[Parameter(Mandatory=$true, Position=0, ParameterSetName="IP Address",
ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[string] $addresses
)
process {
foreach ($ip in $addresses) {
if ($ip -match '(\d\d?\d?\.){3}\d\d?\d?') { # approximate regex, matches some impossible addresses like 999.0.0.0
$s = "$ip".Split(".");
[uint32] $x = 0;
(0..3) | ForEach-Object { # positions 0, 1, 2, 3 in previous string
$x = $x -shl 8; # bit shift previous value to the left by 8 bits
$x += $s[$_];
}
Write-Output $x;
}
}
}
}
I had tried this with $addresses declared as a scalar as shown and as a [string[]] array. In both cases, piping a string of multiple lines (created with shift-enter) causes an error after the first element. If I use the Get-Content command to read the same text from a file the program completes as expected.
PS C:\...\1> $example = "192.168.1.1
192.168.2.1"
PS C:\...\1> $example | Convert-IPtoInteger
Cannot convert value "1
192" to type "System.UInt32". Error: "Input string was not in a correct format."
At C:\...\.ps1:16 char:18
+ $x += $s[$_];
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastFromStringToInteger
3232235776
PS C:\...\1> $example > example.txt
PS C:\...\1> Get-Content .\example.txt | Convert-IPtoInteger
3232235777
3232236033
I believe that the difference is how PowerShell is handling newlines. Line 16 ($x += $s[$_]) appears to be reading "1`n192" in the same token, rather than receiving each element as a separate $ip from the foreach statement.
The Get-Member command shows that $example | Get-Member is an instance of System.String just like Get-Content .\example.txt | Get-Member.
I would like for my program to correctly accept input from text files and also from strings. What am I missing here? Why is Get-Content being parsed differently from a multi-line string?