Get Free Memory Available - powershell

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.

Related

MSAcpi_ThermalZoneTemperature won't refresh

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.

Measure actual clock speed via powershell during an intensive task

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%.

Window: command get current disk speed in/out

I want to get current disk info Read Speed and Write Speed not max speed I/O
like image above, read speed = 0; write speed = 8.8MB/s
Please, anyone can show me a command can get that info.
Just to begin with, this class will give you everything you need that you desire to have:
Get-WmiObject Win32_PerfFormattedData_PerfProc_Process
But my preference is
1) powershell-is-king-Measure-disk-performance-for-iops-and-transfer-rate
2) 2 Functions for IO
Hope it helps

How to stop a powershell block after a timeout for powershell script

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

Sending a Refresh() to WMI in PowerShell

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 }