1

I'm hoping I can get a helping hand here. I love linux shell scripting and I decided to give Windows Powershell a try for the following challenge and I'm failing miserably.

I want to run the following command which outputs the GPU temperature and CPU utilization as the 4th and 5th columns. If the 4th column falls below 50, or the 5th column falls below 80 I want to reboot my system.

"C:\Program Files\NVIDIA Corporation\NVSMI>nvidia-smi" --query-gpu=timestamp,name,pci.bus_id,temperature.gpu,utilization.gpu,utilization.memory --format=csv -l 5

Sample of what the command prints every 5 seconds:

2018/05/21 21:21:54.118, GeForce GTX 1060 6GB, 00000000:01:00.0, 63, 100 %, 93 %
2018/05/21 21:21:59.121, GeForce GTX 1060 6GB, 00000000:01:00.0, 64, 100 %, 95 %
2018/05/21 21:22:04.122, GeForce GTX 1060 6GB, 00000000:01:00.0, 64, 100 %, 94 %

I can easily do this with bash, how would I approach this with Powershell? I'm hoping learning this will get me to understand Powershell. Thanks.

2 Answers 2

1

I'm starting to get the hang of this. It's still magic to me that Powershell knows the actual names for the output. How is it doing that? Is it looking at the parameters I passed the command?

Here's my new code, which stops the ethminer process and restarts it if the temp is less than 50. The problem is that once it restarts ethminer I have it wait 120 seconds, but the next iteration of the loop is the temperature from 120 seconds ago. Do i have to break the loop or is there a cool Powershell way of telling it to use the last output?

$cmd = "& 'C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi' --query-gpu=timestamp,name,pci.bus_id,temperature.gpu,utilization.gpu,utilization.memory --format=csv -l 5"

invoke-expression $cmd | ConvertFrom-CSV | ForEach-Object {
  $_
  if ([int]$_.'temperature.gpu' -lt 50) {
    "temp $($_.'temperature.gpu') is less than 50 restarting ethminer"
    $process = Get-Process -Name "ethminer"
    Stop-Process -InputObject $process
    Get-Process | Where-Object {$_.HasExited}
    Start-Process "C:\Users\svill\Desktop\start - gpu 1.bat.lnk"
    Start-Sleep -s 120
  }
}

Update: Here is a working version of the code running the command over and over with 1 line of output:

$cmd = "& 'C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi' --query-gpu=timestamp,name,pci.bus_id,temperature.gpu,utilization.gpu,utilization.memory --format=csv"

while($true)
{
  invoke-expression $cmd | ConvertFrom-CSV | ForEach-Object {
    $_
    if ([int]$_.'temperature.gpu' -lt 45) {
      "temp $($_.'temperature.gpu') is less than 45 restarting ethminer"
      $process = Get-Process -Name "ethminer"
      Stop-Process -InputObject $process
      Get-Process | Where-Object {$_.HasExited}
      Start-Process "C:\Users\svill\Desktop\start - gpu 1.bat.lnk"
      Start-Sleep -s 60
    }
    Start-Sleep -s 5
  }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Select-Object -Last 1 from stackoverflow.com/questions/4546567/…
Alternatively, can nvidia-smi be told to only output one (1) line?
I tried Select-Object -Last 1 as the last line in the loop but unfortunately it did not work, so I went the route of running the command with the single output which worked out great.
Operations to reduce data should go as early in the pipeline as possible. I would probably put Select-Object -Last 1 after (or before) ConvertFrom-CSV.
@lit let's say i have 6 lines of GPU stats that are output with a single run of the command and i wanted to print those later, would i have to create an array to store it for retrieval?
|
0

The biggest hurdle to overcome is the object orientation of PowerShell.

To start you on some familiar territory, you could use a regex to parse the numbers out of the string.

PS C:\src\t> $s = '2018/05/21 21:21:54.118, GeForce GTX 1060 6GB, 00000000:01:00.0, 63, 100 %, 93 %'
PS C:\src\t> $s -match '.*, (\d*) %, (\d*) %$'
True
PS C:\src\t> $Matches

Name                           Value
----                           -----
2                              93
1                              100
0                              2018/05/21 21:21:54.118, GeForce GTX 1060 6GB, 00000000:01:00.0, 63, 100 %, 93 %


PS C:\src\t> $Matches[1]
100
PS C:\src\t> $Matches[2]
93

Show us some of the code you might create from this and someone will probably have suggestions on going further.

2 Comments

It's being exported as csv. He can literally just pipe to convertfrom-csv
OK so i just tried the following and it's blowing my mind: $cmd = "& 'C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi' --query-gpu=timestamp,name,pci.bus_id,temperature.gpu,utilization.gpu,utilization.memory --format=csv -l 5" invoke-expression $cmd | ConvertFrom-CSV It automatically associated labels like timestamp and name to the proper values - MAGIC.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.