IT Intern Blog

IT Challenges Solved

Get Facebook Events from a Business Page

Posted by IT Intern on October 2, 2009

While working on our new company website, one of my projects was to find a way to get our Facebook events to show up on our website Events page. We have a business page on Facebook, and I soon found out it’s not exactly simple to just get events from a business page. As far as I can tell, you can’t even get an RSS feed of events from a business page. The only feature of a business page that I could find that was even remotely helpful is that each tab on a business page has its own static URL.

So I came up with a php script that will grab the source code of our Facebook events tab and parse the HTML display table of upcoming events. The following is a working example that links to Victoria’s Secret’s Facebook events tab. Just save the code as a .php file on your website, and take a look (requires PHP and CURL).

<?php
/*
facebookevents.php
by The IT Intern

This page will grab the HTML table of upcoming events displayed on a Facebook business page's events tab.
It includes some CSS to format the table using Facebook's id names
*/

//Static URL of a business page's Events tab
$url = 'http://www.facebook.com/victoriassecret?v=app_2344061033&#39;; //Victoria's Secret

//Open curl, set options, get source code, close curl
$curl = curl_init($url);

curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt ($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

$source = curl_exec($curl);
curl_close($curl);

//Strip html before and after events table
$begevents = strpos($source,'<div id="future_events');
$endevents = (strpos($source,'<div id="events_show_past_link'))-$begevents;

$eventscode=substr($source,$begevents,$endevents);

//Edit relative links to be absolute
$absurl = 'http://www.facebook.com&#39;;

//Search links
$start = 0;
while (strpos($eventscode,'/search/',$start) != FALSE) {
$start = strpos($eventscode,'/search/',$start);
$eventscode = substr_replace($eventscode,$absurl,$start,0);
$start += 30;
}

//Event links
$start = 0;
while (strpos($eventscode,'/event.php',$start) != FALSE) {
$start = strpos($eventscode,'/event.php',$start);
$eventscode = substr_replace($eventscode,$absurl,$start,0);
$start += 30;
}

//Add CSS
$displaycode .= '<html><head>
<title>Victoria\'s Secret\'s Events – by The IT Intern</title>
<style type="text/css">
<!--
#future_events { font-size: 14px; }
.timeline {
font-style: italic;
border-bottom: 1px solid;
}
td.tunaimage { padding: 1em; }
img { border: 0; }
td.eventtitle { padding: 1em; }
table.infotable { font-size: 12px; }
-->
</style>
</head>';

// Add events table
$displaycode .= $eventscode;

// Add closing tags
$displaycode .= '</body></html>';

echo $displaycode;

?>

Posted in Facebook, PHP, Scripts | Leave a Comment »

Resizing a MS Virtual PC Harddrive with Windows

Posted by IT Intern on September 3, 2009

I use Microsoft Virtual PC 2007 for testing pretty much everything, and on the first VPC I made (running Windows XP) I promptly ran out of space on the 5GB I initially assigned it. After searching around, I found a great (free) tool from vmToolkit called VHD Resizer:

http://vmtoolkit.com/files/folders/converters/entry87.aspx

This tool is very easy and very handy. It resizes your VPC’s harddrive by essentially copying it to a different file with a larger size. Here’s how to do it:

  1. Make sure your VPC is not running.
  2. Run VHD Resizer and select the harddrive file you need to resize.
    • The full path to the file is now shown under “Source Vhd to Resize”
  3. Under “Destination Vhd” click the “save as” button
    • Choose a different file name for the new harddrive file. The default is to place it in the same directory as the source file.
  4. Choose the type (default is “Dynamic,” which is what you most likely want) and size for the new file.
  5. Click “resize”
    • The file will now begin copying, and will probably take awhile depending on the size of the original file.
  6. When it’s done, close VHD Resizer and open up the Virtual PC Console
  7. Open the Settings for your VPC
  8. Select a Hard Disk with a Current Value of “None”
  9. Enable the “Virtual hard disk file:” radio button and browse to the new file you created.
  10. Save the settings and start up your VPC
  11. Logged on as Administrator, go to Start > My Computer > (right-click) Manage > Disk Management
  12. You should see two volumes:
    • C:, which is your original harddrive file
    • A new volume that has two parts, a healthy part of the same size as the original and an unallocated part
  13. Close Disk Management and go to Start > Run > “diskpart.exe”
  14. You will see a command prompt with “DISKPART>”. Do the following:
    • Enter the command “list volume” (no quotes)
    • From the list of volumes, note the volume number of the new drive
    • Enter the command “select volume X” where X is the new drive number
    • You will see a message that the volume has been selected.
    • Enter the command “extend”
    • After a few seconds, you will see a message that the volume has been extended.
    • Close the command prompt.
  15. Go back into Disk Management and you should now see volume C: and the new volume with only one part of the new size.
  16. Shut down the VPC.
  17. Open the Virtual PC Console and go to the Settings of your VPC.
  18. Select the new Hard Disk that you added and revert it to the “None” radio button selected.
  19. Select the main Hard Disk and change the path to the new file.
  20. Start your VPC.
  21. The VPC should start as normal. After you log in, it will tell you the device has been installed and needs to restart. Go ahead and restart, and now you should be able to log in, go to Disk Management and see your C: drive with the new size available.
  22. You can now delete the old harddrive file.

That’s it! How easy was that? Kudos to vmToolkit for a great tool 🙂

Posted in Virtual PC, Windows | Leave a Comment »

Read and Delivery Receipts Mystery

Posted by IT Intern on September 1, 2009

Today the CEO came to us with an unusual problem. Despite his Outlook 2007 being set to never send read receipts, he was constantly finding read receipts in his Sent folder to an overseas customer. For whatever reason, he does not want to correspond with the customer, and is understandably upset that, after failing to reply to the customer’s emails, the customer will then email back stating he *knows* he got the email and demanding a reply.

So I opened up Outlook 2007 and sent myself several messages, while changing Outlook settings between each. I found what you would normally expect: When I have my “respond to requests” settings on “Always send a response,” I would get a receipt. When set to “Never send a response,” I wouldn’t get one. And when set to “Ask me before responding,” it would do whichever option I chose.

I tried to find if there is any way for a sender to force a recipient to send a read receipt, and as far as I could find, there is not.

Seemingly unable to reproduce his problem, I asked my boss to show me the copy of the sent read receipt that he had forwarded. It did not look at all like the read receipts I had sent myself. In fact, it looked more like a delivery receipt. Checking the headers of the received message confirmed: the messages contained both the

Disposition-Notification-To:

header for a read receipt request, and the

Return-Receipt-To

header for a delivery receipt request.

The weird thing is, though, that delivery receipts are supposed to be handled by the server, not the client, yet he had those delivery receipts right there in his Sent folder. We promptly disabled delivery receipts on our server, and began sending each other test messages. As we expected, no delivery receipts. How could we reproduce this problem? We decided to re-enable delivery receipts and sent some more tests so we could examine the headers. At this time, we sent one of our test messages to the CEO’s account, and to our surprise we got TWO delivery receipts back.

Thoroughly confused, we at first wondered if Outlook wasn’t sending its own delivery receipts (although if it was, we should have gotten them from each other as well), until a closer look at the header of the second delivery receipt revealed the culprit: his Blackberry was sending the delivery receipts itself.

Of course, by this point he had been out of the office for hours, so first thing in the morning we’ll change his Blackberry settings and send him another test email.

Hopefully this will solve his stalker-customer woes 😉

Update: Apparently, there is no Blackberry setting that will disable sending delivery receipts, and this seems to have been a known problem since at least 2007. See these forums

http://www.blackberryforums.com/general-8300-series-discussion-curve/102641-disable-delivery-receipts-8300-a.html
http://alexking.org/blog/2008/03/11/blackberry-e-mail-delivery-confirmations
http://forums.crackberry.com/f2/confirm-delivery-confirm-read-send-read-receipts-blackberry-1463/

We’re trying to implement a filter to catch any email with the “Return-Receipt-To” header and strip it before it gets delivered, but a better option might be just to switch to an iPhone. 😀

Second Update: Stripping the header worked. Our own server would still send a delivery receipt even with the header stripped, but without the header the Blackberry did not know to send one, so it doesn’t now. Problem solved, except anyone who has already received a delivery receipt from his (or anyone’s) Blackberry now has his Blackberry’s direct address (if they know enough to look at the headers). Such a pain, and he’s considering switching to an iPhone anyway.

Posted in Blackberry, Email | Leave a Comment »

Multi-Boot with Windows 7, Vista and XP

Posted by IT Intern on August 6, 2009

Yesterday I got a ticket to add a Windows 7 installation on a new partition on one of our 64 bit testing machines that currently runs both XP and Vista. Win7 installed just fine, but it got rid of the option to boot into XP, and it took me almost 2 full days to figure out how to get it back! I’m telling the tale here of all the tries-and-errors I went through before finally getting it to work.

* If you’re not interested in the entire tale then click here for a summary of what worked.

I began by repartitioning one of the drives using Vista’s “Shrink” option in Disk Management. I then rebooted from my Win7 installation disc to install on the new partition. All went well until I rebooted after Win7 was installed and the boot loader only gave me the options to boot into Vista or Win7. XP was gone.

I did some searching and found it was a common occurrence, and started out trying a free tool called EasyBCD to get the XP entry back. It added a new entry for XP and the entry showed up when I rebooted, but when I selected it I got an error that said “the file \NTLDR could not be loaded because it is either missing or corrupt” and recommended I repair XP.

After I had installed Win7, I noticed something interesting: XP was originally on the C: partition and Vista on the E: partition. I installed Win7 on the new F: partition, but Win7 renamed them all, so that XP is now on F: and Win7 is on C:. However, looking at the Disk Manager in Vista still shows the original configuration, with XP on C: and Win7 on F:.

As the error message suggested, I inserted the XP disc and ran Recovery Console, where I was surprised to see the following options:
1: D:\WINDOWS
2: C:\Windows
3: E:\Windows

I ended up figuring out that XP was on number 1, the D: drive (and from what I’ve learned I now suppose C: to be Win7).

I selected 1, then tried running fixboot, first on C: and then on D:, restarting each time. Both times it gave me the same NTLDR error message, with no options except to restart.

At this point I couldn’t get into any of the OS’s, so I booted from my Win7 disc and chose repair. It brought back my Vista bootloader with the bad XP entry. I deleted the XP entry with EasyBCD and decided to try using bcdedit.exe instead. After searching around for bcdedit help I finally found this: http://technet.microsoft.com/en-us/library/cc721886%28WS.10%29.aspx#BKMK_bcdedit

To install a previous version of Windows onto a computer running Windows Vista
1. Install the previous version of Windows.
2. Log on to the older operating system and restore the latest boot manager by running the following. Fixntfs.exe will be in the \boot directory of the active partition.
fixntfs /lh
3. Create a BCD entry for the older operating system by specifying the following. Bcdedit.exe is located in the \Windows\System32 directory of the Windows Vista partition. Description is the description of the new entry for the older operating system.
Bcdedit /create {legacy} /d “Description”
Bcdedit /set {legacy} device boot
Bcdedit /set {legacy} path \ntldr
Bcdedit /displayorder {legacy} /addlast
4. Restart the computer in order for the changes to take effect.

Although XP was the original installation, I thought this may work. I skipped step 1 (obviously), and for step 2 went into the Recovery Console from the XP CD.

From here, the \boot directory was “access denied”. ATTRIB didn’t work on it, so I couldn’t access the fixntfs file. I rebooted to Vista and browsed the C: drive (which is where Vista sees the XP installation). I looked in \boot ( I had to access the folder by typing the path in the address bar), and fixntfs.exe was not even there. So I downloaded it from http://forum.osnn.net/attachment.php?s=7e7a81fa0b57c9cceb78aa2e1f8f55f6&attachmentid=7473&d=1147018827, pasted it into the C:\boot folder (as well as C:\ and C:\WINDOWS just in case), and rebooted back into Recovery Console.

I tried to run it from different locations with every possible syntax, but it always came back with “the command is not recognized.” So I decided to try booting back into Vista and running it from there. Double-clicking it looked like it ran, and no errors came up, but nothing else happened either. C:\NTLDR was still not listed, so I typed in C:\NTLDR in the address bar and a “Open With” dialog came up asking me which program to use to open the file. So something was there. I decided to proceed with the next 2 steps from within Vista.

I went to the Vista icon > All Programs > Accessories > Right-Click on Command Prompt and chose Run as administrator.

I typed the first command and got the message “The entry {ntldr} was successfully created.
Next three commands came back with: “The operation completed successfully.

Sounded good to me. Restart. XP was now back in the boot list, but when I tried to load it I got the same “missing or corrupt” message from Windows Boot Manager.

I found this website http://tinyempire.com/notes/ntldrismissing.htm and decided to give his boot cd a try. I downloaded the 64-bit version .ISO and burned it to a CD. Booting from the CDROM took me straight into Windows XP. The files I needed, however, were not on the .ISO, so I also downloaded the 64ntfile.zip from that website to get good copies of ntldr and ntdetect.com. I copied those into C:\ and restarted (I did not want his copy of boot.ini so I kept what I already had.)

I hoped I would see the old boot manager screen, but instead I got the list from the Vista bootloader. Boo. I tried the XP entry and got the error again, so I rebooted with the CD to get back into XP. I opened the Disk Manager and marked the C: partition as active (the F: partition, which has Windows 7, was the active one, and D: is the CDROM, as it should be, although in the Recovery Console it finds the XP installation on D:. This is so weird.)

I crossed my fingers and restarted.

Hmm, strange. This time before it even got to the boot list I got “A disk read error occurred. Press Ctrl+Alt+Del to restart.” I had left the boot CD in the drive, so I removed it and tried again. Same error. I put the CD back in and rebooted from it, and changed the Win7 (F: ) partition to be active again, and restarted.

It brought up the good ol’ Vista bootloader. This time I booted into Win7, just for kicks (actually, since the newly assigned drive letters only show up in Win7, I hoped I’d have better luck getting the right files on the right partition from there).

Aha! Inside Win7, XP was shown to be on the F: partition, although it’s listed on the D: partition when I run Recovery Console from the XP disc. I went back into the console (run as administrator) and ran bcdedit.exe. When I first did those steps above from the Microsoft website, I wasn’t happy with the line
Bcdedit /set {legacy} device boot

“device boot”? The others have the device set to a partition, like this

device partition=C:

so I wanted to change legacy’s device from boot to partition=D:, so I issued
Bcdedit /set {legacy} device partition=D:

No luck. It said: “An error has occurred setting the element data. The request is not supported.

I was sure my syntax was correct, so I don’t know why it’s not supported. I decided to delete the entry with
Bcdedit /delete {legacy} /f

Running bcdedit again listed only the Win7 and Vista options. I made a new one, this time using the following:
Bcdedit /create {legacy} /d “Windows XP”
Bcdedit /set {legacy} device partition=D:

I had to stop here because I got the same error. Maybe D: is not a valid drive letter for a partition? Instead I tried:
Bcdedit /set {legacy} device partition=F:

And it worked! F: is where Win7 thinks XP is, but the Recovery Console thinks it’s on drive D:… so I wasn’t sure if this would *actually* work. But I finished the last two steps:
Bcdedit /set {legacy} path \ntldr
Bcdedit /displayorder {legacy} /addlast

Restart.

Well, not entirely failed… This time trying to boot XP I got the message:

Invalid BOOT.INI file
Booting from C:\windows\
NTDETECT failed

I wonder if it failed because I had to set the device to F:. I rebooted into Vista this time to take a look at bcdedit. The Win7 entry now has “device partition=F:” and Vista has “device partition=E:” Which means, of course, XP has “device partition=C:” When I tried to set XP’s device to D: it gave me the same error as before.

Since it said “Invalid BOOT.INI,” I tried editing the file, which I had to do from within XP, since it must be done from the Startup and Recovery (right-click My Computer > Properties > Advanced tab > Settings under Startup and Recovery > Edit under System Startup), which is not available in Vista. I tried editing this line (listed twice):
“multi(0)disk(0)rdisk(0)partition(1)\WINDOWS”

to
“multi(0)disk(0)rdisk(0)partition(2)\WINDOWS”

And restarted. I got the same error, so I tried “partition(0)” and it still didn’t work. After looking around some more I found
http://www.5starsupport.com/faq/booting.htm#7-9

Try this as a possible fix in Windows XP:

Boot to the XP CD. When it asks you if you want to install or Repair, choose Repair. This will take you to the Recovery console. Choose the XP install to log into, usually there’s only 1, and enter the password when prompted. For Home, the default password is blank. At the C:\Windows prompt type the following commands:

1. FIXBOOT, answer Yes
2. CD \
3. ATTRIB -H NTLDR
4. ATTRIB -S NTLDR
5. ATTRIB -R NTLDR
6. ATTRIB -H NTDETECT.COM
7. ATTRIB -S NTDETEC.COM
8. ATTRIB -R NTDETECT.COM
9. COPY X:\I386\NTLDR C:\
10. COPY X:\I386\NTDETECT.COM C:\

In steps 9 and 10, “X” is the letter of your CD-ROM drive.

so I changed the file back to the original partition(1) and went back to the Recovery Console to try the new instructions.

I chose the XP installation on D:, but when I ran fixboot from the command line, it automatically ran it on C:. I could specify drive D:, but I let it run on C:, and then ran it on D: as well. I copied the files to both C: and D:, then restarted.

Now the boot list is gone and it goes directly to XP, except it still gives me the error message
Invalid BOOT.INI file
Booting from C:\windows\

But apparently NTDETECT didn’t fail this time, because it continued booting and got me to the login screen. So my BOOT.INI was still invalid. I edited it inside XP and I noticed the line under [operating systems] had the following options at the end:
/NOEXECUTE=OPTIN /FASTDETECT /USEPMTIMER

From here http://support.microsoft.com/kb/289022 I saw that the default should have only the /fastdetect option, so I removed the others and restarted again, but I still got the error message before it booted into XP. At this point, I had no idea if it was looking for BOOT.INI on D: or C:, so I wanted to get a default copy into both to see if that worked. Since the only way I could access D: as a partition is from Win7 (both XP and Vista see it as the CDROM), I had to boot from the Win7 disc and repair again to get the Vista bootloader back. Before I did that I made a copy of the BOOT.INI file inside the Vista (E: ) drive as a .txt, just in case I couldn’t access the original.

The bootloader came up with all three options, but before testing the XP option I loaded Win7 to get copies of BOOT.INI in a few places. Browsing the computer showed me the C: drive as Win7, E: as Vista and F: as XP. If things are working as I suspect, the BOOT.INI file should be in the F: drive. Typing F:\boot.ini into the address bar popped up the file I made in Notepad. But I also needed to have a copy in the C: drive. With F:\boot.ini open, I tried Save As > C:, but I apparently don’t have permission to save files to the root folder. Good thing I made a copy. I opened up E:, copied boot.txt, and pasted it into C:. I had to turn off ‘Hide extensions for known file types”, then renamed the file to boot.ini. But I was still bothered, because in Win7, XP is shown on drive F:, where in the Recovery Console it’s on D:. So I went back to the disk manager and reassigned the drive letter so that XP is now on D:, then restarted.

Success! The Vista bootloader came up with my three options, and XP now boots perfectly.

So now what I suspect is that Win7 not only renamed its own partition to C:, but made itself the *real* C: drive as well. But all the system files for XP are also on that partition, or at least the BOOT.INI is (I edited the BOOT.INI file on the C: drive in Win7 to remove a line I had commented out, and when I tried to make the same edit on the F: drive in Win7 I couldn’t access it, so I logged back in to XP and tried editing it from Startup and Recovery as before, and it was linked to the one I had edited in Win7. So that other file is now just… floating around, inaccessible, and not being used). So both XP and Win7 are booting from the same partition, only XP switches to use its own partition once it’s booted up. A strange configuration, but at least it’s working! And if that really is the case, then XP’s boot files (boot.ini, ntldr and ntdetect.com) need only be on the C: drive, and not on the XP partition. It also shouldn’t matter what letter the XP partition is assigned, but I’m going to leave everything as it is now.

In case you didn’t want to read my trying tale of figuring this all out, I have included a summary of only the steps that (I think) made everything work, since I went through a lot of redundant steps, and some of the stuff I tried didn’t seem to affect things at all. I didn’t try this summary of steps, so it may be missing something – you have been warned.

Summary of (perceived) Contributing Steps to Make a Multi-Boot Box with Windows 7, Vista and XP:

Assumed: You already have XP and Vista working on your machine, on separate partitions of a single drive.

From within Vista, create a new partition by shrinking an existing partition and formatting the new space. Reboot from Win7 installation disc, and install Win7 on the new partition.

From within Win7, open the command line as administrator, and run bcdedit. You should see two entries, one for Win7 and one for Vista. Issue the following:
Bcdedit /create {legacy} /d “Description”
Bcdedit /set {legacy} device partition=X:
Bcdedit /set {legacy} path \ntldr
Bcdedit /displayorder {legacy} /addlast

where Description is what you want XP to be called in the boot list, and X: is the drive letter on which Win7 shows your XP installation. If the partition happens to be D: or some other that bcdedit won’t let you assign, go into the Disk Manager in Win7 and reassign the drive letter for XP’s partition, then reissue the command with the new drive letter.

Reboot using the XP disc, and go into Recovery Console. The installation you should choose has X:\WINDOWS in all caps. You can verify this is the XP installation by issuing
CD \
DIR

and verifying the folder “Documents and Settings” exists.

From there issue the following:
1. FIXBOOT, answer Yes
2. FIXBOOT X:, answer Yes
3. CD \
4. ATTRIB -H NTLDR
5. ATTRIB -S NTLDR
6. ATTRIB -R NTLDR
7. ATTRIB -H NTDETECT.COM
8. ATTRIB -S NTDETEC.COM
9. ATTRIB -R NTDETECT.COM
10. COPY Z:\I386\NTLDR X:\
11. COPY Z:\I386\NTDETECT.COM X:\
12. COPY Z:\I386\NTLDR C:\
13. COPY Z:\I386\NTDETECT.COM C:\
where Z: is the letter of your CD-ROM drive, and X: again is the XP installation. I have duplicated the steps for both drives because I’m still not exactly sure which one worked.

Reboot from the Win7 disc again, and choose Repair. Select Startup Repair, and log back into Win7.

In Win7, open Computer and browse to X:\boot.ini (again, X: is the drive where Win7 thinks XP is located).

The file should open in Notepad, and should look similar to this:

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=”Microsoft Windows XP Professional” /fastdetect

If there are any other entries under [operating systems], delete those lines so that you have a default file just as above (leaving the partition number as it is).

Use “Save As” to make a copy on the Desktop (or somewhere else… we want it in the C: drive, but Win7 will not allow you to save there). Save it as boot.txt.

Copy the boot.txt that you just saved and paste it into C:\. Now rename the file to boot.ini (you will have to turn off “Hide extensions for known file types” in order to change the extension).

Now reboot and you should see all your options in the boot menu. Select XP and it should boot with no problems.

I did not test these steps; I have only listed the steps out of everything I tried that seemed to contribute to the working solution. If you run into any errors, retrace my original steps to see if there’s anything else you need.

Posted in Windows | Leave a Comment »

VBScript with WMI for Windows Workstation Audit

Posted by IT Intern on July 24, 2009

One of the first projects my boss assigned me was to do an audit of all the workstations in both buildings of our office. His main reason was that he’s sure there are many workstations not being backed up. He initially said he wants the name and physical location of each machine, as well as the active drive letters that should be backed up. He also mentioned that some of the workstations did not have the correct administrator password, and he’d like to know what each one is set as. He didn’t give me any specifics on how he wanted to collect the information, but I sort of got the impression he expected I would simply walk around to each machine and write it all down.

The IT Intern doesn’t work that way. Since it’s my project, it’s my decision how to get it done. And I chose to use VBScript with WMI. I’m not exactly familiar with either of those (VBScript moreso than WMI, but I’m here to learn, right?), so I did a fair bit of researching VBS expressions and WMI classes, and I managed to come up with a pretty neat script. It’s not as awesome as it could be – it writes to a tab-delimited text file – but the goal of the project didn’t justify spending a lot of time on it. If it were up to me, I’d make the script do the actual update and record everything in a database (I’m not sure why there isn’t a database for this already), but that’s not what the boss wants. On second thought, if he knew I could make it happen he might decide it’s worth it (I’d love to have a database project). But let’s just get through this script for now.

Since the project is fairly simple, I made a script that runs locally on each machine. It does all the work itself, so we can have everyone run it from their own computers and in a few minutes we’ll have all the information we need. If we were to scale the project up, I’d make it run remotely.

I mentioned the tab-delimited output file. I chose tab-delimited so the contents of the file can be copied directly into a spreadsheet. Again, it’s a small project and only needs to happen once, but if we were to go further I would make the data write directly to a database.

Now we get to the good stuff: the code. I’m a firm believer in commenting code, so my file starts off with a couple paragraphs of comments.

‘ WorkstationAudit.vbs
‘ by The IT Intern

‘ This script is to be run locally on each machine whenever an audit is performed.
‘ Extracted information will be appended to a .txt file on \\MYSERVER\Audits
‘ The contents of the .txt file can be copied as a whole into an Excel Spreadsheet,
‘ which will then be properly formatted for either use as-is or for exporting to a database.

‘ PRIOR TO EACH AUDIT:
‘ Locate the file “SysInfoTemplate.txt” on \\MYSERVER\Audits
‘ This file contains the column headers for the spreadsheet
‘ Make a copy of the file in the same folder and rename the copy to “SysInfo.txt”
‘ When the audit is complete, copy the contents of “SysInfo.txt” to an Excel Spreadsheet.
‘ When the spreadsheet has been reviewed and saved, delete “SysInfo.txt”

‘ Information collected from this script:
‘ ===============================
‘ – Computer Name
‘ – User Name of user logged on
‘ – IP Address
‘ – MAC Address
‘ – Drive Letters (only for drives of type 3 = local disk)
‘ – Size of each drive
‘ – Free space of each drive
‘ – Operating System and Version on each drive
‘ – Also sets the Administrator password
‘ ===============================
‘**Start Encode**

The last line includes “Start Encode,” which is for Windows Script Encoder. Rather than pull the administrator password from each machine, review each, and walk around and make sure all the wrong ones are corrected, I decided to make the script just set the password right when it’s run so we know they are all correct. But that means the password is right in the .vbs file, which anyone can read with a text editor. We decided to use Windows Script Encoder to generate a .vbe file which will ultimately be used to run on the workstations. Although it is possible to decode a script that has been encoded with Windows Script Encoder, it’s secure enough for our needs.

Now for the dims and setting variables.

Option Explicit
Dim objWMIService, objItem, objItem2, colItems, colItems2, strComputer
Dim MyConf, MySysInfo, MyCompName, MyIP, MyMac, MyUserName
Dim objFSO, objFolder, objShell, objTextFile, objFile, objUser
Dim strDirectory, strFile, strText
‘ Sets the directory and filename for the exported info
strDirectory = “\\MYSERVER\Audits”
strFile = “\SysInfo.txt”

‘These string variables are for the output. MyConf is formatted to write to the screen when the script is finished and show the
‘results of the information collected. MySysInfo is formatted to write the tab-delimited information to the text file.
MyConf = “”
MySysInfo = “”

On Error Resume Next
strComputer = “.” ‘Sets the computer to the local machine

The next line connects to the root\cimv2 namespace, which is where you’ll find the majority of the WMI classes.

‘ WMI connection to Root CIMV2 Namespace
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)

