In one of my previous blog posts PowerShell: Documenting your environment by running systeminfo on all Domain-Computers I have described how to list important system information of all Domain Computers by running systeminfo. Now I want to paste it in a function. The name of this function will be Get-SystemInfo. What a surprise. I’m really a creative person. 🙂 And here it is.
The Goal
The approach is to gather all relevant Operating System information from all Domain Computer and/or Domain Servers or from one or more computers. It should look like this:
As mentioned, I’ve already prepared some stuff in a previous blog post. Now I want to go a huge step further.
Get-SystemInfo
The Parameters
Get-SystemInfo enables you to define a scope or computername. Pressing CTRL+Space lists all options. Two of them are particularly interesting.
A closer look at parameters …
Ok, I have to admit I’m not a professional developer who cares much about error and error conditions. But I try to provide some help. Pay attention to the description of the scope parameter.
Or simply type Get-SytemInfo -Scope and then press CTRL+Space.
Which brings me to the next part: Playing with Get-SystemInfo. Remember the parameter values. Now they come into play … and action …
Get-SystemInfo in Action: Defining a Scope
Query all Servers
Query all Domain-Controllers
Query all Client Computer (WinRM must be enabled, it’s disabled by default on all client operating systems)
For enabling WinRM with Group Policies see:
Query all Computers
Do you like it? Let’s keep going it’s not the end …
Get-SystemInfo in Action: Defining a Computer Name
Running on one Computer only
Running on multiple computer (separate them by comma)
Which brings me to the last part of this blog post. Actually, the most important thing. The function itsself.
The Function
Make sure you run the code an a Domain Controller or on a computer with RSAT installed.
function Get-SystemInfo { param ( [parameter(HelpMessage='Enter the following values: LocalHost, ServerOnly, DCOnly, ClientOnly or AllComputer')] [ValidateSet('LocalHost', 'ServerOnly', 'DCOnly', 'ClientOnly', 'AllComputer')] $Scope, $ComputerName ) $header='Host Name','OS','Version','Manufacturer','Configuration','Build Type','Registered Owner','Registered Organization','Product ID','Install Date','Boot Time','System Manufacturer','Model','Type','Processor','Bios','Windows Directory','System Directory','Boot Device','Language','Keyboard','Time Zone','Total Physical Memory','Available Physical Memory','Virtual Memory','Virtual Memory Available','Virtual Memory in Use','Page File','Domain','Logon Server','Hotfix','Network Card','Hyper-V' If ($Scope -eq 'ServerOnly') { Invoke-Command -ComputerName (Get-ADComputer -Filter {operatingsystem -like '*server*'}).Name {systeminfo /FO CSV | Select-Object -Skip 1} -ErrorAction SilentlyContinue | ConvertFrom-Csv -Header $header | Out-GridView } elseif ($Scope -eq 'DCOnly') { Invoke-Command -ComputerName (Get-ADDomainController -Filter *).Name {systeminfo /FO CSV | Select-Object -Skip 1} -ErrorAction SilentlyContinue | ConvertFrom-Csv -Header $header | Out-GridView } elseif ($Scope -eq 'LocalHost') {systeminfo /FO CSV | Select-Object -Skip 1 | ConvertFrom-Csv -Header $header | Out-GridView } elseif ($Scope -eq 'ClientOnly') { Invoke-Command -ComputerName (Get-ADComputer -Filter {operatingsystem -notlike '*server*'}).Name {systeminfo /FO CSV | Select-Object -Skip 1} -ErrorAction SilentlyContinue | ConvertFrom-Csv -Header $header | Out-GridView } elseif ($Scope -eq 'AllComputer') { Invoke-Command -ComputerName (Get-ADComputer -Filter *).Name {systeminfo /FO CSV | Select-Object -Skip 1} -ErrorAction SilentlyContinue | ConvertFrom-Csv -Header $header | Out-GridView } elseif ($ComputerName) { Invoke-Command -ComputerName $ComputerName {systeminfo /FO CSV | Select-Object -Skip 1} -ErrorAction SilentlyContinue | ConvertFrom-Csv -Header $header | Out-GridView } }
The script has grown over time. One of my followers pointed out to me that it would be better to work with switch instead lots of If and elseif. Thank you for the advice. Here is the function with switch. We can thus save some lines.
function Get-SystemInfo { param ( [parameter(HelpMessage='Enter the following values: LocalHost, ServerOnly, DCOnly, ClientOnly or AllComputer')] [ValidateSet('LocalHost', 'ServerOnly', 'DCOnly', 'ClientOnly', 'AllComputer')] $Scope, $ComputerName ) $header='Host Name','OS','Version','Manufacturer','Configuration','Build Type','Registered Owner','Registered Organization','Product ID','Install Date','Boot Time','System Manufacturer','Model','Type','Processor','Bios','Windows Directory','System Directory','Boot Device','Language','Keyboard','Time Zone','Total Physical Memory','Available Physical Memory','Virtual Memory','Virtual Memory Available','Virtual Memory in Use','Page File','Domain','Logon Server','Hotfix','Network Card','Hyper-V' switch ($Scope) { 'ServerOnly' {Invoke-Command -ComputerName (Get-ADComputer -Filter {operatingsystem -like '*server*'}).Name {systeminfo /FO CSV | Select-Object -Skip 1} -ErrorAction SilentlyContinue | ConvertFrom-Csv -Header $header | Out-GridView} 'DCOnly' {Invoke-Command -ComputerName (Get-ADDomainController -Filter *).Name {systeminfo /FO CSV | Select-Object -Skip 1} -ErrorAction SilentlyContinue | ConvertFrom-Csv -Header $header | Out-GridView} 'LocalHost' {systeminfo /FO CSV | Select-Object -Skip 1 | ConvertFrom-Csv -Header $header | Out-GridView} 'ClientOnly' {Invoke-Command -ComputerName (Get-ADComputer -Filter {operatingsystem -notlike '*server*'}).Name {systeminfo /FO CSV | Select-Object -Skip 1} -ErrorAction SilentlyContinue | ConvertFrom-Csv -Header $header | Out-GridView} 'AllComputer' {Invoke-Command -ComputerName (Get-ADComputer -Filter *).Name {systeminfo /FO CSV | Select-Object -Skip 1} -ErrorAction SilentlyContinue | ConvertFrom-Csv -Header $header | Out-GridView} } If ($ComputerName) { Invoke-Command -ComputerName $ComputerName {systeminfo /FO CSV | Select-Object -Skip 1} -ErrorAction SilentlyContinue | ConvertFrom-Csv -Header $header | Out-GridView } }
Make it permanent
If you like my approach open PowerShell ISE. Copy the function to your ISE session. Create a folder in C:\Program Files\Windows PowerShell\Modules and save the code as psm1 file. Make sure that your file name and folder name match.
Close PowerShell. Open PowerShell again. The command is now available for all users. Have fun with Get-SystemInfo!
See also
It’s worth taking a look at my other functions which are very useful for day-to-day tasks:
Test- FirewallAllServer: Query the Firewall status on all Windows Servers (enabled/disabled)
PowerShell: Notify me when someone is added to the Administrator Group
Categories: PowerShell, Windows 10, Windows Server
I dont see results, function not return any error. I want to see installed Disk
LikeLike
What are the necessary ports that must be opened from the firewall?
LikeLike
WinRM Must be enabled
LikeLike
Open port 5985 TCP?
LikeLike
Good Work Patrick. This is what i was looking for , It will add more value if you could add “Individual Computers” in scope and it will have comma separated computer names so that user can specify the choice of his own computers. The other most information missing here is about the Hard Disk info about computers. Also one suggestion if you rewrite this using these commandlets (Get-WmiObject or Get-CimInstance ) it will be much fast in bringing results.
LikeLiked by 1 person
Why use lots of If elseif’s instead of a single switch?
LikeLike
Thank your for the hint. This script had grown over a long time.Using a single switch is a nice idea. Both approaches will work as excpected.
LikeLike