0

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?

1 Answer 1

1

Put the IP Addresses in an object array:

$example = @("192.168.1.1", "192.168.2.1")
$example | convert-IPtointeger

result:

3232235777 
3232236033

The reason it is different is because you are using Foreach-Object against a string:

$example1 = @("192.168.1.1", "192.168.2.1") 
$example1.GetType()

$example2 = "192.168.1.1
192.168.2.1"
$example2.GetType()

$example3 = (Get-Content "C:\Users\owain.esau\Desktop\links.txt" )
$example3.GetType()

This returns the following

IsPublic IsSerial Name                                     BaseType                                                                                                                                                                          
-------- -------- ----                                     --------                                                                                                                                                                          
True     True     Object[]                                 System.Array                                                                                                                                                                      
True     True     String                                   System.Object                                                                                                                                                                     
True     True     Object[]                                 System.Array  
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.