Now I use the namespace connection to access the Win32_ComputerSystem class, which, among other things, contains the computer name and the name of the logged in user.

‘Gets Username and Computer name from System
Set colItems = objWMIService.ExecQuery(“Select * from Win32_ComputerSystem”)

For Each objItem in colItems
MyUserName = Split(objItem.UserName,”\”)
MyCompName = objItem.Name
Next
‘Add user and computer name to MyConf and MySysInfo
MyConf = MyConf & “Computer Name: ” & MyCompName & VbCr &_
“User Name: ” & MyUserName(1) & VbCr
MySysInfo = MySysInfo & MyCompName & chr(9) & MyUserName(1) & chr(9)

set colItems = nothing

I used the Split() method with the User Name, since Win32_ComputerSystem returns the logged in user name as a path like Machine\Username. I split it at the “\” to get just the username.

The chr(9)’s are the tabs between each item for my tab-delimited text file.

Now I access the Win32_NetworkAdapterConfiguration class to get the IP and MAC address for the computer, which may come in handy.

‘ Gets info from Network Adapter
Set colItems = objWMIService.ExecQuery(_
“SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True”)

‘Get IP and MAC addresses
For Each objItem in colItems
MyIP = objItem.IPAddress(0)
MyMac = objItem.MACAddress
Next
MyConf = MyConf & “IP: ” & MyIP & VbCr & “MAC: ” & MyMac & VbCr & VbCr
MySysInfo = MySysInfo & MyIP & chr(9) & MyMac & chr(9)

