How to get remote system information – Part 1

Scenario:

How to get remote system information with PowerShell – Part 1.

This time we will go through a new script that allows us to get system information and not only from remote systems. This post is the first part from a series of posts that will follow. The script can run on PCs, laptops, physical and virtual servers. Read the post to find out what is needed so you will be able to run the script smoothly.

The script will help you to understand and work with retrieving information from remote systems. We will go through the information later on what we can retrieve with this version and how it works. To help you understand what we are doing and what is needed we will go through some background information. Please note that this is not the only way to do it but at least one way to do it. This is a simple way to do it. It can be done with various ways using also a combination of other languages.

Graphical User Interface (GUI)

In this script we are working with Windows Forms. Windows Forms is a library that you can use to provide GUI on your scripts. It is included in Microsoft .Net Framework by default. As PowerShell is built above Microsoft .Net Framework you can use PowerShell scripting language to create GUI on your scripts and be able to retrieve information, manipulate information and present it on GUI. Windows Forms and controls are static. Controls are placed based on an initial point in the form which is the first top left point. A more professional and flexible way is to use WPF Forms. We will discuss about WPF Forms on another post. To be able to create UI with PowerShell you need first to load the assembly. The command to load the assembly is:

Add-Type -AssemblyName System.Windows.Forms

Main Form

After the assembly is created we will need to create our form and the controls we want. First of all we create our form by using the below:

$MainForm = New-Object system.Windows.Forms.Form $MainForm.Text = "Computer Information" $MainForm.Size = New-Object System.Drawing.Size(1200,800) $MainForm.ShowDialog()

The first command creates the form object, the second command shows the title of the form and the third command is the size of the form in pixels. The last command, will display the form. We have configure more properties based on what we want to achieve. In the script you will see that more properties are configured.

Labels

To create a label inside the form you need to use the below commands.

$lbl_ComputerName = New-Object System.Windows.Forms.Label $lbl_ComputerName.Location = New-Object System.Drawing.Point(0,5) $lbl_ComputerName.Size = New-Object System.Drawing.Size(150,20) $lbl_ComputerName.Text = "Computer Name" $MainForm.Controls.Add($lbl_ComputerName)

As for all our UI object we need to create the label object first by using the first command. By using the second command we are providing the location of the label inside the form. For the example above we says that we want the label to start from 0 pixels on x axis and 5 pixels on y axis. The third command is the size of the label. The example above says that that we want to have the label 150 pixels on x axis and 20 pixels on y axis. The next command is the text that we want to show in the label. The last command is the command that we use for all of our objects to present the any control, textbox and label in the form. Please note the the last command needs to be placed before displaying the form.

Text Boxes

To create and display a text box in the form you needs to use the below commands which are similar to labels.

$txt_ComputerName = New-Object System.Windows.Forms.TextBox $txt_ComputerName.Location = New-Object System.Drawing.Point(150,5) $txt_ComputerName.Size = New-Object System.Drawing.Size(200,20) $MainForm.Controls.Add($txt_ComputerName)

Buttons

Buttons are created and displayed the same way as labels and text boxes. The difference on buttons s that we want the to do something when we click them.

$btn_System = New-Object System.Windows.Forms.Button $btn_System.Location = New-Object System.Drawing.Point(5,50) $btn_System.Size = New-Object System.Drawing.Size(145,25) $btn_System.Text = "System" $btn_System.Add_Click($System_info) $MainForm.Controls.Add($btn_System)

The above commands will create, size, locate, and display the button in the form. The 5th command is the command that we use to add the action that we want to be done when we click the button. Note here that $System_info is a function that we call when the button is clicked.

CIM Standard

Microsoft was using WMI to retrieve information from systems. WMI was using CIM standard to provide this information. With Get-WMIObject you were able retrieve the information that you wanted. WMI is built on the WBEM and CIM standards from the Distributed Management Task Force (DMTF). In PowerShell 3.0, Microsoft introduced CIM commands to directly access this information. In this script we are using CIM commands to retrive the information. As you will see below in the script, functions that are called from the buttons, are using Get-CIMInstance to get the information.

Information that we get from the systems

By using this script, in its initial version, you are able to get information about the following:

Computer System

BIOS

Processor

RAM Memory

Motherboard

Physical Drives

Logical Drives

Video Controller

Network Adapters

Monitors

Operating System

Keyboard

Pointing Devices

