Creating a array of info for remote computers

I have a basic P.S. that brings in info about IE, but what I want to do is add some functionality to it. I would like to add the following:
-Current IP
-Current User logged in
-Java Version
-Office Version
I don’t know how to incorporate that into my current PS. I’m pretty new to Powershell and everything I try to add, errors out.

$array =@() 
$keyname = 'SOFTWARE\\Microsoft\\Internet Explorer' 
$computernames = Get-Content C:\Users\ppagal\Desktop\computers.txt
foreach ($server in $computernames) 
{ 
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $server) 
$key = $reg.OpenSubkey($keyname) 
$value = $key.GetValue('Version')
$value1 = $key.GetValue('svcUpdateVersion')
$value2 = $key.Getvalue('svcKBNumber')

 $obj = New-Object PSObject 
         
        $obj | Add-Member -MemberType NoteProperty -Name "ComputerName" -Value $server 
         
        $obj | Add-Member -MemberType NoteProperty -Name "IEVersion" -Value $value 
        
        $obj | Add-Member -MemberType NoteProperty -Name "SvcUpdateVersion" -Value $value1 
        
        $obj | Add-Member -MemberType NoteProperty -Name "KB_Number" -Value $value2
 
        $array += $obj  
 
 
} 
 
$array | select ComputerName,IEVersion,SvcUpdateVersion,KB_Number| export-csv IE_Version.csv 

Any help would be very much appreciated. I need to run this powershell and pull this info from remote computers connected on my network. That’s why I’m calling a text file with machine names. Currently, my Output is a csv file.

Thank you so much everyone in advance for your help.

not sure about java yet, but this might be a good starting point

These all look like they are classes in WMI. Learn about classnames
specifically win32_networj

To get version numbers of software look at incorporating this script:

https://gallery.technet.microsoft.com/scriptcenter/Get-RemoteProgram-Get-list-de9fd2b4
With this function you can filter for java versions

And the current user:

http://www.peetersonline.nl/2008/11/oneliner-get-logged-on-users-with-powershell/

With the IPs that can be gotten at by using the Class Win32_NetWorkAdapterConfiguration using Get-WMIObject.

I am actually doing something similar to this myself.

Anthony/ WeiYen Tan,

Thank you so so much for helping get this formatted correctly in a powershell! AS I was working on it as well, I found some code to add to Anthony’s PS and is works really well.
Below is the code I found for the java version.

 function Get-JavaVersion ($computer = $env:COMPUTERNAME) {
    $keyname = 'SOFTWARE\JavaSoft\Java Web Start'
    
    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computer)
    $key = $reg.OpenSubkey($keyname)
    $version = $key.GetValue('CurrentVersion')
    
    return $version
}

2 questions now . . 1)How can I export this to a csv file? FORMAT –> Machine Name | IP | LoggedIN | OfficeVersion | IEVersion | JavaVersion 2) is there a way to identify the machine names that were unreachable and add those machine names to the those to a csv file?

Thanks again for all your help with this. This will make things so much easier. Being new to powershell and new to this forum, I have really appreciated your contributions and suggestions.

Thanks again in advance for help with this.
Patrick

i have updated my pastebin link above to include your last two questions.

Anthony,

Thank you so much for your help. I was able to get the powershell to work. Can you help me tweak this a little bit so that the powershell will scan an IP range instead of pull from a text file?

My challenge is that I am querying over 250 machines and some of the machines are not always powered on. Going through the list of machines is taking over 7 minutes to complete. I want to be able to scan an IP range and then query against machines that are currently online. I’m hoping that will shave some time off.

Here is my ps code to scan for IP’s and resolve hostnames:

1..254 | ForEach-Object {Get-WmiObject Win32_PingStatus -Filter "Address='10.128.116.$_' and Timeout=200 and ResolveAddressNames='true' and StatusCode=0" | select ProtocolAddress*}

Here is my ps code to collect the info:

# https://powershell.org/wp/forums/topic/creating-a-array-of-info-for-remote-computers/
function Get-IPAddress ($computer = $env:COMPUTERNAME) {
    return (Test-Connection $computer -Count 1).IPV4Address.tostring()
}

