Retrieving system information from a remote system(s) using powershell - script provided

Viewed 47

I am trying to create a script that pulls relevant system information from the a client workstation and provides the following:

  1. Pings workstations to see if online/offline
  2. Displays the requested information on the screen
  3. Dumps requested data to a file

The reason why I am doing a write host and dumping to a file, I want to be able to have anyone in our service desk run it, and have a file copy if we need to retain the data for historical purposes. I am having trouble writing the information to the file, plain and simple I don't know how to do that (sorry :D) here is my code, any help that you are able to provide would be greatly appreciated. Thank you!

$Computers = "COMPUTERNAME"

Clear-Host

#Sets the array for the input of any string
$Outputmessage = @()

#Runs "foreach" loop statement and sets the computer variables, and performs WMI queries based on WMI Providers
foreach ($Computer in $Computers) {
    #Perform ping test on workstation prior to checking system information
    $pingtest = Test-Connection -ComputerName $Computer -Quiet -Count 1 -ErrorAction SilentlyContinue

    if ($pingtest) {
     
        #Runs WMI queries to get computer information to output on to the screen

        $computerSystem = get-wmiobject Win32_ComputerSystem -Computer $Computer
        $computerBIOS = get-wmiobject Win32_BIOS -Computer $Computer
        $computerOS = get-wmiobject Win32_OperatingSystem -Computer $Computer
        $computerCPU = get-wmiobject Win32_Processor -Computer $Computer
        $computerHDD = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter drivetype=3
        $computerDiskType = Get-WmiObject Win32_Diskdrive | Where { $_.Model } | Select caption
        $computerDisplayCount = (Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorBasicDisplayParams | where { $_.Active -like "True" }).Active.Count

                    
        #Displays on screen the system information requested translated to the below

        "-------------------------------------------------------"

        write-host "System Information for: " $computerSystem.Name -BackgroundColor DarkCyan
        ""
        "Manufacturer: " + $computerSystem.Manufacturer
        "Model: " + $computerSystem.Model
        "Asset Tag: " + $computerBIOS.SerialNumber
        "CPU: " + $computerCPU.Name
        "HDD Capacity: " + "{0:N2}" -f ($computerHDD.Size / 1GB) + "GB"
        "HDD Space: " + "{0:P2}" -f ($computerHDD.FreeSpace / $computerHDD.Size) + " Free (" + "{0:N2}" -f ($computerHDD.FreeSpace / 1GB) + "GB)"
        "Disk Type: " + $computerDiskType.caption
        "RAM: " + "{0:N2}" -f ($computerSystem.TotalPhysicalMemory / 1GB) + "GB"
        "Operating System: " + $computerOS.caption + ", Service Pack: " + $computerOS.ServicePackMajorVersion
        "Connected Monitors: " + $computerDisplayCount
        "User logged In: " + $computerSystem.UserName
        
        ""
        "-------------------------------------------------------"

        $Result = $computerSystem.Name, $computerBIOS.Model, $computerOS.SerialNumber, $computerCPU.Name, $computerHDD.Size, $computerDiskType.caption, $computerDisplayCount, $computerSystem.UserName
            
    }
    else {
        $OutputMessage += "$Computer - OFFLINE"
    }
}

$Outputmessage + $Result | Out-File -FilePath "FILE PATH" -Encoding utf8 -Append

Here is the output what is displayed in the screen

-------------------------------------------------------
System Information for:  COMPUTERNAME

Manufacturer: Manufacturer
Model: System model
Asset Tag: serial number
CPU: CPU information
HDD Capacity: drive capacity
HDD Space: Free space
Disk Type: Drive type
RAM: Memory amount
Operating System: OS Version
Connected Monitors: Number of connected monitors
User logged In: DOMAIN\USERNAME

-------------------------------------------------------

Thank you so much for your assistance

1 Answers

I would take the route of using a PSCustomObject to better organize your data. First and foremost, there are a couple of issues in your code where you don't reference the remote computer, but rather it defaults to yours relaying your information, not theirs. Another point to be made is connectivity. Just because you can ping a machine, it doesn't mean you can connect to it.

With all that's said above, given that this will be used by others, I would create a re-usable function in this case:

Function Get-SystemInfo {
[cmdletbinding()]
    Param (
        [parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true)]
        [string[]]$ComputerName = $env:COMPUTERNAME
    )
    Begin 
    { 
        $PSCustomObject = [PSCustomObject]@{
            ComputerName = $null
            Status       = $null
            Manufacturer = $null
            Model        = $null
            AssetTag     = $null
            CPU          = $null
            HDDCapacity  = $null
            HDDSpace     = $null
            DiskType     = $null
            RAM          = $null
            OperatingSystem   = $null
            ConnectedMonitors = $null
            UserloggedIn = $null
        }
    }
    Process
    {
        foreach ($computer in $ComputerName)
        {
            try {
                $PSCustomObject.ComputerName = $computer
                
                $cimSession = New-CimSession -ComputerName $computer -ErrorAction 'Stop'
                $PSCustomObject.Status = 'Online - Connected'

                $computerSystem = Get-CimInstance -ClassName 'Win32_ComputerSystem' -CimSession $cimSession -Property 'Manufacturer','Model','TotalPhysicalMemory ','UserName'
                $PSCustomObject.Manufacturer = $computerSystem.Manufacturer
                $PSCustomObject.Model = $computerSystem.Model
                $PSCustomObject.RAM = "{0:N2}" -f ($computerSystem.TotalPhysicalMemory / 1GB) + "GB"
                $PSCustomObject.UserloggedIn = $computerSystem.UserName

                $computerBIOS = Get-CimInstance -ClassName 'Win32_BIOS' -CimSession $cimSession
                $PSCustomObject.AssetTag = $computerBIOS.SerialNumber

                $computerOS = Get-CimInstance -ClassName 'Win32_OperatingSystem' -CimSession $cimSession
                $PSCustomObject.OperatingSystem = $computerOS.caption + ", Service Pack: " + $computerOS.ServicePackMajorVersion

                $computerCPU = Get-CimInstance -ClassName 'Win32_Processor' -CimSession $cimSession
                $PSCustomObject.CPU = $computerCPU.Name

                $computerHDD = Get-CimInstance -ClassName 'Win32_LogicalDisk' -CimSession $cimSession -Filter 'drivetype=3'
                $PSCustomObject.HDDCapacity = "{0:N2}" -f ($computerHDD.Size / 1GB) + "GB"
                $PSCustomObject.HDDSpace  = "{0:P2}" -f ($computerHDD.FreeSpace / $computerHDD.Size) + " Free (" + "{0:N2}" -f ($computerHDD.FreeSpace / 1GB) + "GB)"

                $computerDiskType = Get-CimInstance -ClassName 'Win32_Diskdrive' -CimSession $cimSession | Where-Object -FilterScript { $_.Model } 
                $PSCustomObject.DiskType = $computerDiskType.caption

                $computerDisplayCount = (
                    Get-CimInstance -Namespace 'root\wmi' -ClassName 'WmiMonitorBasicDisplayParams' -CimSession $cimSession | 
                    Where-Object -FilterScript { $_.Active -like "True" } 
                ).Active.Count
                $PSCustomObject.ConnectedMonitors = $computerDisplayCount
            }
            catch {
                $PSCustomObject.Status       = if (Test-Connection -ComputerName $computer -Count 1) { 'Online - Unable to Connect' } else { 'offline' }
                $PSCustomObject.Manufacturer = $null
                $PSCustomObject.Model        = $null
                $PSCustomObject.AssetTag     = $null
                $PSCustomObject.CPU          = $null
                $PSCustomObject.HDDCapacity  = $null
                $PSCustomObject.HDDSpace     = $null
                $PSCustomObject.DiskType     = $null
                $PSCustomObject.RAM          = $null
                $PSCustomObject.OperatingSystem   = $null
                $PSCustomObject.ConnectedMonitors = $null
                $PSCustomObject.UserloggedIn = $null
            }
            finally {
                $PSCustomObject
                if ($cimSession)
                {
                    Remove-CimSession -CimSession $cimSession -ErrorAction 'SilentlyContinue'
                }
            }
        }
    }
    End { }
}

A function becomes much more handy when typing Get-SystemInfo -ComputerName 'ComputerOne','ComputerTwo', rather than modifying the $computers variable each time. From here you can pipe to Out-File, Export-Csv or any other export cmdlet of your choosing.

Related