Danny
 New Member Posts:10

 |
| 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 |
|
|
|
|
Danny
 New Member Posts:10

 |
| 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? |
|
|
|
|
SAPIENScripter
 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."
|
|
|
SAPIENScripter
 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.shaw Co-Community Director
 Basic Member Posts:188

 |
| 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 |
|
|
SAPIENScripter
 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  2}" -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."
|
|
|
Danny
 New Member Posts:10

 |
| 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 |
|
|
|
|
Danny
 New Member Posts:10

 |
| 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. |
|
|
|
|
SAPIENScripter
 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 2}" -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."
|
|
|
Danny
 New Member Posts:10

 |
| 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. |
|
|
|
|
SAPIENScripter
 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."
|
|
|
greeouss
 New Member Posts:2

 |
| 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()
}
} |
|
|
|
|
glnsize
 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 |
|
|
|
|