function Get-MachineName ($computer = $env:COMPUTERNAME) {
    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computer)
    
    return $computer
}

function Get-LoggedInUser ($computer = $env:COMPUTERNAME) {
    # could use this to get logged in user
    #(Get-WmiObject win32_computerSystem -ComputerName $computer).username

    $owners = @{}
    Get-WmiObject win32_process -ComputerName $computer -Filter 'name = "explorer.exe"' | % {$owners[$_.handle] = $_.getowner().user}
    return Get-Process -ComputerName $computer explorer | % {$owners[$_.id.tostring()]}
}

function Get-OfficeVersion ($computer = $env:COMPUTERNAME) {
    $version = 0

    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computer)

    $reg.OpenSubKey('SOFTWARE\Microsoft\Office').GetSubKeyNames() | % {
        if ($_ -match '(\d+)\.') {
            if ([int]$matches[1] -gt $version) {
                $version = $matches[1]
            }
        }
    }

    return $version
}

function Get-IPAddress ($computer = $env:COMPUTERNAME) {
    return (Test-Connection $computer -Count 1).IPV4Address.tostring()
}

function Get-IEVersion ($computer = $env:COMPUTERNAME) {
    $keyname = 'SOFTWARE\Microsoft\Internet Explorer'

    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computer)
    $key = $reg.OpenSubkey($keyname)
    $version = $key.GetValue('Version')
    $svcUpdateVersion = $key.GetValue('svcUpdateVersion')

    if ($svcUpdateVersion) {
        return $svcUpdateVersion
    } else {
        return $version
    }
}

function Get-JavaVersion ($computer = $env:COMPUTERNAME) {
    $keyname = 'SOFTWARE\JavaSoft\Java Web Start'
    
    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computer)
    $key = $reg.OpenSubkey($keyname)
    $version = $key.GetValue('CurrentVersion')
    
    return $version
}

# script entry point
$computernames = Get-Content C:\Users\ppagal\Desktop\computers.txt

$results = foreach ($computer in $computernames) {
    if (Test-Connection $computer -Count 2 -Quiet) {
        [pscustomobject]@{
            ComputerName = $computer
            IPAddress = Get-IPAddress $computer
            LoggedInUser = Get-LoggedInUser $computer
            OfficeVersion = Get-OfficeVersion $computer
            IEVersion = Get-IEVersion $computer
            JavaVersion = Get-JavaVersion $computer
        }
    } else {
        [pscustomobject]@{
            ComputerName = $computer
            IPAddress = '-'
            LoggedInUser = '-'
            OfficeVersion = '-'
            IEVersion = '-'
            JavaVersion = '-'
        }
    }
}

$results | Format-Table -AutoSize

$results | Export-Csv c:\users\ppagal\desktop\Test.csv 

How can I merge these to scripts so that the PS will query against the “online” IP’s or hostnames and not the txt.file??

Thanks again for your help. This has become a critical tool for me that I use weekly.
Patrick

i think you would just change line 67 to this

$computernames = 1..254 | ForEach-Object {Get-WmiObject Win32_PingStatus -Filter "Address='10.128.116.$_' and Timeout=200 and ResolveAddressNames='true' and StatusCode=0" | select ProtocolAddress*}

also, your Get-MachineName function just returns whatever is input ($reg variable is not being used), and that function is not being used in your script

Thanks for the suggestion, but that did not work. I though it would be that simple, but something must be missing

Is this in an AD domain? get-computer supplies the ip address but it must be online to do so. Alternatively you can query dns with the gethostbyaddress method.

Use the test-connection after the fact to determine whether you want to try to get info from the machine.

Do you have a 2012 server available? DNScmdlet’s are pretty useful.

Just curious,

Would anyone be willing to test this script to see if it works for them?

I send it to a co-worker who is in a different department on a different subnet and he is getting errors and the .csv file is never created. a bunch on red letters across the screen and then it closes. He even tried running it in the ISE to try and bypass any restrictions but still doesn’t work

