Posts Tagged ‘Solutions’

How to use VBS, WMI, and Twitter to track your server temperature.

Posted By Corey on July 28th, 2009

With the record temperatures in Seattle this week, I finally got around to doing something kind of silly but useful. I really just wanted something simple to notify me when  my server was getting too hot, warning levels, while not good, are manageable. Critical levels, I end dealing with another way. Dell says my 2900 should warn me at 42c and critically warn me at 47c. Personally I’m much happier when it’s hovering around 34c.

But like I said, I just wanted a quick way to be notified if my server is getting to hot. Twitter has the benefit of texting me directly for stuff I choose so I figured it’d be an easy way of being notified. With the help of a few searches and some hacking and slashing of code I’ve got a nice little way of keeping tabs on my server through Twitter now. Technically since it’s using WMI, keeping track of just about anything is possible. There’s a load of data available if you check out MSDN. In my case, Dell exposes quite a bit of data against my PowerEdge 2900. In most cases this script and this sort of idea will work with just about any system out there running Vista, 7, or Server 2008. Straight out of the box no less.

First things first, I wanted to make sure I could pull the right data. In this sample, we use some simple VBS to query the WMI service and create a query to pull the current reading and status from the temperature sensor. In my first version, I omitted the if statements to make things simpler but later to make it work with the Twitter portion of the script I needed to write the WMI values to a variable. I did this a second time to pull the fan speeds as well since the first test with the temp worked well.

On Error Resume Next

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2\dell")

Set colItems = objWMIService.ExecQuery("Select CurrentReading, Status from CIM_TemperatureSensor")

For Each objItem in colItems
 if typename(objItem.Status) <> "Null" then
  if objItem.Status(0) <> "" Then
  sStatus = objItem.Status(0) ' write to variable
  Wscript.Echo "Status: " & sStatus ' print out the info
  end if
 end if
 if typename(objItem.CurrentReading) <> "Null" then
  if objItem.CurrentReading(0) <> "" Then
  sTemp = objItem.CurrentReading(0) ' write to variable
  Wscript.Echo "Temp: " & sTemp / 10 & "c" ' print out the info
  end if
 end if
Next

Set colItems = objWMIService.ExecQuery("Select CurrentReading from CIM_Tachometer") ' switching context

For Each objItem in colItems
 if typename(objItem.CurrentReading) <> "Null" then
  if objItem.CurrentReading(0) <> "" Then
  sFan = sFan + objItem.CurrentReading(0)  ' increase the sum of fan speeds
  sCount = sCount + 1 ' increase the count of fans
  end if
 end if
Next
Wscript.Echo "RPM:  " & Cstr(Round(sFan / sCount)) ' take the sum total of fan speeds and average it out 

So this first VBScript really just comes in handy for making sure you’re gathering the right data and writing it to a variable then printing it out to the command line fine. Perfect little test bed really.

Next, we’ll want to make sure we can write to Twitter just fine. To do this I used this sample VBScript:

if not wscript.arguments.count > 1 then
   wscript.echo "Not enough options provided"
   wscript.quit
end if

sUrl = "http://twitter.com/statuses/update.xml"
sUsername = wscript.arguments(0)
sPassword = wscript.arguments(1)
sMessage = wscript.arguments(2)

wscript.echo sUsername & ", " & sPassword & ", " & sMessage
sMessage = "status=" & sMessage

HTTPPost sUrl, sMessage, sUsername, sPassword

Function HTTPPost(sUrl, sRequest, sUsername, sPassword)
  set oHTTP = CreateObject("Microsoft.XMLHTTP")
oHTTP.open "POST", sUrl,false,sUsername,sPassword
  oHTTP.send sMessage
  HTTPPost = oHTTP.responseText
  WScript.Echo HTTPPost
End Function

The usage is pretty simple, from the command line you run the script, twitter.vbs you pass it your username, password, and the message you want posted. If it updates Twitter you know that bit works. I honestly borrowed this code from some random find on the web, I wish I could remember which result it was but I don’t (if you recognize it please give me a link for proper credit). But honestly there’s a bunch of samples out there, Twitter does a good job of helping people with their API.

Now finally, I took the two samples above, then combined them into the code that now reads the info through WMI and posts to Twitter:

