header
header Register : : Login header
header
divider
menuleft
menuright
submenu
left

[August 25th, 2008] Check the home page regarding PowerShell related news from a brand new sponsor: Idera

Calculating CPU Usage?
Last Post 01 Sep 2008 02:53 PM by glnsize. 12 Replies.
Printer Friendly
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
DannyUser is Offline
New Member
New Member
Posts:10
Avatar

--
27 Jan 2008 09:33 PM  

HEy guys,

i wrote a small script to calculate the CPU Usage of each task running on a machine. My problem is now, that whenever i try to calculate the CPU Usage is get the result "infinite". I also dont wanna use the powershell gadgets because i wanna keep the requirements as low as possible. Maybe someone can give me a hint, i think it depends on the decimal places.

btw: Where is the edit-button^^ ?

[QUOTE]


set-variable timespan -value 10 -option constant

function CPUcalc ($a , $b)
{
    return ($a / $b * 100)
}


$Processes = get-process
$Processes= $Prozesse.count



$a1 = get-process | sort-object name | select-object CPU;
$b = get-process | sort-object name | select-object Name;
$c = get-process | sort-object name | select-object Description;

$a1 | forEach-Object {$arrayA1 += ,$_.CPU};
$b | forEach-Object {$arrayB += ,$_.Name};
$c | forEach-Object {$arrayC += ,$_.Description};


$starttime = (get-date);


sleep $timespan


$a2 = get-process | sort-object name | select-object CPU;
$a2 | forEach-Object {$arrayA2 += ,$_.CPU}



$endtime = (get-date)

[double]$count = new-timespan -Start ($StartZeit) -End ($Endzeit) | Format-List TotalSeconds
$count = "{0:N4}" -f $count;


#zum NullArrayumgehen
$lv =0
do
{$CPUDifferenz = $ArrayA2[$lv] - $ArrayA1[$lv];
if ($CPUDifference -eq 0) {$CPUUsage = 0}
#elseif ($arrayA1[$lv] -gt $Arraya2[$lv]) {write-warning "Error, StartCPU bigger EndCPU"}
else {$CPULast = CPUcalc $CPUDifference $count};
write-host -f green "Processname:" $arrayb[$lv];
write-host -f green "Description:" $arrayc[$lv];
write-host -f green "StartCPU:" $arrayA1[$lv];
write-host -f green "EndCPU:" $arrayA2[$lv];
write-host -f yellow "CPU-Usage: "$CPUUsage;
write-host -f green "Process: "($lv+1);
write-host -f red "CPU-Difference:" $CPUDifference;
$lv++;}
until ($lv -eq ($Processes));
write-host "Prozesse insgesamt:" $Processes;

[/QUOTE]

 

I tried to translate every variables, so if theres something dont working i might oversaw one.

 

 

THX GUYS



DannyUser is Offline
New Member
New Member
Posts:10
Avatar

--
28 Jan 2008 08:48 AM  
Hm i think i got my mistake. I always get the message, that i cannot convert "System.Object" to "System.%Datatype%". Is there a script or a function/method for doing this?


SAPIENScripterUser is Offline
New Member
New Member
Posts:45

--
28 Jan 2008 03:29 PM  
I think if you get in the PowerShell mindset, this will be a little easier to accomplish. Here's a more efficient PowerShell way to get you started.

$ProcBefore=Get-Process

sleep -Seconds 60

$procAfter=Get-Process

foreach ($p in $ProcBefore) {
$procAfter | where {$_.id -eq $p.id} -OutVariable z | Out-Null
if (($p.cpu) - ($z[0].CPU) -gt 0 ) {
Write-Host -ForegroundColor red ($p.id) ($p.name) BEFORE:($p.CPU) AFTER: ($z[0].CPU)
} else
{
Write-Host ($p.id) ($p.name) BEFORE:($p.CPU) AFTER: ($z[0].CPU)
}

}

I'm still trying somethings out to make your script more Powershell-ish. But I wanted to at least give you this.


Jeffery Hicks
Microsoft PowerShell MVP
http://blog.sapien.com
http://www.scriptinganswers.com

"Those who forget to script are doomed to repeat their work."
SAPIENScripterUser is Offline
New Member
New Member
Posts:45

