9

#PSTip Using PowerShell runspaces to find unassigned IPv4 addresses

Note: This tip requires PowerShell 2.0 or later.

We often come across infrastructure configuration scenarios where we need to find a free IP address before assigning the same to a server in an automated manner. However, when the given IP range that is provided is large, it may take longer to complete the free IP scanning. There are many tips and articles written around this topic. There are a few articles that suggest using background jobs and throttling of background jobs. Fellow PowerShell MVP Boe Prox has published a great article on differences between PowerShell jobs and runspaces. This prompted me to write a function using PowerShell runspaces to get the free IPv4 addresses in a given network range.

If you understand PowerShell runspaces, the following function is self-explanatory. If you are new to PowerShell runspaces, I recommend reading a series of articles on this by Boe.

Function Get-AvailableIPv4Address {
    param (
        [System.Collections.ArrayList] $IPRange
    )

    $MaxThreads = 30
    $ScriptBlock = {
        Param (
        [String]$IPAddress
        )
        Test-Connection -ComputerName $IPAddress -Count 1 -Quiet
    }
 
    $RunspacePool = [RunspaceFactory]::CreateRunspacePool(1,$MaxThreads)
    $RunspacePool.Open()
    $Jobs = @()

    $IPRange | % {
       $Job = ::Create().AddScript($ScriptBlock).AddArgument($_)
       $Job.RunspacePool = $RunspacePool
       $Jobs += New-Object PSObject -Property @{
          IPAddress = $_
          Pipe = $Job
          Result = $Job.BeginInvoke()
       }
    }
 
    While ( $Jobs.Result.IsCompleted -contains $false) {
        Start-Sleep -Seconds 1
    }
 
    $Results = @()
    ForEach ($Job in $Jobs)
    {
        if (-not $Job.Pipe.EndInvoke($Job.Result)) {
            $job.IPAddress
        }
    }

}

#Example Usage
$IPRange = New-Object System.Collections.ArrayList
1 .. 254 | % { $IPRange.Add("192.168.10.$_") | Out-Null }
$IPRange = @(Get-AvailableIPv4Address -IPRange $IPRange)
Filed in: Columns, Tips and Tricks Tags: ,

9 Responses to "#PSTip Using PowerShell runspaces to find unassigned IPv4 addresses"

  1. JV says:

    Won’t work. If machine is off then the address can be duplicated. Use DHCP to manage addresses.

  2. Steve says:

    Not familiar with this notation:

    1::Create().AddScript

    ISE gets error:

    At line:19 char:25
    + $Job = 1::Create().AddScript($ScriptBlock).AddArgument($_)
    + ~
    An expression was expected after ‘(‘.
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ExpectedExpression

  3. Steve says:

    I checked out video link in your introduction and saw that this worked:

    ::Create().AddScript($ScriptBlock).AddArgument($_)

  4. Martin says:

    You should dispose the runspacePool (e.g. $RunspacePool.Dispose()), otherwise you are leaking threads (and handles), and eventually the host will hang.

Leave a Reply

Submit Comment

© 2017 PowerShell Magazine. All rights reserved. XHTML / CSS Valid.
Proudly designed by Theme Junkie.
%d bloggers like this: