Code

Robot avatar images lovingly delivered by Robohash.org.

Twizzle  •  20 Mar 2024   •    
Screenshot

Creating little Powershell scripts is quite satisfying. There are always a small number of processes I repeat but have to look up how to do them via a command line each time. So I just use "found code" and ChatGPT to write me a Powershell script so I can keep it for later. For example, I sometimes ping a range of IP addresses. This can be done via a command line:

for /L %i in (1,1,254) do ping -n 1 192.168.1.%i

The only issue with that, is that you have to tweak the IP address manually each time, especially if you only want to only ping from .10 to .20 - its a pain.

My Powershell script prompts for an IP address in CIDR format: 192.168.1.0/24 which then converts it, knowing that the range of IP addresses it needs to ping is 192.168.1.1 to 192.168.1.254

I am not sure how often I will use it, but it is there now just in case.

# calculate IP address range from CIDR notation
# https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing

function cidrToIpRange {
    param (
        [string] $cidrNotation
    )

    $addr, $maskLength = $cidrNotation -split '/'
    [int]$maskLen = 0
    if (-not [int32]::TryParse($maskLength, [ref] $maskLen)) {
        throw "Cannot parse CIDR mask length string: '$maskLen'"
    }
    if (0 -gt $maskLen -or $maskLen -gt 32) {
        throw "CIDR mask length must be between 0 and 32"
    }
    $ipAddr = [Net.IPAddress]::Parse($addr)
    if ($ipAddr -eq $null) {
        throw "Cannot parse IP address: $addr"
    }
    if ($ipAddr.AddressFamily -ne [Net.Sockets.AddressFamily]::InterNetwork) {
        throw "Can only process CIDR for IPv4"
    }

    $shiftCnt = 32 - $maskLen
    $mask = -bnot ((1 -shl $shiftCnt) - 1)
    $ipNum = [Net.IPAddress]::NetworkToHostOrder([BitConverter]::ToInt32($ipAddr.GetAddressBytes(), 0))
    $ipStart = ($ipNum -band $mask) + 1
    $ipEnd = ($ipNum -bor (-bnot $mask)) - 1

    # return as tuple of strings:
    ([BitConverter]::GetBytes([Net.IPAddress]::HostToNetworkOrder($ipStart)) | ForEach-Object { $_ } ) -join '.'
    ([BitConverter]::GetBytes([Net.IPAddress]::HostToNetworkOrder($ipEnd)) | ForEach-Object { $_ } ) -join '.'
}

$ipToUse = Read-Host "Enter IP address and subnet mask (e.g., 192.168.1.0/24):"
$start, $end = cidrToIpRange $ipToUse
Write-Host "Start: $start, end: $end"

# Function to convert IP address to integer
function ConvertTo-Int32 {
    param (
        [string]$IPAddress
    )
    $ipBytes = $IPAddress.Split('.')
    $intIP = 0
    for ($i = 0; $i -lt 4; $i++) {
        $intIP += [int]$ipBytes[$i] * [math]::Pow(256, 3 - $i)
    }
    return $intIP
}

# Function to convert integer to IP address
function ConvertTo-IPAddress {
    param (
        [int]$IntIP
    )
    $ipBytes = @()
    for ($i = 0; $i -lt 4; $i++) {
        $ipBytes += [math]::Floor($IntIP / [math]::Pow(256, 3 - $i))
        $IntIP = $IntIP % [math]::Pow(256, 3 - $i)
    }
    return $ipBytes -join '.'
}

# Function to get IP range
function Get-IPRange {
    param (
        [string]$StartIPAddress,
        [string]$EndIPAddress
    )
    $startInt = ConvertTo-Int32 -IPAddress $StartIPAddress
    $endInt = ConvertTo-Int32 -IPAddress $EndIPAddress

    $IPRange = @()
    for ($i = $startInt; $i -le $endInt; $i++) {
        $IPRange += ConvertTo-IPAddress -IntIP $i
    }

    return $IPRange
}

# Prompt for IP address range
$startIP = $start
$endIP = $end

# Get IP address range
$ipRange = Get-IPRange -StartIPAddress $startIP -EndIPAddress $endIP

# Ping each IP address in the range
foreach ($ip in $ipRange) {
    $pingResult = Test-Connection -ComputerName $ip -Count 1 -Quiet
    if ($pingResult) {
        Write-Host "Ping successful: $ip"
    }
}

Comments


Discover more

Sourced from other writers across Lifelog

Ooops we couldn't find any related post...