--
28 Jan 2008 03:30 PM  
replace each sad face with a colon : and a (


Jeffery Hicks
Microsoft PowerShell MVP
http://blog.sapien.com
http://www.scriptinganswers.com

"Those who forget to script are doomed to repeat their work."
marco.shawUser is Offline
Co-Community Director
Basic Member
Basic Member
Posts:188
Avatar

--
28 Jan 2008 03:33 PM  
Glad to see Jeff is checking this out.

As for me, I copied your script as is. It has several errors in it where you are trying to translate stuff into English: some variables have had their name changed, but you haven't changed all the references to the variable throughout the script.

Consider reposting, and maybe just leave your variables as is, and don't try to make any language changes.


Marco

*Microsoft MVP - Windows PowerShell: http://www.microsoft.com/mvp
*PowerGadgets MVP: http://www.powergadgets.com/mvp
*Blog: http://marcoshaw.blogspot.com
SAPIENScripterUser is Offline
New Member
New Member
Posts:45

--
28 Jan 2008 04:02 PM  
I can't seem to get my CPU values to change so I tested by looking at the workingset property. Is this along the lines of what you are after?

foreach ($p in $ProcBefore) {
$procAfter | where {$_.id -eq $p.id} -OutVariable z | Out-Null
if (($z[0].workingset)-($p.workingset) -gt 0 ) {
$usage="{0:P2}" -f (1-(($p.workingset)/($z[0].workingset)))
$color="RED"
}
else
{
$usage="0 %"
$color="WHITE"
Write-Host ($p.id) ($p.name) BEFORE: ($p.workingset) AFTER: ($z[0].workingset)
}

Write-Host -ForegroundColor $color ($p.id) ($p.name)
Write-Host -ForegroundColor $color BEFORE: ($p.workingset) AFTER: ($z[0].workingset)
Write-Host -ForegroundColor $color Usage: $usage
}



Jeffery Hicks
Microsoft PowerShell MVP
http://blog.sapien.com
http://www.scriptinganswers.com

"Those who forget to script are doomed to repeat their work."
DannyUser is Offline
New Member
New Member
Posts:10
Avatar

--
29 Jan 2008 07:43 AM  

At the moment i still try to understand your script(s) correctly. In the meanwhile i developed a working version for me but i am exerted to get a more "powershell-ish" understanding ;)

 

Btw what does this "($z.]" mean or better how does it work? Nevertheless i will google it, but maybe you have the best explanation.

 

Thanks for your help



DannyUser is Offline
New Member
New Member
Posts:10
Avatar

--
29 Jan 2008 07:49 AM  
#Time to Sleep
set-variable Zeitraum -value 3 -option constant

#Alerts
set-variable -name CPURot -value 2 -option constant
set-variable -name CPUGelb -value 0.5 -option constant


function CPUcalc ($a , $b)
{
return ($a / $b * 100)
}

#Number of Processes
$Prozesse = (get-process).count

get-process | sort-object Name | select-object CPU, Name, Description | ForEach-Object {$ArrayStartCPU += ,$_.CPU; $ArrayName += ,$_.Name; $ArrayDesc += ,$_.Description};

sleep $Zeitraum

get-process | sort-object Name | select-Object CPU | ForEach-Object {$ArrayEndCPU += ,$_.CPU};

$i =0

do
{$CPUDifferenz = $ArrayEndCPU[$i] - $ArrayStartCPU[$i];
$CPULast = CPUcalc $CPUDifferenz $Zeitraum; $CPULast = "{0:N4}" -f $CPULast;$AName = $ArrayName[$i]; $ADesc = $ArrayDesc[$i];
if ($CPULast -ge $CPURot) {write-host -f red $CPULast}
elseif (($CPULast -lt $CPURot) -AND ($CPULast -ge $CPUGelb)) {write-host -f yellow $CPULast}
else {write-host -f green $CPULast}
$i++}

until ($i -eq ($Prozesse));



This is btw my solution.


SAPIENScripterUser is Offline
New Member
New Member
Posts:45

--
29 Jan 2008 01:10 PM  

Your new code is better and certainly more PowerShell like.  I've revised my sample and added inline comments to better explain what is happening.


# Take a snapshot of running processes
$ProcBefore=Get-Process

#sleep for some specified number of seconds
Write-Host "Sleeping..."
sleep -Seconds 60

# Take an "after" snapshot of running processes
$procAfter=Get-Process

# enumerate each process object in the before process
# object set
foreach ($p in $ProcBefore) {

# pipe the "after" process object to Where-Object
# looking for the matching process in the "before"
# set.  I'm matching on the ID property.  The matching
# process will be saved to variable $z
# The expression is piped to out-null so the result
# isn't displayed to the screen
 $procAfter | where {$_.id -eq $p.id} -OutVariable z | Out-Null
 
# $z is technically an array with one element, so I use
# [0] to get the first element.  I'm looking at the
# workingset property of this object.  Remember, this
# is the matching process in the "after" snapshot.
# If the value of of the after process's workingset
# minus the before process workingset is greater than 0
# then I know there was an increase in workingset size

 if (($z[0].workingset)-($p.workingset) -gt 0 ) {

# $usage is a variable showing the result
# of the before process workingset/after process workingset
# and formatted using the .NET format operator, -f
# as a percentage.

#if you see a smiley it should be replaced with

#{ 0 : P2}  Just take out the spaces
  $usage="{0:P2}" -f (1-(($p.workingset)/($z[0].workingset)))

# defined a variable for later use with write-host
  $color="RED"
 }
 else
 {
 # there was no difference so set default variables
  $usage="0 %"
  $color="WHITE"
 }
# write the results to the screen
Write-Host -ForegroundColor $color ($p.id) ($p.name)
Write-Host -ForegroundColor $color BEFORE: ($p.workingset) AFTER: ($z[0].workingset)
Write-Host -ForegroundColor $color Usage: $usage
}


