Slow WMI request on Windows 2008R2 - wmi

Has anyone got any suggestions to speed up this WMI query? I'm updating a client application every 5 seconds to show the CPU stats. It was much quicker on Windows 2003 but takes at least 5 seconds to return an integer for 4 CPU cores:
Private Sub GetProcessorIdleTime(ByVal Server As String)
Dim searcher As New ManagementObjectSearcher("\\" & Server & "\root\CIMV2", "SELECT LoadPercentage FROM Win32_Processor")
Dim collection As ManagementObjectCollection = searcher.[Get]()
For Each row In collection
TextBox1.Text = TextBox1.Text & vbCrLf & Convert.ToInt32(row("LoadPercentage"))
Next
End Sub
Or is there a better way to retrive this information remotely?

To improve the performance, you must re-use the WMI connection to the remote server, establishing a connection is one of the more expensive tasks when you execute a WQL sentence.
In your code you are setting a new WMI remote connection each time. So rewrite your code creating a new method to establish the remote connection and then reuse (share) the ManagementObjectSearcher object in your GetProcessorIdleTime method.

Related

Google Cloud Functions Java 11 (Beta) Runtime - Performance Issue

I have created a new Cloud Function using Java 11 (Beta) Runtime to handle HTML form submission for my static site. It's a simple 3-field form (name, email, message). No file upload is involved. The function does 2 things primarily:
Creates a pull request with BitBucket
Sends email to me using SendGrid
NOTE: It also verifies recaptcha but I've disabled it for testing.
The function when ran on my local machine (base model 2019 Macbook Pro 13") takes about 3 secs. I'm based in SE Asia. The same function when deployed to Google Cloud us-central1 takes about 25 secs (8 times slower). I have almost the same code running in production as part of a Servlet on GAE Java 8 runtime also in US Central region for a few years. It takes about 2-3 secs including recaptcha verification and sending the email. I'm trying to port it over to Cloud Function, but the performance is about 10 times slower with Cloud Function even without recaptcha verification.
For comparison, the Cloud Function is running on 256MB / 400GHz instance, whereas my GAE Java 8 runtime runs on F1 (128MB / 600GHz) instance. The function is using only about 75MB of memory. The function is configured to accept unauthenticated requests.
I noticed that even basic String concatenation like: String c = a + b; takes a good 100ms on the Cloud Function. I have timed the calls and a simple string concatenation of about 15 strings into one takes about 1.5-2.0 seconds.
Moreover, writing a small message (~ 1KB) to the HTTPUrlConnection output stream and reading the response back takes about 10 seconds (yes seconds)!
/* Writing < 1KB to output stream takes about 4-5 secs */
wr = new OutputStreamWriter(con.getOutputStream());
wr.write(encodedParams);
wr.flush();
wr.close();
/* Reading response also take about 4-5 secs */
String responseMessage = con.getResponseMessage();
Similarly, the SendGrid code below takes another 10 secs to send the email. It takes about 1 sec on my local machine.
Email from = new Email(fromEmail, fromName);
Email to = new Email(toEmail, toName);
Email replyTo = new Email(replyToEmail, replyToName);
Content content = new Content("text/html", body);
Mail mail = new Mail(from, subject, to, content);
mail.setReplyTo(replyTo);
SendGrid sg = new SendGrid(SENDGRID_API_KEY);
Request sgRequest = new Request();
Response sgResponse = null;
try {
sgRequest.setMethod(Method.POST);
sgRequest.setEndpoint("mail/send");
sgRequest.setBody(mail.build());
sgResponse = sg.api(sgRequest);
} catch (IOException ex) {
throw ex;
}
Something is obviously wrong with the Cloud Function. Since my original code is running on GAE Java 8 runtime, it was very easy for me to port it over to the Cloud Function with minor changes. Otherwise I would have gone with NodeJS runtime. I'm also not seeing any of the performance issues when running this function on my local machine.
Can someone help me make sense of the slow performance issue?
What you're seeing is almost certainly due to the "cold start" cost associated with the creation of a new server instance to handle the request. This is an issue with all types of Cloud Functions, as described in the documentation:
Several of the recommendations in this document center around what is known as a cold start. Functions are stateless, and the execution environment is often initialized from scratch, which is called a cold start. Cold starts can take significant amounts of time to complete. It is best practice to avoid unnecessary cold starts, and to streamline the cold start process to whatever extent possible (for example, by avoiding unnecessary dependencies).
I would expect JVM languages to have an even longer cold start time due to the amount of time that it takes to initalize a JVM, in addition to the server instance itself.
Other than the advice above, there is very little one can due to effectively mitigate cold starts. Efforts to keep a function warm are not as effective as you might imagine. There is a lot of discussion about this on the internet if you wish to search.
Keep in mind that the Java runtime is also in beta, so you can expect improvements in the future. The same thing happened with the other runtimes.

How to debug "could not receive data from client: Connection reset by peer"

I'm running a django-celery application on Ubuntu-12.04.
When I run a celery task from my web interface, I get the following error, taken form postgresql-9.3 logfile (maximum level of log):
2013-11-12 13:57:01 GMT tss_usr 8113 LOG: could not receive data from client: Connection reset by peer
tss_usr is the postgresql user of the django application database and (in this example) 8113 is the pid of the process who killed the connection, I guess.
Have you got any idea on why this happens or at least how to debug this issue?
To make things work again I need to restart postgresql which is extremely uncomfortable.
I know this is an older post, but I just found it because I had the same error today in my postgres logs. I narrowed it down to a PDO select statement. I'm using Zend Framework 1.10.3 on Ubuntu Precise.
The following pdo statement generated an error if $opinion is a long text string. The column opinion is type Text in my postgres table. The query succeeds if $opinion is under a certain number of characters. 1000 characters works fine. 2000 characters fails with "could not receive data from client: Connection reset by peer".
$select = $this->db->select()
->from( 'datauserstopics' )
->where("opinion = ?",trim($opinion))
->where("datatopicsid = ?",trim($tid))
->where("datausersid= ?",$datausersid);
$stmt = $this->db->query($select);
I circumvented the problem by using:
->where("substr(opinion,1,100) = ?",trim(substr($opinion,1,100)))
This is not a perfect solution, but for my purposes, the select statement using substr() suffices.
Note that I have no problem inserting long strings into the same table/column. The disconnect problem only appears for me on the PDO select with relatively long text strings.
I'm getting it in 2017 with 9.4, I have no text fields, don't know what a PDO is. My select statement is about 50 bytes long, I'm trying to fetch an int4 and a double precision. I suspect the error message can mean multiple things.
I've since found https://dba.stackexchange.com/questions/142350/postgres-could-not-receive-data-from-client-connection-reset-by-peer which indicates it could be a problem with the client configuration. My client is libpg and PQconnectdb() is giving me a CONNECTION_OK return. It works at least partly.
For me, restarting the hypervisor where both the Postgres and the application using it helped. I've seen stack traces in dmesg before, though.

Detecting AC Power connection in WinPE?

I'm trying to determine if a laptop is connected to AC power.
The OS Im running under is WinPE.
My app is written in native C++.
WMI queries using Win32_Battery are not supported and the GetSystemPowerStatus API always returns '1' for ACLineStatus (running on AC power or not).
Any ideas?
Additonal investigation:
Just tried the API 'CallNtPowerInformation' with POWER_INFORMATION_LEVEL::SystemBatteryState. The SYSTEM_BATTERY_STATUS structure element AcOnLine also returns 1 regardless of power supply status. Probably just calls the same system level code but thought I'd add it in here.
I managed to answer my own question and it proved to be very simple in the end.
In WinPE the following noddy script returned null when executed because the battery wasn't being recognised:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Battery",,48)
For Each objItem in colItems
Wscript.Echo objItem.BatteryStatus
Wscript.Echo objItem.Caption
Next
I found a battery device driver in my PE image (\windows\inf\battery.inf) which once installed resulted in the battery being recognised and the above script returning the expected values. i.e. BatteryStatus = 2 (The system has access to AC so no battery is being discharged) or BatteryStatus = 1 (The battery is discharging i.e. AC not connected).
Driver can be installed in the PE image itself or loaded on demand. i.e. drvload

How to / Is it possible to monitor remote WMI scripting?

do u know perhaps a way (via script or program) to find out if e.g. a WMI script runs from a remote PC1 and performs some tasks in another PC2 when I am seating in a third PC: PC3
Assume that all PC belong to the same network and domain and have windows xp installed.
The reason for this that I administer a small network and I think that one student shuts down the PC where another student works, via WMI scripting.
Is there a way to monitor (via script or program) such a thing, without disabling wmi remote access.
Thanks everybody
You can get the credentials used to perform the shutdown by looking at verbose WMI logs.
1) Enable verbose WMI logging
Run 'Wmimgmt.msc' (also available under My Computer > 'Manage' > 'Services and Applications' > 'WMI Control')
Select 'WMI Control (Local)', right click --> select 'Properties'
Select 'Logging' Tab, set 'Logging level' to Verbose
2) Look at the WMI log files (Default location: %WINDIR%\system32\wbemLogs) to see record of remote access and actions taken. Specifically, look at wbemcore.log
Example: When I logged in remotely I saw the following entry [<domain> and <username> here were the real ones used for the remote connection]:
(Thu Aug 13 <time>) : DCOM connection from <domain>\<username>
at authentiction level Packet, AuthnSvc = 9, AuthzSvc = 1, Capabilities = 0
Then, to execute the WMI method the student would need to GetObject Win32_OperatingSystem, which showed up like this:
(Thu Aug 13 <time>): CALL CWbemNamespace::GetObject
BSTR ObjectPath = win32_operatingsystem
long lFlags = 0
And finally you'd look for executing the Win32Shutdown method, which should log something like this:
(Thu Aug 13 <time>) : CALL CWbemNamespace::ExecMethodAsync
BSTR ObjectPath = Win32_OperatingSystem
BSTR MethodName = Win32Shutdown