CD/DVD-drives

Sound Devices

Printers

Software installed (Use this at your own risk. Win32_Product class is not stable by design and might was issues on remote system.)

Processes

Services

For each of the above we get some information as it is provided by the system. If any of the fields are empty or any action does not provide any result, then it means that the system that you are trying to get the information does not provide it. With this script you will be able to get all this information remotely without the need to login with RDP on the system. If you do not provide any computer name, then the script will provide the information of the local system.

Requirements

First of all as we are using CIM commands you will need to have at least PowerShell 3.0 installed on the computer/ server that you will run the script. Secondly the user that will run the script need to have remote management permission on the remote system to be able to connect and get the information. The last thing that you need to ensure is that the remote system will need to run WINRM to be able to connect to it. WMI commands are using DCOM connection to remote system. CIM commands are using WSMAN to connect to the remote system. If you are not running WINRM on them then you will not be able to get any information. Note that script will work if you run it locally as CIM uses DCOM to connect to the local system and if no computer name will be specified the script will provide information of the local system.

You can download the script here or copy it from below.

Hope you like it. If you have any questions or anything else please let me know in the comments below.

Stay tuned for the next part of this series.

Related Links:

Solution / Script:

$System_info = { $ComputerName = $txt_ComputerName.Text $System = Get-CimInstance -Class Win32_ComputerSystem -ComputerName $ComputerName $lbl_sysinfo.Text = $System | FL -Property Name,Manufacturer,Model,PartOfDomain,Domain,Workgroup, DNSHostName,NumberOfProcessors,NumberOfLogicalProcessors, TotalPhysicalMemory,CurrentTimeZone,DaylightInEffect, HypervisorPresent,PrimaryOwnerName,UserName | Out-String } $bios_info = { $ComputerName = $txt_ComputerName.Text $Bios = Get-CimInstance -Class Win32_Bios -ComputerName $ComputerName $lbl_sysinfo.Text = $Bios | FL -Property Name,SerialNumber,Version,BIOSVersion,ReleaseData | Out-String } $CPU_info = { $ComputerName = $txt_ComputerName.Text $CPU = Get-CimInstance -Class Win32_Processor -ComputerName $ComputerName $lbl_sysinfo.Text = $CPU | FL -Property DeviceID,Manufacturer,Name,Caption,L2CacheSize,L3CacheSize, LoadPercentage,CurrentClockSpeed | Out-String } $RAM_info = { $ComputerName = $txt_ComputerName.Text $RAM = Get-CimInstance -Class Win32_PhysicalMemory -ComputerName $ComputerName $lbl_sysinfo.Text = $RAM | FL -Property Tag,DeviceLocator,Manufacturer,PartNumber,SerialNumber, Capacity,Speed | Out-String } $MB_info = { $ComputerName = $txt_ComputerName.Text $MB = Get-CimInstance -Class Win32_BaseBoard -ComputerName $ComputerName $lbl_sysinfo.Text = $MB | FL -Property Manufacturer,Model,Version | Out-String } $PhysicalDrives_info = { $ComputerName = $txt_ComputerName.Text $PhysicalDrives = Get-CimInstance -Class Win32_DiskDrive -ComputerName $ComputerName $lbl_sysinfo.Text = $PhysicalDrives | FL -Property DeviceID,FirmwareRevision,Manufacturer,Model,MediaType, SerialNumber,InterfaceType,Partitions,Size,TotalCylinders, TotalHeads,TotalSectors,TotalTracks,TracksPerCylinderBytePerSector, SectorsPerTrack,Capabilities,CapabilityDescriptions,Status | Out-String } $LogicalDrives_info = { $ComputerName = $txt_ComputerName.Text $LogicalDrives = Get-CimInstance -Class Win32_LogicalDisk -ComputerName $ComputerName $lbl_sysinfo.Text = $LogicalDrives | FL -Property DeviceID,Description,VolumeName,ProviderName,Size,FreeSpace, VolumeSerialNumber,FileSystem,Compressed | Out-String } $GPU_info = { $ComputerName = $txt_ComputerName.Text $GPU = Get-CimInstance -Class Win32_VideoController -ComputerName $ComputerName $lbl_sysinfo.Text = $GPU | FL -Property DeviceID,Name,VideoProcessor,AdapterDACType,AdapterRAM,DriverDate, DriverVersion,VideoModeDescription,CurrentBitsPerPixel,CurrentHorizontalResolution, CurrentVerticalResolution,CurrentNumberOfColors,CurrentRefreshRate,MaxRefreshRate, MinRefreshRate,Status | Out-String } $Network_info = { $ComputerName = $txt_ComputerName.Text $Network = Get-CimInstance -Class Win32_NetworkAdapter -ComputerName $ComputerName $lbl_sysinfo.Text = $Network | FL -Property DeviceID,Name,Manufacturer,ProductName,ServiceName,MACAddress,AdapterType, NetConnectionID,NetEnabled,Speed,PhysicalAdapter,TimeOfLastReset | Out-String } $Monitor_info = { $ComputerName = $txt_ComputerName.Text $Monitor = Get-CimInstance -Class Win32_DesktopMonitor -ComputerName $ComputerName $lbl_sysinfo.Text = $Monitor | FL -Property DeviceID,Name,MonitorManufacturer,MonitorType,PixelsPerXLogicalInch, PixelPerYLogicalInch,ScreenHeight,ScreenWidth,Status | Out-String } $OS_info = { $ComputerName = $txt_ComputerName.Text $OS = Get-CimInstance -Class Win32_OperatingSystem -ComputerName $ComputerName $lbl_sysinfo.Text = $OS | FL -Property Name,Manufacturer,Caption,Version,MUILanguages,BuildNumber,BuildType,InstallDate,OSArchitecture, PortableOperatingSystem,Primary,BootDevice,LastBootUpTime,LocalDateTime,CurrentTimeZone, RegisteredUser,SerialNumber,SystemDevice,SystemDirectory,SystemDrive,WindowsDirectory,EncryptionLevel, FreePhysicalMemory,FreeSpaceInPagingFiles,FreeVirtualMemory,SizeStoredInPagingFiles,TotalVirtualMemorySize, TotalVisibleMemorySize,Status | Out-String } $Keyboard_info = { $ComputerName = $txt_ComputerName.Text $Keyboard = Get-CimInstance -Class Win32_Keyboard -ComputerName $ComputerName $lbl_sysinfo.Text = $Keyboard | FL -Property Description,Caption,NumberOfFunctionKeys | Out-String } $Mouse_info = { $ComputerName = $txt_ComputerName.Text $Mouse = Get-CimInstance -Class Win32_PointingDevice -ComputerName $ComputerName $lbl_sysinfo.Text = $Mouse | FL -Property Description,Name,HardwareType,Manufacturer | Out-String } $CDROM_info = { $ComputerName = $txt_ComputerName.Text $CDROM = Get-CimInstance -Class Win32_CDROMDrive -ComputerName $ComputerName $lbl_sysinfo.Text = $CDROM | FL -Property Drive,Name,Caption,Description,Manufacturer,MediaType,MfrAssignedRevisionLevel, CapabilityDescriptions,MediaLoaded | Out-String } $Sound_info = { $ComputerName = $txt_ComputerName.Text $Sound = Get-CimInstance -Class Win32_SoundDevice -ComputerName $ComputerName $lbl_sysinfo.Text = $Sound | FL -Property DeviceID,Name,Manufacturer,ProductName | Out-String } $Printers_info = { $ComputerName = $txt_ComputerName.Text $Printers = Get-CimInstance -Class Win32_Printer -ComputerName $ComputerName $lbl_sysinfo.Text = $Printers | FL -Property DeviceID,Name,HorizontalResolution,VerticalResolution,Default,DriverName,Direct,Network,Local, Hidden,KeepPrintedJobs,PrintJobDataType,PrintProcessor,PortName,Shared,ServerName,SpoolEnabled, WorkOffline,CapabilityDescriptions,Status | Out-String } $Software_info = { $ComputerName = $txt_ComputerName.Text $Software = Get-CimInstance -Class Win32_Product -ComputerName $ComputerName $lbl_sysinfo.Text = $Software | FL -Property Name,Version,Description,Vendor,InstallDate,InstallLocation,HelpLink,URLInfoAbout,URLUpdateInfo | Out-String } $Process_info = { $ComputerName = $txt_ComputerName.Text $Process = Get-CimInstance -Class Win32_Process -ComputerName $ComputerName $lbl_sysinfo.Text = $Process | FL -Property ProcessName,Path,CreationDate | Out-String } $Services_info = { $ComputerName = $txt_ComputerName.Text $Services = Get-CimInstance -Class Win32_Service -ComputerName $ComputerName $lbl_sysinfo.Text = $Services | FL -Property Name,DisplayName,Description,StartMode,Started,State,PathName | Out-String } Add-Type -AssemblyName System.Windows.Forms $MainForm = New-Object system.Windows.Forms.Form $MainForm.Text = "Computer Information" $MainForm.Size = New-Object System.Drawing.Size(1200,800) $MainForm.AutoScroll = $True $MainForm.MinimizeBox = $True $MainForm.MaximizeBox = $True $MainForm.WindowState = "Normal" $MainForm.SizeGripStyle = "Hide" $MainForm.ShowInTaskbar = $True $MainForm.Opacity = 1 $MainForm.StartPosition = "CenterScreen" $Font = New-Object System.Drawing.Font("Consolas",12,[System.Drawing.FontStyle]::Regular) $MainForm.Font = $Font $lbl_ComputerName = New-Object System.Windows.Forms.Label $lbl_ComputerName.Location = New-Object System.Drawing.Point(0,5) $lbl_ComputerName.Size = New-Object System.Drawing.Size(150,20) $lbl_ComputerName.Text = "Computer Name" $MainForm.Controls.Add($lbl_ComputerName) $lbl_sysinfo = New-Object System.Windows.Forms.Label $lbl_sysinfo.Location = New-Object System.Drawing.Point(155,50) $lbl_sysinfo.Size = New-Object System.Drawing.Size(500,500) $lbl_sysinfo.AutoSize = $True $lbl_sysinfo.Text = "" $MainForm.Controls.Add($lbl_sysinfo) $txt_ComputerName = New-Object System.Windows.Forms.TextBox $txt_ComputerName.Location = New-Object System.Drawing.Point(150,5) $txt_ComputerName.Size = New-Object System.Drawing.Size(200,20) $txt_ComputerName.Font = $Font $MainForm.Controls.Add($txt_ComputerName) $btn_System = New-Object System.Windows.Forms.Button $btn_System.Location = New-Object System.Drawing.Point(5,50) $btn_System.Size = New-Object System.Drawing.Size(145,25) $btn_System.Text = "System" $btn_System.Add_Click($System_info) $MainForm.Controls.Add($btn_System) $btn_BIOS = New-Object System.Windows.Forms.Button $btn_BIOS.Location = New-Object System.Drawing.Point(5,75) $btn_BIOS.Size = New-Object System.Drawing.Size(145,25) $btn_BIOS.Text = "BIOS" $btn_BIOS.Add_Click($bios_info) $MainForm.Controls.Add($btn_BIOS) $btn_CPU = New-Object System.Windows.Forms.Button $btn_CPU.Location = New-Object System.Drawing.Point(5,100) $btn_CPU.Size = New-Object System.Drawing.Size(145,25) $btn_CPU.Text = "CPU" $btn_CPU.Add_Click($cpu_info) $MainForm.Controls.Add($btn_CPU) $btn_RAM = New-Object System.Windows.Forms.Button $btn_RAM.Location = New-Object System.Drawing.Point(5,125) $btn_RAM.Size = New-Object System.Drawing.Size(145,25) $btn_RAM.Text = "RAM" $btn_RAM.Add_Click($ram_info) $MainForm.Controls.Add($btn_RAM) $btn_MB = New-Object System.Windows.Forms.Button $btn_MB.Location = New-Object System.Drawing.Point(5,150) $btn_MB.Size = New-Object System.Drawing.Size(145,25) $btn_MB.Text = "Motherboard" $btn_MB.Add_Click($mb_info) $MainForm.Controls.Add($btn_MB) $btn_PhysicalDrives = New-Object System.Windows.Forms.Button $btn_PhysicalDrives.Location = New-Object System.Drawing.Point(5,175) $btn_PhysicalDrives.Size = New-Object System.Drawing.Size(145,25) $btn_PhysicalDrives.Text = "Physical Drives" $btn_PhysicalDrives.Add_Click($PhysicalDrives_info) $MainForm.Controls.Add($btn_PhysicalDrives) $btn_LogicalDrives = New-Object System.Windows.Forms.Button $btn_LogicalDrives.Location = New-Object System.Drawing.Point(5,200) $btn_LogicalDrives.Size = New-Object System.Drawing.Size(145,25) $btn_LogicalDrives.Text = "Logical Drives" $btn_LogicalDrives.Add_Click($LogicalDrives_info) $MainForm.Controls.Add($btn_LogicalDrives) $btn_Graphics = New-Object System.Windows.Forms.Button $btn_Graphics.Location = New-Object System.Drawing.Point(5,225) $btn_Graphics.Size = New-Object System.Drawing.Size(145,25) $btn_Graphics.Text = "Graphics" $btn_Graphics.Add_Click($GPU_info) $MainForm.Controls.Add($btn_Graphics) $btn_Network = New-Object System.Windows.Forms.Button $btn_Network.Location = New-Object System.Drawing.Point(5,250) $btn_Network.Size = New-Object System.Drawing.Size(145,25) $btn_Network.Text = "Network" $btn_Network.Add_Click($Network_info) $MainForm.Controls.Add($btn_Network) $btn_Monitors = New-Object System.Windows.Forms.Button $btn_Monitors.Location = New-Object System.Drawing.Point(5,275) $btn_Monitors.Size = New-Object System.Drawing.Size(145,25) $btn_Monitors.Text = "Monitors" $btn_Monitors.Add_Click($Monitor_info) $MainForm.Controls.Add($btn_Monitors) $btn_OS = New-Object System.Windows.Forms.Button $btn_OS.Location = New-Object System.Drawing.Point(5,300) $btn_OS.Size = New-Object System.Drawing.Size(145,25) $btn_OS.Text = "OS" $btn_OS.Add_Click($OS_info) $MainForm.Controls.Add($btn_OS) $btn_Keyboard = New-Object System.Windows.Forms.Button $btn_Keyboard.Location = New-Object System.Drawing.Point(5,325) $btn_Keyboard.Size = New-Object System.Drawing.Size(145,25) $btn_Keyboard.Text = "Keyboard" $btn_Keyboard.Add_Click($Keyboard_info) $MainForm.Controls.Add($btn_Keyboard) $btn_Mouse = New-Object System.Windows.Forms.Button $btn_Mouse.Location = New-Object System.Drawing.Point(5,350) $btn_Mouse.Size = New-Object System.Drawing.Size(145,25) $btn_Mouse.Text = "Mouse" $btn_Mouse.Add_Click($Mouse_info) $MainForm.Controls.Add($btn_Mouse) $btn_CDROM = New-Object System.Windows.Forms.Button $btn_CDROM.Location = New-Object System.Drawing.Point(5,375) $btn_CDROM.Size = New-Object System.Drawing.Size(145,25) $btn_CDROM.Text = "CDROM" $btn_CDROM.Add_Click($CDROM_info) $MainForm.Controls.Add($btn_CDROM) $btn_Sound = New-Object System.Windows.Forms.Button $btn_Sound.Location = New-Object System.Drawing.Point(5,400) $btn_Sound.Size = New-Object System.Drawing.Size(145,25) $btn_Sound.Text = "Sound" $btn_Sound.Add_Click($Sound_info) $MainForm.Controls.Add($btn_Sound) $btn_Printers = New-Object System.Windows.Forms.Button $btn_Printers.Location = New-Object System.Drawing.Point(5,425) $btn_Printers.Size = New-Object System.Drawing.Size(145,25) $btn_Printers.Text = "Printers" $btn_Printers.Add_Click($Printers_info) $MainForm.Controls.Add($btn_Printers) $btn_Software = New-Object System.Windows.Forms.Button $btn_Software.Location = New-Object System.Drawing.Point(5,450) $btn_Software.Size = New-Object System.Drawing.Size(145,25) $btn_Software.Text = "Software" $btn_Software.Add_Click($Software_info) $MainForm.Controls.Add($btn_Software) $btn_Process = New-Object System.Windows.Forms.Button $btn_Process.Location = New-Object System.Drawing.Point(5,475) $btn_Process.Size = New-Object System.Drawing.Size(145,25) $btn_Process.Text = "Process" $btn_Process.Add_Click($Process_info) $MainForm.Controls.Add($btn_Process) $btn_Services = New-Object System.Windows.Forms.Button $btn_Services.Location = New-Object System.Drawing.Point(5,500) $btn_Services.Size = New-Object System.Drawing.Size(145,25) $btn_Services.Text = "Services" $btn_Services.Add_Click($Services_info) $MainForm.Controls.Add($btn_Services) $MainForm.ShowDialog()