Run script to check CPU and Memory utilization

If you would like to quickly display CPU and Memory utilization in PowerShell console then this script is for you. This is another great example on how to use PowerShell custom objects and add it to array.

CPU and Memory utilization

In past I often had this situation when one of the servers was unresponsive due to high performance which was causing service interruption. Unfortunately SCOM server didn’t catch that CPU or Memory sudden spike and I had to scan all of our servers manually to find what is happening. This is why the following script has been created to avoid similar cases in the future and to quickly identify culprit.

Script is based on Get-WmiObject commands:

# Processor utilization
$Processor = (Get-WmiObject -ComputerName $Server -Class win32_processor -ErrorAction Stop | Measure-Object -Property LoadPercentage -Average | Select-Object Average).Average
 
# Memory utilization
$ComputerMemory = Get-WmiObject -ComputerName $Server -Class win32_operatingsystem -ErrorAction Stop
$Memory = ((($ComputerMemory.TotalVisibleMemorySize - $ComputerMemory.FreePhysicalMemory)*100)/ $ComputerMemory.TotalVisibleMemorySize)
$RoundMemory = [math]::Round($Memory, 2)

Output (Script 2):

CPU and Memory
CPU and Memory

Script 1:


    $Servers = Get-Content "C:\users\$env:username\desktop\servers.txt"
    $Array = @()
  
    ForEach ($Server in $Servers) {
        $Check = $Processor = $ComputerMemory = $RoundMemory = $Object = $null
        $Server = $Server.trim()

        Try {
            # Processor utilization
            $Processor = (Get-WmiObject -ComputerName $Server -Class win32_processor -ErrorAction Stop | Measure-Object -Property LoadPercentage -Average | Select-Object Average).Average
  
            # Memory utilization
            $ComputerMemory = Get-WmiObject -ComputerName $Server -Class win32_operatingsystem -ErrorAction Stop
            $Memory = ((($ComputerMemory.TotalVisibleMemorySize - $ComputerMemory.FreePhysicalMemory)*100)/ $ComputerMemory.TotalVisibleMemorySize)
            $RoundMemory = [math]::Round($Memory, 2)
            
            # Creating custom object
            $Object = New-Object PSCustomObject
            $Object | Add-Member -MemberType NoteProperty -Name "Server name" -Value $Server
            $Object | Add-Member -MemberType NoteProperty -Name "CPU %" -Value $Processor
            $Object | Add-Member -MemberType NoteProperty -Name "Memory %" -Value $RoundMemory

            $Object
            $Array += $Object
        }
        Catch {
            Write-Host "Something went wrong ($Server): "$_.Exception.Message
            Continue
        }
    }

    #Final results
    If ($Array) { 
        $Array | Out-GridView -Title "CPU and Memory"
        $Array | Export-Csv -Path "C:\users\$env:username\desktop\results.csv" -NoTypeInformation -Force
    }

Script 2:

$Servers = Get-Content "C:\users\$env:username\desktop\servers.txt"
$Array = @()
 