I don’t understand why it works on my PC and not his. I know that’s a loaded question, but here is what I know:

  1. we are both part of the same group policy group,
  2. we have the same AD profile that give us the same permissions
  3. our machines have the same image

Could it be an execution policy setting?

Let me know if you have tested it and what you’re results are.

Thanks,

Patrick

Here is the final script:

# https://powershell.org/wp/forums/topic/creating-a-array-of-info-for-remote-computers/
function Get-IPAddress ($computer = $env:COMPUTERNAME) {
    return (Test-Connection $computer -Count 1).IPV4Address.tostring()
}

function Get-MachineName ($computer = $env:COMPUTERNAME) {
    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computer)
    
    return $computer
}

function Get-LoggedInUser ($computer = $env:COMPUTERNAME) {
    # could use this to get logged in user
    #(Get-WmiObject win32_computerSystem -ComputerName $computer).username

    $owners = @{}
    Get-WmiObject win32_process -ComputerName $computer -Filter 'name = "explorer.exe"' | % {$owners[$_.handle] = $_.getowner().user}
    return Get-Process -ComputerName $computer explorer | % {$owners[$_.id.tostring()]}
}

function Get-OfficeVersion ($computer = $env:COMPUTERNAME) {
    $version = 0

    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computer)

    $reg.OpenSubKey('SOFTWARE\Microsoft\Office').GetSubKeyNames() | % {
        if ($_ -match '(\d+)\.') {
            if ([int]$matches[1] -gt $version) {
                $version = $matches[1]
            }
        }
    }

    return $version
}

function Get-IPAddress ($computer = $env:COMPUTERNAME) {
    return (Test-Connection $computer -Count 1).IPV4Address.tostring()
}

function Get-IEVersion ($computer = $env:COMPUTERNAME) {
    $keyname = 'SOFTWARE\Microsoft\Internet Explorer'

    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computer)
    $key = $reg.OpenSubkey($keyname)
    $version = $key.GetValue('Version')
    $svcUpdateVersion = $key.GetValue('svcUpdateVersion')

    if ($svcUpdateVersion) {
        return $svcUpdateVersion
    } else {
        return $version
    }
}

function Get-JavaVersion ($computer = $env:COMPUTERNAME) {
    $keyname = 'SOFTWARE\JavaSoft\Java Web Start'
    
    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computer)
    $key = $reg.OpenSubkey($keyname)
    $version = $key.GetValue('CurrentVersion')
    
    return $version
}

# script entry point
$computernames = $computernames = 1..254 | ForEach-Object { Get-WmiObject Win32_PingStatus -Filter "Address='10.128.116.$_' and Timeout=200 and ResolveAddressNames='true' and StatusCode=0" } | Select-Object -ExpandProperty ProtocolAddressResolved

$results = foreach ($computer in $computernames) {
    if (Test-Connection $computer -Count 2 -Quiet) {
        [pscustomobject]@{
            ComputerName = $computer
            IPAddress = Get-IPAddress $computer
            LoggedInUser = Get-LoggedInUser $computer
            OfficeVersion = Get-OfficeVersion $computer
            IEVersion = Get-IEVersion $computer
            JavaVersion = Get-JavaVersion $computer
        }
    } else {
        [pscustomobject]@{
            ComputerName = $computer
            IPAddress = '-'
            LoggedInUser = '-'
            OfficeVersion = '-'
            IEVersion = '-'
            JavaVersion = '-'
        }
    }
}

$results | Format-Table -AutoSize

REM $Path = "$env:userprofile\Desktop\computer_info.csv"
REM $results | Export-Csv -filepath $path -NoTypeInformation
 $results | Export-Csv "$env:USERPROFILE\desktop\final_call.csv"

You’re using test-connection three times. fyi, test-connection is Win32_PingStatus gift wrapped.

REM $Path = “$env:userprofile\Desktop\computer_info.csv”
REM $results | Export-Csv -filepath $path -NoTypeInformation

Are we mixing batch with PS?

Good call out dan,

Amateur oversight on my end. I deleted the REM and got the same result.
Any thoughts?

Patrick