set colItems = nothing

Now for some nested loops. I need to get all the active drive letters from each machine, and I also need to know the operating system each drive is running. Since it’s possible that a machine may have multiple OS’s running on partitions, I need to check each drive for its OS. However, the drive information comes from a different class than the OS information, so I need to nest the queries.

‘ Gets info from Physical Disks, e.g. C:\
Set colItems = objWMIService.ExecQuery(“Select * from Win32_LogicalDisk”)
‘ Gets info from Operating System (done separately for nested operation)
Set colItems2 = objWMIService.ExecQuery(“Select * from Win32_OperatingSystem”)

‘Get machine information and add to MyConf and MySysInfo
For Each objItem in colItems
If objItem.DriveType = 3 Then

MyConf = MyConf & “Physical Drives:” & VbCr &_
“==============================” & VbCr & _
“Drive Letter: ” & objItem.Name & vbCr & _
“Size: ” & Int(objItem.Size /1073741824) & ” GB” & vbCr & _
“Free Space: ” & Int(objItem.FreeSpace /1073741824) & _
” GB” & VbCr
MySysInfo = MySysInfo & objItem.Name & chr(9) &_
Int(objItem.Size /1073741824) & ” GB” & chr(9) &_
Int(objItem.FreeSpace /1073741824) & ” GB” & chr(9)