Essentially $p is the current "before" process and $z[0] is the "after" process.  You can list or compare as many properties as you want.  In your function, you need to make sure that $b is greater than 0 or you will get a divide by 0 error.



Jeffery Hicks
Microsoft PowerShell MVP
http://blog.sapien.com
http://www.scriptinganswers.com

"Those who forget to script are doomed to repeat their work."
DannyUser is Offline
New Member
New Member
Posts:10
Avatar

--
30 Jan 2008 02:37 PM  
Hi SAPIENScripter,
i tried to adapt your script, but i dont even get it running for my workingset. i mainly get the error "Unexpected token ']' in expression or statement." which refers always to your array "($zΎ]".
Maybe i still didnt got that point how your declaration worked.


SAPIENScripterUser is Offline
New Member
New Member
Posts:45

--
30 Jan 2008 03:42 PM  

The problem is that the site is mangling my code.  It should be $z [ 0 ] but without the spaces. 

I've attached my script as a text file.  Save it locally and rename with a .ps1 extension.


Attachment: 1130464014071.txt

Jeffery Hicks
Microsoft PowerShell MVP
http://blog.sapien.com
http://www.scriptinganswers.com

"Those who forget to script are doomed to repeat their work."
greeoussUser is Offline
New Member
New Member
Posts:2
Avatar

--
01 Sep 2008 08:44 AM  

Hello to everyone, this is my first post. Maybe somone helps.  About the post, see that everybody uses get-process, and that is useless with remote machines. I made a function for that  asking wmi (works as estimate between two sample, its not exact)

pd, sorry my english ;-)

#----------------------------------------------------------------------------------------------------------------------------------------------

function cpu-usage
 { if ($Args)
        {$machine=$Args}
    else
        {$machine="localhost"}
      
#loop to refresh information cpu usage            
 while($auxiliary -ne 'Q')
       {

#first sample of processes
$before   = gwmi win32_perfrawdata_perfproc_process -ComputerName $machine
sleep -Milliseconds (100)

#second sample of processes
$after = gwmi win32_perfrawdata_perfproc_process -ComputerName $machine

#hash list with the difference of two samples
$difference = @{}
#array with cpu percentage for each process
$result = @{}


#compare two samples and store difference in $difference["processname"]
foreach ($process_before in $before)
{ foreach ($process_after in $after)
    { if ($process_after.name -eq $process_before.name)
        {$difference_process = [long]$process_after.percentprocessortime -[long]$process_before.percentprocessortime
         $difference[$process_before.name] = $difference_process      
        }
    }
}

#total cpu time
$sum = $difference["_Total"]

#with all processes, we calculate percentaje
foreach ($i in $difference.keys)
    {$result[$i] = ((($difference.$i)/$sum)*100)
    }

          
#sort array descending
$result= (($result.GetEnumerator() | sort value -Descending)[1..10])

  
      Clear-Host
      Write-Host ""
      Write-Host "press Q to quit, another key to refresh"
    
     format-table -AutoSize -InputObject $result @{Label= "Name:"; Expression = {$_.name}},`
        @{Label = "percentaje CPU"; Expression= {"{0:n2}" -f ($_.Value)}}
      
        $auxiliary = $Host.UI.RawUI.ReadKey()
        $auxiliary = [string]$auxiliary.character
        $auxiliary=$auxiliary.toupper()       
        }      
}



glnsizeUser is Offline
Basic Member
Basic Member
Posts:101

--
01 Sep 2008 02:53 PM  

there is a lot of good content in all of those scripts.  A bit of a side note if you ever see Ύ] in a script posted on these forums.  It was intended to read [ 0 ].  When posting put a space between the brackets and the integer... This space will not effect powershell but it will render correctly on the forums.

Or

Just post it to http://poshcode.org and link back.

~Glenn



You are not authorized to post a reply.

Active Forums 4.1
right
   
footer Sponsored by Quest Software • SAPIEN Technologies • ShellTools, LLC • Microsoft Windows Server 2008 footer
footer