I want to read temperature sensors from my motherboard in PowerShell 5.1. Unfortunately the corresponding WMI-object won't fetch new values if I call it more than once. Even restarting PowerShell won't help. The only way to get new data is to reboot my PC and run the code again...
My code:
Write-Host "Temperatures:"
Write-Host "-------------"
$ThermalZones = Get-WmiObject -Class MSAcpi_ThermalZoneTemperature -Namespace "root/wmi"
$ThermalZones = $ThermalZones | Where -Property CurrentTemperature -gt 0
$ThermalZones | ForEach {"$($_.InstanceName.Replace('ACPI\ThermalZone\', '')): $($_.CurrentTemperature / 10 - 273) [°C]"}
I noticed there is a "SamplingPeriod" property for each zone which is 0 by default every time I re-run the code but changing it seems to have no effect... Can I somehow force a refresh?
The temperature is updated, if Speedfan is started.
This is one way to force the refresh.
Or log off an log on again.
Unfortunately the parameter SamplingPeriod can not be set but only requested.
Related
I have the following script to measure the current cpu clock rate from this [link][1].
$MaxClockSpeed = (Get-CimInstance CIM_Processor).MaxClockSpeed
$ProcessorPerformance = (Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance").CounterSamples.CookedValue
$CurrentClockSpeed = $MaxClockSpeed*($ProcessorPerformance/100)
I am looking to test the performance of the CPU to see how far it can go in terms of frequency.
The reason for this is that we have a few machines that are faulty out of our hundreds of machines, and it turns out that when you push them a bit, their clock rate doesn't change and stays at around 20% utilization. This would allow us, via our monitoring system, to find them easily.
Is there a way to programmatically via powershell to make an intensive task during or just before capturing the actual clock speed to know how far it can get? Something like a loop or something?
[1]: Unable to get current CPU frequency in Powershell or Python
I found something interesting on this website.
So to make the cpu work at 100% for a short time, I can use a background job:
$NumberOfLogicalProcessors = Get-WmiObject win32_processor | Select-Object -ExpandProperty NumberOfLogicalProcessors
ForEach ($core in 1..$NumberOfLogicalProcessors){
start-job -ScriptBlock{
$result = 1;
foreach ($loopnumber in 1..2147483647){
$result=1;
foreach ($loopnumber1 in 1..2147483647){
$result=1;
foreach($number in 1..2147483647){
$result = $result * $number
}
}
$result
}
}
}
Read-Host "Press any key to exit..."
Stop-Job *
It makes the cpu go usually at 100% of utilization. During that time I can easily run the script:
$MaxClockSpeed = (Get-CimInstance CIM_Processor).MaxClockSpeed
$ProcessorPerformance = (Get-Counter -Counter "\Processor Information(_Total)\% Processor Performance").CounterSamples.CookedValue
$CurrentClockSpeed = $MaxClockSpeed*($ProcessorPerformance/100)
For instance, in my case, when I test the $processorPerformance I get "107.998029830411" as an example, so this shows My processor works fine when I push it.
N.B I must add the Start-sleep -Seconds 20 parameter while the background tasks are running, because on all the machines it takes around 15 seconds until the x logical processors are running at 100%.
As the title states, I have a .bat job running within PowerShell that when finished running, I would like a sound notification to go off. I was wondering if there was a PowerShell command that I can add to my existing PowerShell command.
In addition to the solutions #TheGameiswar suggests, you can have some fun by making the system actually speak to you:
# Create a new SpVoice objects
$voice = New-Object -ComObject Sapi.spvoice
# Set the speed - positive numbers are faster, negative numbers, slower
$voice.rate = 0
# Say something
$voice.speak("Hey, Harcot, your BAT file is finished!")
Note: I only tested this on Windows 10, so it may not work on other versions, but give it a go and see.
Besides the excellent solutions of boxdog (here) and TheGameiswar (here), I want to mention another possibility, which lets you play some standard system sounds:
[System.Media.SystemSounds]::Asterisk.Play()
[System.Media.SystemSounds]::Beep.Play()
[System.Media.SystemSounds]::Exclamation.Play()
[System.Media.SystemSounds]::Hand.Play()
[System.Media.SystemSounds]::Question.Play()
Another text-to-speech approach
Add-Type -AssemblyName System.Speech
$synth = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer
$synth.Speak("Hey $env:USERNAME, your job is finished!")
Customization
For full details, read the docs.
Voice
Select a voice:
$synth.SelectVoice("Microsoft Zira Desktop")
You can view available voices with:
$synth.GetInstalledVoices() | Select-Object -ExpandProperty VoiceInfo
Rate
Set the speaking rate from -10 (slow) through 10 (fast):
$synth.Rate = 5
Volume
Set the volume from 0 (quiet) through 100 (loud):
$synth.Volume = 75
you could use powershell automatic variables to check bat file status ..As per this,$? returns true ,if command is successfull..
below is sample code
$a =Invoke-Command -ScriptBlock {
& "C:\temp1\test.bat"
}
if($?){
[console]::beep(500,300)
}
You could also play custom sounds,
$PlayWav=New-Object System.Media.SoundPlayer
$PlayWav.SoundLocation=’C:\Foo\Soundfile.wav’
$PlayWav.playsync()
references:
https://devblogs.microsoft.com/scripting/powertip-use-powershell-to-play-wav-files/
I have to get by PowerShell command the ammount of free memory size (the same that I see in the Performance Monitor GUI):
I have searched on each parameter seen on the following command output:
Get-WmiObject Win32_OperatingSystem | fl *free*
but I haven't found anything useful.
Could you help me please?
The Win32_OperatingSystem class provides a global view on the free memory. As Avshalom already pointed out you need to query a different WMI class (Win32_PerfFormattedData_PerfOS_Memory), since you're looking for a particular portion of the total free memory.
Subtract the two standby cache sizes from the available bytes to get the desired value:
Get-WmiObject Win32_PerfFormattedData_PerfOS_Memory | ForEach-Object {
$_.AvailableBytes - ($_.StandbyCacheNormalPriorityBytes + $_.StandbyCacheReserveBytes)
}
Divide the result by 1MB to get the value in megabytes instead of bytes.
I want to invoke the command
$myArray = Get-Wmiobject -Class Win32-printer
But, on rare occasions, this command sometimes never fails nor succeed, returning the list of available printer.
I would like to assign $myArray only if the invocation takes less than a few seconds, lets say 5. Otherwise, I want to display a dialog telling that printers are unavailable at this moment.
How to start a powershell block with a timeout?
You can use a job for that:
$job = Start-Job { Get-Wmiobject -Class Win32-printer }
$job | Wait-Job -Timeout 5
if ($job.State -eq 'Running') {
# Job is still running, cancel it
$job.StopJob()
} else {
# Job completed normally, get the results
$myArray = $job | Receive-Job
}
I would say to create your own customized WMI queries using type casting and the native .NET providers. This way the work is still being done in the same opened console and you have physical control on the time outs.
I basically had the same frustration as you did. I would be querying servers all day until I hit the one that had a broken WMI. After so much, I started researching how to create my own WMI function to get around this. That was my solution to the problem. Learned a lot along the way.
Here is an article to help you along your way.
http://stevenmurawski.com/powershell/2009/01/dealing-with-wmi-timeouts/
Just to add to the above- powershell also has a built in stopwatch diagnostic for timeout functionality.
https://technet.microsoft.com/en-us/magazine/2009.03.heyscriptingguy.aspx
In a PowerShell script I am trying to get the number of page faults per second with this command:
(Get-WmiObject Win32_PerfFormattedData_PerfOS_memory).PageFaultsPersec
Unfortunately, it reads always the same value because I don't Refresh() the performance counter.
How can I send a Refresh() method to Performance Data via PowerShell?
You can get the value using performance counters:
Get-Counter '\Memory\Page Faults/sec'
However, if I call you code in a loop, it works without problems (although it is better practise to first store the wmi object).
1..10 | % { sleep -sec 2; (Get-WmiObject Win32_PerfFormattedData_PerfOS_memory).PageFaultsPersec }