‘Find OS for each drive
For Each objItem2 in colItems2
If objItem2.SystemDrive = objItem.Name then
MyConf = MyConf & “OS: ” & objItem2.Caption & ” – ” & objItem2.Version & VbCr
MySysInfo = MySysInfo & objItem2.Caption & ” – ” & objItem2.Version
end if
Next

MyConf = MyConf & VbCr
MySysInfo = MySysInfo & chr(9)
End If
Next

I got all my info. Now I need to print it to my text file. I will open a File System Object, point it to a path, and have it create the path if it doesn’t exist (I know it exists because I will create it before running the script, but just in case).

‘ Create the File System Object to begin exporting information
Set objFSO = CreateObject(“Scripting.FileSystemObject”)

‘ Check that the strDirectory folder exists
If objFSO.FolderExists(strDirectory) Then
Set objFolder = objFSO.GetFolder(strDirectory)
Else
Set objFolder = objFSO.CreateFolder(strDirectory)
WScript.Echo “Just created ” & strDirectory
End If

If objFSO.FileExists(strDirectory & strFile) Then
Set objFolder = objFSO.GetFolder(strDirectory)
Else
Set objFile = objFSO.CreateTextFile(strDirectory & strFile)
Wscript.Echo “Just created ” & strDirectory & strFile
End If