Dim strUsername, strPassword, strMessage, sStatus, sTemp, sFan, sCount ' declare variables

On Error Resume Next

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2\dell") 'specify wmiService

Set colItems = objWMIService.ExecQuery("Select CurrentReading, Status from CIM_TemperatureSensor")

For Each objItem in colItems
 if typename(objItem.Status) <> "Null" then
  if objItem.Status(0) <> "" Then
  sStatus = objItem.Status(0) ' write to variable
  end if
 end if
 if typename(objItem.CurrentReading) <> "Null" then
  if objItem.CurrentReading(0) <> "" then
  sTemp = objItem.CurrentReading(0) ' write to variable
  end if
 end if
Next

Set colItems = objWMIService.ExecQuery("Select CurrentReading from CIM_Tachometer") ' switching context

For Each objItem in colItems
 if typename(objItem.CurrentReading) <> "Null" then
  if objItem.CurrentReading(0) <> "" Then
  sFan = sFan + objItem.CurrentReading(0)
  sCount = sCount + 1 ' take the sum total of fan speeds and average it out
  end if
 end if
Next

strUsername = "corego" '  Twitter username
strPassword = " " ' Twitter password, remove for testing
strMessage =  "automated message from @corego's server: the status is " & CStr(sStatus) & ", the ambient temp is " & CStr(sTemp / 10) & "c, and average fan speed across " & sCount & " fans is " & CStr(Round(sFan / sCount)) & "RPM" 'mesage that's posted to Twitter.

' strMessage is where the big ass string is put together.
' Use CStr to ensure the values from WMI are in a string format, divide the temp by 10 since it needs it.
' Take the average fan speed across the number of fans and round them to make it pretty.

' Calling the function and store the result in a variable.
Dim strTwitterXMLResponse
strTwitterXMLResponse = SendToTwitter(strMessage, strUsername, strPassword)

' Post back the result with a messagebox so you know something happend.
' MsgBox strMessage, VbOkOnly, "TWITTER STATUS UPDATE"

' The MsgBox is disabled for live, enabled for testing, uncomment this and comment your password for testing.

Function SendToTwitter(strMessage, strUsername, strPassword) ' actual send function

     ' This is the function which does all the work.
     ' It uses XMLHTTP to post your message to Twitter.
     Dim objHTTP
     Set objHTTP = CreateObject("Microsoft.XMLHTTP")
          objHTTP.open "POST", "http://twitter.com/statuses/update.xml", false, strUsername, strPassword
          objHTTP.send "status=" & strMessage
          ' The function stores the Twitter response to the result of the function so you can use this later
          SendToTwitter = objHTTP.responseText
     Set objHTTP = nothing 'Release the object
End Function

And that’s pretty much that. You could run this as a scheduled task to update regularly. You could maybe add some refresher code to leave it running all the time and only update when the temperature changes. Options are pretty much open. You could also modify this to spit out some HTML for your WordPress blog, something I might do at some point.

In the end, I used Dell’s Open Manage stuff to use the built in alerting. I’ve set it up to basically run this VBS any time the system is in the Warning or Critical levels I mentioned previously. If the temp hits 42c it’ll kick off the alert and Twitter will get updated along with the SMS sent to my iPhone. Another future idea is to write a very simple iPhone friendly web page that’ll let me manage the server. Maybe cycle IIS, restart, shutdown, etc. For now this is good enough.

I was going to create an account just for the server on Twitter but that seems excessive. I don’t like managing multiple accounts and this should only alert when it really needs to. But there you go. Enjoy.

Oh and one last thing, I’ve tested this against only a single machine, so YMMV, I’m also not a Dev, you can probably perfect the code, make it simpler, cleaner, whatever. Feel free to provide constructive feedback.

How to temporarily fix the Zune 30’s Z2K9 woes.

Posted By Corey on December 31st, 2008

Open Zune 30Since my warranty was already void as of 12/07, and because I already swapped the 30GB HDD for a 60GB HDD, I ended up opening the Zune, then reseating the cable from the battery to the main board which resets the Zune (it’s the little brown plastic piece on the right in the attached photo, the one with the long cable going to it over the hard drive).

It seems as long as the Zune isn’t sync’d again with the software open it should function. I’m still in the process of testing this but I’m guessing jumping the clock forward to Jan 1, 2009 may let things pass over fine. But then again I don’t really suggest doing this after you get it working :) .

