Home > Back-end >  ping ip range and get informations about the pc which are online
ping ip range and get informations about the pc which are online

Time:10-06

actually i want to modify my existing powershell script. at the moment i need to provide a list of machine names. how do i need to modify my script that i dont't need a txt file, but only provide a ip range. and the script shows me which ip/pc names are online etc

$machines = Get-Content -Path "C:\temp\pcnames.txt"

function Get-LoggedOnUser
{
 [CmdletBinding()]
 param
 (
     [Parameter()]
     [ValidateScript({ Test-Connection -ComputerName $_ -Quiet -Count 1 })]
     [ValidateNotNullOrEmpty()]
     [string[]]$ComputerName = $env:COMPUTERNAME
 )
 foreach ($comp in $machines)
 {
     $output = @{ 'ComputerName' = $comp }
     $output.UserName = (Get-WmiObject -Class win32_computersystem -ComputerName $comp).UserName
     $output.Info = (Get-CimInstance -Class CIM_ComputerSystem -ComputerName $comp).model
     $output.IP = (Get-CimInstance -CimSession $comp -ClassName Win32_NetworkAdapterConfiguration -Filter "IPEnabled = 'True'").IPAddress[0]
     [PSCustomObject]$output
 }
}
Get-LoggedOnUser | Out-GridView

CodePudding user response:

You mean something like this?

function Test-IpRange {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        [IpAddress]$IpStart,

        [Parameter(Mandatory=$true, Position = 1)]
        [IpAddress]$IpEnd
    )

    # calculate the range of IP addresses by converting the IP to decimal format
    # avoid using obsolete property ([IpAddress]$IpAddress).Address
    [byte[]]$bytes = $IpStart.GetAddressBytes()
    [array]::Reverse($bytes)
    $startRange = [System.BitConverter]::ToUInt32($bytes, 0)
    [byte[]]$bytes = $IpEnd.GetAddressBytes()
    [array]::Reverse($bytes)
    $endRange = [System.BitConverter]::ToUInt32($bytes, 0)
    # swap if startaddress > end address
    if ($startRange -gt $endRange) { $startRange,$endRange = $endRange, $startRange }

    for($i = $startRange; $i -le $endRange; $i  ) {
        $adr = ([IPAddress]$i).GetAddressBytes()
        [array]::Reverse($adr)
        $ipToTest = [IPAddress]::Parse($($adr -join '.')).IPAddressToString
        $ping = Test-Connection -ComputerName $ipToTest -Count 1 -Quiet -ErrorAction SilentlyContinue
        if ($ping) {
            $computerName = (([System.Net.Dns]::GetHostEntry($ipToTest)).Hostname -split '\.')[0]
            $computerInfo = Get-CimInstance -Class CIM_ComputerSystem -ComputerName $computerName
            $adapterInfo  = Get-CimInstance -ComputerName $computerName -Class Win32_NetworkAdapterConfiguration | 
                            Where-Object { $_.IPAddress -contains $ipToTest }
            [PsCustomObject]@{
                ComputerName = $computerName
                IPAddress    = $ipToTest
                Online       = $true
                CurrentUser  = $computerInfo.UserName
                Manufacturer = $computerInfo.Manufacturer
                Model        = $computerInfo.Model
                MACAddress   = $adapterInfo.MACAddress
            }
        }
        else {
            [PsCustomObject]@{
                ComputerName = 'N/A'
                IPAddress    = $ipToTest
                Online       = $false
                CurrentUser  = 'N/A'
                Manufacturer = 'N/A'
                Model        = 'N/A'
                MACAddress   = 'N/A'
            }
        }
    }
}

Test-IpRange '192.168.0.10' '192.168.0.15' | Format-Table -AutoSize

would return something like

ComputerName IPAddress    Online CurrentUser     Manufacturer        Model    MACAddress       
------------ ---------    ------ -----------     ------------        -----    ----------       
PC07         192.168.0.10   True Contoso\chkdsk  Some PC maker, Ltd. ABCDE123 01:23:45:67:89:AA
PC03         192.168.0.11   True Contoso\wipedsk Some PC maker, Ltd. FGHIJ789 0A:1B:1C:1D:1E:1F
N/A          192.168.0.12  False N/A             N/A                 N/A      N/A              
N/A          192.168.0.13  False N/A             N/A                 N/A      N/A              
N/A          192.168.0.14  False N/A             N/A                 N/A      N/A              
N/A          192.168.0.15  False N/A             N/A                 N/A      N/A              


You could replace everything between if ($ping) { .. } into

Invoke-Command -ComputerName $ipToTest -HideComputerName -ScriptBlock {
    # this will now run on the remote computer
    $computerInfo = Get-CimInstance -Class CIM_ComputerSystem
    $adapterInfo  = Get-CimInstance -Class Win32_NetworkAdapterConfiguration | 
                    Where-Object { $_.IPAddress -contains $using:ipToTest }
    [PsCustomObject]@{
        ComputerName = $env:COMPUTERNAME
        IPAddress    = $using:ipToTest
        Online       = $true
        CurrentUser  = $computerInfo.UserName
        Manufacturer = $computerInfo.Manufacturer
        Model        = $computerInfo.Model
        MACAddress   = $adapterInfo.MACAddress
    }
} | Select-Object * -ExcludeProperty RunspaceId

and by that have the remote computer gather the information rather than your local machine. However, if that would be faster I cannot say/test myself.

Invoke-Command can also take an array of computernames/IpAddresses in its -ComputerName parameter and that would probably speed up the script.
Thing is that you then must first get a sub array of pingable IP addresses using Test-Connection on the whole range and capture which machines can be pinged and which machines failed.
For the pingable machines then use one single Invoke-Command -ComputerName $onlineMachines and for the failed ones run a separate loop to output the objects with N/A

  • Related