ForEach($Server in $Servers)
{
    $Server = $Server.trim()

    Write-Host "Processing $Server"

    $Check = $null
    $Processor = $null
    $ComputerMemory = $null
    $RoundMemory = $null
    $Object = $null

    # Creating custom object
    $Object = New-Object PSCustomObject
    $Object | Add-Member -MemberType NoteProperty -Name "Server name" -Value $Server

    $Check = Test-Path -Path "\\$Server\c$" -ErrorAction SilentlyContinue

    If($Check -match "True")
    {
        $Status = "True"

        Try
        {
            # Processor utilization
            $Processor = (Get-WmiObject -ComputerName $Server -Class win32_processor -ErrorAction Stop | Measure-Object -Property LoadPercentage -Average | Select-Object Average).Average
 
            # Memory utilization
            $ComputerMemory = Get-WmiObject -ComputerName $Server -Class win32_operatingsystem -ErrorAction Stop
            $Memory = ((($ComputerMemory.TotalVisibleMemorySize - $ComputerMemory.FreePhysicalMemory)*100)/ $ComputerMemory.TotalVisibleMemorySize)
            $RoundMemory = [math]::Round($Memory, 2)
        }
        Catch
        {
            Write-Host "Something went wrong" -ForegroundColor Red
            Continue
        }

        If(!$Processor -and $RoundMemory)
        {
            $RoundMemory = "(null)"
            $Processor = "(null)"
        }

        $Object | Add-Member -MemberType NoteProperty -Name "Is online?" -Value $Status
        $Object | Add-Member -MemberType NoteProperty -Name "Memory %" -Value $RoundMemory
        $Object | Add-Member -MemberType NoteProperty -Name "CPU %" -Value $Processor

        # Display resutls for single server in realtime
        #$Object
 
        # Adding custom object to our array
        $Array += $Object
    }
    Else
    {
        $Object | Add-Member -MemberType NoteProperty -Name "Is online?" -Value "False"
        $Object | Add-Member -MemberType NoteProperty -Name "Memory %" -Value "(null)"
        $Object | Add-Member -MemberType NoteProperty -Name "CPU %" -Value "(null)"
        
        # Display resutls for single server in realtime
        #$Object
 
        # Adding custom object to our array
        $Array += $Object
    }
}  

    If($Array)
    { 
        $Array | Sort-Object "Is online?" 

        #$Array | Out-GridView
 
        #$Array | Export-Csv -Path "C:\users\$env:username\desktop\results.csv" -NoTypeInformation -Force
    }

Please check also article about getting memory utilization report – link.