How do I listen/identify when a program runs in Windows using C++?

Specifically, I want to listen to when programs are run and record information such as: timestamp, executable, windows name and user.
Alternatively, use the WMI interface to find out what's running and take appropriate action. In the VBScript code below the WMI subsystem is being queried with Select * from Win32_Process so as to change the process priority. Find out what other attributes are available for Win32_Process and you should find stuff that's heading in the direction you want to go.
Const NORMAL_PRIORITY = 32
Const LOW_PRIORITY = 64
Const REALTIME_PRIORITY = 128
Const HIGH_PRIORITY = 256
Const BELOWNORMAL_PRIORITY = 16384
Const ABOVENORMAL_PRIORITY = 32768
Function SetPriority( sProcess, nPriority )
Dim sComputer
Dim oWMIService
Dim cProcesses
Dim oProcess
Dim bDone
bDone = False
sComputer = "."
Set oWMIService = GetObject("winmgmts:\\" & sComputer & "\root\cimv2")
Set cProcesses = oWMIService.ExecQuery ("Select * from Win32_Process Where Name = '" & sProcess & "'")
For Each oProcess in cProcesses
oProcess.SetPriority( nPriority )
bDone = True
Next
SetPriority = bDone
End Function
The most obscene way of doing this is the Google-desktop way
Namely to have your DLL load into every process that is ever started and to log information.
If you're interested more, install google desktop and watch its dll load into your processes. Then look in the registry to see it does it.
Be mindful that this is entering to the realm of virus like behaviour.
I would use the PSAPI function EnumProcesses() to periodically get a list of running processes.
You could set up a WMI permanent event subscription to monitor process creation and log the details. I have some samples here - one of the samples monitors notepad.exe creation and logs the events in a txt file. Permanent event subscription monitors events 'at all times', but if you want to monitor events 'for the duration of your application', you can use WMI COM API with C++ - the WQL event query is the same in both cases. The documentation is here.
Look into using the Perfmon API's (check MSDN for references).