set objFile = nothing
set objFolder = nothing
‘ OpenTextFile Method needs a Const value
‘ ForAppending = 8 ForReading = 1, ForWriting = 2
Const ForAppending = 8

Set objTextFile = objFSO.OpenTextFile _
(strDirectory & strFile, ForAppending, True)

‘ Writes to the file and closes it
objTextFile.WriteLine(MySysInfo)
objTextFile.Close

MyConf = MyConf & “===============================” & VbCr & “* Computer information has been exported.” & VbCr

Finally, I need to make sure the administrator password is set correctly.

‘ Set objUser = GetObject(“WinNT://” & strComputer & “/Administrator”)
‘ objUser.SetPassword(“1234567”)

‘ The above two lines are commented in case someone decides to copy/paste this script and accidentally changes their administrator password
‘ If you really want this script to set your administrator password, uncomment the two lines above and change “1234567” to whatever you want the password to be (include the quotes)

MyConf = MyConf & “* Administrator Password has been set.”

Now I popup a confirmation screen to indicate the script is over, clean up my variables, and I’m done!

Wscript.Echo MyConf

WSCript.Quit

‘Clean up memory allocation
set objWMIService = nothing
set objItem = nothing
set objItem2 = nothing
set colItems = nothing
set colItems2 = nothing
set objFSO = nothing
set objFolder = nothing
set objShell = nothing
set objTextFile = nothing
set objFile = nothing
set objUser = nothing

Posted in Scripts, VB, WMI | Leave a Comment »

Transfer (export/import) Commodities in UPS WorldShip 11

Posted by IT Intern on July 22, 2009

UPS WorldShip: A very complicated piece of software, and that’s putting it nicely. At my office we have two buildings we send shipments from, and each building has a copy of WorldShip that need to stay in sync. My first encounter with the software was to upgrade both copies from version 10 to 11 and get the negotiated rates updated correctly on both machines. A bit of a wonky process, but not too bad.

About a week later, a ticket comes in asking to have the commodities transferred from one building to the other. After a lengthy and complicated walkthrough with UPS Tech Support (during which even the UPS rep had difficulty… after getting me several steps in, she realized she had it wrong and actually put me on hold while she figured it out), I finally got the commodities transferred and closed the ticket hoping I never have to deal with that software again.

As soon as the UPS rep began “hmm”-ing and “let’s see”-ing on the phone, I grabbed a pen and wrote down every excruciating step. She walked me through the export process and explained the import process, for which I would have to hang up and go to the machine in the other building, and I wrote down everything. I wanted every detail documented in case I (or anyone else) ever had to do this again. I even took my time taking screenshots through the import for my own reference — I wasn’t taking any chances. I wrote up the steps, which turned into three full Word document pages, and now I post them for your reference (in case you are attempting this process yourself), or for your entertainment (in case you don’t have to deal with this software and wish to chuckle at what a pain it is for me and others who do).

UPS Commodities Import/Export Instructions

UPS WorldShip v.11

STEP 1: EXPORT:

Section 1.1: Create an Export Map

In this section you will create a new map for exporting commodities. If you have previously created an export map, you can skip this section.

  • Go to Import/Export Data > Create/Edit Map…
  • Under “New Map” select the radio button “Export data from Worldship” and check “Export CSV” when it becomes enabled.
  • From the dropdown list, select “Commodity
  • In the “Name” field, enter a memorable name for your map and click “Create
  • The “Commodity” tab should be selected; if not, select it and click “Add all columns
  • Select the “SED specific data” tab and click “Add all columns
  • Select the “NAFTA specific data” tab and click “Add all columns
  • As you add columns, the column names will show up on the right side of the window
  • Select the radio button “Overwrite existing file” and check “Include header row
  • Click “OK
  • Click “Save
  • Click “OK

Section 1.2: Export Commodities

In this section you will perform the actual export of the commodities.

  • Go to Import/Export Data > Batch Export…
  • Highlight the map you created in Section 1.1 and click “Next
  • Click “Next
  • Choose a memorable location to save the file and click “Save
  • You have now created a .csv file. You will need a copy of this file to use for importing commodities to the target computer

STEP 2: IMPORT

Section 2.1: Create an Import Map

In this section you will create a new map for importing commodities using the .csv file you created in Section 1.2. (1) If you have previously created an import map, you can skip this section.

  • Go to Import/Export Data > Connection Assistant…
  • Select the radio button “Create a new map for Import” and click “Next
  • Under “Import Data Types” select “Commodity” from the drop down list and click “Next
  • Select the radio button “By File” and click “Browse…
  • Next to “Files of type:” select “Text Files (*.txt, *.csv)” from the drop down list
  • Select the .csv file you created in Section 1.2 (1)
  • Under “Data Source Name (DSN)” enter a memorable and unique name (it must be different than the name you used in Section 1.1)
  • Under “ODBC Drivers” highlight “Microsoft Text Driver (*.txt, *.csv)
  • Click “Next
  • The radio button “New Map” should be selected; if not, select it
  • Under “New Map Name:” enter the unique name you created for the Data Source Name previously
  • Click “Next
  • Click “Finish
  • The “ODBC Text Setup” window will open
  • Click “Options>>
  • Click “Define Format…
  • Select your .csv file from the list
  • Check “Column Name Header
  • Click “Guess
  • The “Columns” field will be populated with the column names from your .csv file
  • Highlight each column name and verify that the “Data Type” is “Char” and the “Width” is 255, making changes as necessary
  • Click “OK
  • If you see an error that says “Failed to save table attributes of (null) into (null).” Click “OK” (this has no effect on the import)
  • Back in the “ODBC Text Setup” window, click “OK
  • Now you are back to the “Edit <mapname> import map” window, where you will manually define the database relationships. You will see “ODBC Tables” on the left with the column names from your .csv file, and “WorldShip Fields” on the right with field names that match your column names. Under “WorldShip Fields” there is a drop down list that includes “Commodities”, “SED specific data”, and “NAFTA specific data”.
    • On the left under “ODBC Tables” drag the “Column Name” column to the right until you can see the entire description of each item. Each item’s name on the left will correspond to the field names under each drop down category on the right. For example, the item on the left called “COMMODITYDESCRIPTIONOFGOODS” corresponds to the item on the right called “Description of goods” under the “Commodity” drop down category.
    • Highlight the first pair of corresponding items and click “Connect.” You will see a matching red symbol next to the paired items when they are connected.
    • Do this for each pair, except for the “COMMODITYPARTNUMBER” item. For this item, select the corresponding items on each side, click “Define Primary Key for Import” (you will see a key symbol show up next to the left item only), then click “Connect.
  • After you have connected all the items, click “OK
  • When it asks “Do you want to Batch Import now with <mapname>?”, click “Yes
  • Click “Next
  • Click “Save
  • You will see the UPS Truck progress bar. When it is finished, click “Save

Section 2.2: Import Commodities

In this section you will perform only an import of the commodities using the map you created in Section 2.1. (1) If you have just done Section 2.1, you have already done a batch import and do not need to do this section.

  • Go to Import/Export Data > Batch Import…
  • Highlight the map you created in Section 2.1 and click “Next
  • In the “Import/Export Preview“ window, click “Next
  • You will see the UPS Truck progress bar, followed by the “Import/Export Summary“ window
  • Click “Save

NOTES

(1) The Import Map includes a reference to the directory and filename of the .csv export file. When using the Import Map to import from a new Export file, be sure the exported .csv is saved with the exact directory and filename referenced in the Import Map. If you are unsure, follow the steps to create a new Import Map.

Posted in UPS WorldShip | Leave a Comment »