6 thoughts on “Run script to check CPU and Memory utilization

  1. Great!!
    Works perfectly fine for the remote servers which are in same domain. How do we get the same for servers in different domain.

    1. Hi Varun,
      You have to add -Credential parameter in Get-WMIObject commands:

      $Servers = Get-Content “C:\users\$env:username\desktop\servers.txt”
      $Array = @()
      $Cred = Get-Credential “domain\$env:username”
      ForEach($Server in $Servers)
      {
      $Server = $Server.trim()

      Write-Host “Processing $Server”

      $Check = $null
      $Processor = $null
      $ComputerMemory = $null
      $RoundMemory = $null
      $Object = $null

      # Creating custom object
      $Object = New-Object PSCustomObject
      $Object | Add-Member -MemberType NoteProperty -Name “Server name” -Value $Server

      $Check = Test-Path -Path “\\$Server\c$” -ErrorAction SilentlyContinue

      If($Check -match “True”)
      {
      $Status = “True”

      Try
      {
      # Processor utilization
      $Processor = (Get-WmiObject -ComputerName $Server -Class win32_processor -ErrorAction Stop -Credential $Cred | Measure-Object -Property LoadPercentage -Average | Select-Object Average).Average

      # Memory utilization
      $ComputerMemory = Get-WmiObject -ComputerName $Server -Class win32_operatingsystem -ErrorAction Stop -Credential $Cred
      $Memory = ((($ComputerMemory.TotalVisibleMemorySize – $ComputerMemory.FreePhysicalMemory)*100)/ $ComputerMemory.TotalVisibleMemorySize)
      $RoundMemory = [math]::Round($Memory, 2)
      }
      Catch
      {
      Write-Host “Something went wrong” -ForegroundColor Red
      Continue
      }

      If(!$Processor -and $RoundMemory)
      {
      $RoundMemory = “(null)”
      $Processor = “(null)”
      }

      $Object | Add-Member -MemberType NoteProperty -Name “Is online?” -Value $Status
      $Object | Add-Member -MemberType NoteProperty -Name “Memory %” -Value $RoundMemory
      $Object | Add-Member -MemberType NoteProperty -Name “CPU %” -Value $Processor

      # Display resutls for single server in realtime
      #$Object

      # Adding custom object to our array
      $Array += $Object
      }
      Else
      {
      $Object | Add-Member -MemberType NoteProperty -Name “Is online?” -Value “False”
      $Object | Add-Member -MemberType NoteProperty -Name “Memory %” -Value “(null)”
      $Object | Add-Member -MemberType NoteProperty -Name “CPU %” -Value “(null)”

      # Display resutls for single server in realtime
      #$Object

      # Adding custom object to our array
      $Array += $Object
      }
      }

      If($Array)
      {
      $Array | Sort-Object “Is online?”
      }

  2. Hello

    I want to get CPU , Memory , Disk and Network utilization of one single process in a computer can you please help me in tweaking the script for achieving that

    For example now it gives average CPU & Memory of the whole computer

    But I want the CPU, Memory , Disk & Network for a single process like Google Chrome

    1. Could you please clarify what exactly do you need? Which netowrk or disk details?
      You can try this for some performance details too:
      $Servers = “Server01”,
      “Server02”,
      “Server03”,
      “Server04”,
      “Server05”,
      “Server06”,
      “Server07”

      $Process = “Notepad”
      $Results = @()

      Try {
      $Results = icm -cn $Servers {param($Process)

      $Processes = Get-process $Process
      foreach($Process in $Processes){
      $ScriptPerfData = Get-WmiObject -Class Win32_PerfFormattedData_PerfProc_Process | Where {$_.IDProcess -eq $Process.id} |
      Select-Object ElapsedTime,IODataBytesPersec,IODataOperationsPersec,IOOtherBytesPersec,IOOtherOperationsPersec,IOReadBytesPersec,IOReadOperationsPersec,IOWriteBytesPersec,IOWriteOperationsPersec
      If($ScriptPerfData) {
      $Obj = New-Object psobject
      $Obj | Add-Member -MemberType NoteProperty -Name Name -Value $Process.Name
      $Obj | Add-Member -MemberType NoteProperty -Name Id -Value $Process.Id
      $Obj | Add-Member -MemberType NoteProperty -Name Mem -Value $Process.VM
      $Obj | Add-Member -MemberType NoteProperty -Name CPU -Value $Process.CPU
      $Obj | Add-Member -MemberType NoteProperty -Name ElapsedTime -Value $ScriptPerfData.ElapsedTime
      $Obj | Add-Member -MemberType NoteProperty -Name IODataBytesPersec -Value $ScriptPerfData.IODataBytesPersec
      $Obj | Add-Member -MemberType NoteProperty -Name IODataOperationsPersec -Value $ScriptPerfData.IODataOperationsPersec
      $Obj | Add-Member -MemberType NoteProperty -Name IOReadOperationsPersec-Value $ScriptPerfData.IOReadOperationsPersec
      $Obj | Add-Member -MemberType NoteProperty -Name IOWriteBytesPersec -Value $ScriptPerfData.IOWriteBytesPersec
      $Obj | Add-Member -MemberType NoteProperty -Name IOWriteOperationsPersec -Value $ScriptPerfData.IOWriteOperationsPersec
      $Obj
      }
      }
      } -ArgumentList $Process | Select-Object @{n=’ServerName’;e={$_.pscomputername}}, Name,Id,VM,CPU,ElapsedTime,IODataBytesPersec,IODataOperationsPersec,IOOtherBytesPersec,IOOtherOperationsPersec,IOReadBytesPersec,IOReadOperationsPersec,IOWriteBytesPersec,IOWriteOperationsPersec
      }
      Catch {
      $_.Exception.Message;
      Exit
      }

      $Results | Out-GridView -Title “Results”

      1. In the Windows TaskManager under Processes tab you have Apps running

        I want to get the CPU , Memory , Disk and Network usgaes for a single App

        I also want to get the values in a interval of 5 seconds

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.