Of course, I don’t suggest voiding the warranty by opening up your Zune either. Hopefully you won’t.

UPDATE: Now that we’re in good old 2009 the Zune has righted itself thanks to the infinite loop ending. All is right in the world and the final FAQ regarding the Zune resurrection has been posted on the proper Zune support site.

UPDATE: Gizmodo posting first on the reseat fix though I don’t believe you need to unplug the hard drive so I advise against that. I also suggest waiting for the official solution to come from Zune support.

UPDATE: From the Zune forums:

Early this morning we were alerted by our customers that there was a widespread issue affecting our 2006 model Zune 30GB devices (a large number of which are still actively being used).  The technical team jumped on the problem immediately and isolated the issue: a bug in the internal clock driver related to the way the device handles a leap year.  The issue should be resolved over the next 24 hours as the time change moves to January 1, 2009.   We expect the internal clock on the Zune 30GB devices will automatically reset tomorrow (noon, GMT). By tomorrow you should allow the battery to fully run out of power before the unit can restart successfully then simply ensure that your device is recharged, then turn it back on.  If you’re a Zune Pass subscriber, you may need to sync your device with your PC to refresh the rights to the subscription content you have downloaded to your device.

Customers can continue to stay informed via the support page on zune.net (zune.net/support).

We know this has been a big inconvenience to our customers and we are sorry for that, and want to thank them for their patience.

Q:  Why is this issue isolated to the Zune 30 device?

It is a bug in a driver for a part that is only used in the Zune 30 device.

Q:  What fixes or patches are you putting in place to resolve this situation?

This situation should remedy itself over the next 24 hours as the time flips to January 1st.

Q:  What’s the timeline on a fix?

The issue Zune 30GB customers are experiencing today will self resolve as time changes to January 1.

Q:  Why did this occur at precisely 12:01 a.m. on December 31, 2008?

There is a bug in the internal clock driver causing the 30GB device to improperly handle the last day of a leap year.

Q:  What is Zune doing to fix this issue?

The issue should resolve itself.

Q:  Are you sure that this won’t happen to all 80, 120 or other flash devices?

This issue is related to a part that is only used in Zune 30 devices.

Q:  How many 30GB Zune devices are affected? How many Zune 30GB devices were sold?

All 30GB devices are potentially affected.

UPDATE: Over at ZuneBoards.com, a moderator has posted up the source and analysis for the cause of the bug on the Zune 30’s. Pretty interesting. In the end a minor mistake and a missed test case causing a major headache. Likely a simple firmware update will prevent the problem again next leap year. Granted I doubt any Zune 30’s will even be able to hold a charge by then:

year = ORIGINYEAR; /* = 1980 */

while (days > 365)
{
    if (IsLeapYear(year))
    {
        if (days > 366)
        {
            days -= 366;
            year += 1;
        }
    }
    else
    {
        days -= 365;
        year += 1;
    }
}

Testing out the new AddThis button… details on setting up your own with dasBlog.

Posted By Corey on July 15th, 2008

I was using something else before, Feedburner I guess, I suppose I could keep using it, but it seemed limited. While using Redfin today I noticed they had the Share on Facebook with the down arrow and that it was using the AddThis.com service. Registered real quick grabbed the generated code and popped it in. Had to refer to the macro definitions for dasBlog but it seems to be working right now, the code looks like this:

<!– ADDTHIS BUTTON BEGIN –>
<script type=”text/javascript”>
addthis_pub = ‘YOUR USER NAME’;
</script><a href=”
http://www.addthis.com/bookmark.php” onMouseOver=”return addthis_open(this, ”, ‘<%PermalinkUrlRaw%>‘, ‘<%itemTitleRaw%>‘)” onMouseOut=”addthis_close()” onClick=”return addthis_sendto()”><img src=”http://s9.addthis.com/button1-addthis.gif” width=”125″ height=”16″ border=”0″ alt=”" /></a><script type=”text/javascript” src=” . But that’s for another post… Tip though, voltage converters for fans or fans with a high CFM and low dB rating work amazingly well as do rubber grommets for fans and HDD’s and not to mention that Dynamat isn’t half bad for noise absorption as well.