Sending a Refresh() to WMI in PowerShell - 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 }

Related

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

When are data sections evaluated?

When are PowerShell data sections evaluated?
Specifically, are they only ever evaluated once at the point of runtime definition/loading? Or are they evaluated on every execution of the containing function, even if it has already been defined/loaded?
I'm assuming that the containing context is a function or advanced function that will be called multiple times in a single session after being defined/loaded, rather than a script file that would have to be reloaded on every invocation (as far as I understand, anyway).
Script to test for both questions:
(get-date).TimeOfDay.ToString()
Start-Sleep -Milliseconds 100
DATA dat -supportedCommand Get-Date {
get-date
}
Start-Sleep -Milliseconds 100
(get-date).TimeOfDay.ToString()
Start-Sleep -Milliseconds 100
$dat.TimeOfDay.ToString()
results (note that time from second line is the latest):
12:21:23.3191254
12:21:23.5393705
12:21:23.4306211
Which concludes that:
Data section evaluation is executed immediately, not delayed
Data section is evaluated only once, not on every usage
Data Sections would be much more useful if we had control over those mechanics. For example reading large text file only when needed or refreshing a variable upon every access.

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

What is the maximum size of PSDataStreams class or the Powershell.Streams property?

I'm trying to execute around 40000 commandlets in Powershell and this is my code.
rmcommand = new PSCommand();
rmcommand.AddScript(shellcommand);
rmcommand.Commands.Add("Out-String");
powershell.Commands = rmcommand;
Collection<PSObject> results = powershell.Invoke();
Here, shellcommand is the command to execute and I pass it to the method each time. Now, let us say all the commandlets give an error. So these errors are stored in powershell.streams property. What is the maximum size of this property? Because, after executing around 23000 commandlets, I think the stream gets full and the execution stalls. At the same time, if I read the stream after each invoke, all 40000 commandlets are executing fine. So I assume the stream is getting full. Is it the case? Or, am I missing anything?

Calculating Private Working set memory in perl

I'm basically trying to query private working set of a process in perl.
I have already refereed this post.
The solution works great on win8/8.1 but for some reason the following line returns nothing on win7x64 and I have tried using IDProcess instead of Name, it still returns no process.
my $proc = $objWMI->ExecQuery("select * from Win32_Process where Name=\'notepad\'");
$objWMI = Win32::OLE->GetObject('winmgmts:\\\\.\\root\\cimv2');
$proc= $objWMI->ExecQuery("select * from Win32_PerfRawData_PerfProc_Process where Name=\'notepad\'");
foreach my $process (in($proc))
{
print "abc";
$out = $process->{WorkingSetPrivate};
}
So this thing doesn't work.
Is there any different way of querying private working set size of a process in perl?
It seems like on windows 7 64 bit the performance counter was corrupted. I finally founded this post Corrupt Performance Counter
So I started cmd as admin and did lodctr /R (This basically reset your performance counters). After this, I was finally able to get the process, and this following code worked flawless :)
my $proc = $objWMI->ExecQuery("select * from Win32_PerfRawData_PerfProc_Process where Name=\'notepad\'");