Importing product descriptions into ZenCart using PowerShell, Excel, and phpmyadmin - Part 2

Posted on January 17th, 2008 in E-Commerce, PowerShell, Zen Cart by Tom

If you followed the last post, this one is a continuation.

So, you’ve imported all of your products into the products table with the last script. Next, you need to add the information about the products to products_to_categories, so the categories are properly mapped, and to products_descriptions, so you have a name, etc.

 You’ll need the products_id of the FIRST product you inserted with the last script.

Check out this PowerShell script: More…

Importing product catalogs into ZenCart using PowerShell, Excel, and phpmyadmin - Part 1

Posted on January 17th, 2008 in PowerShell by Tom

I’ve been busy tonight working on ChaosCollectibles, trying to get all of the products added. Since the first thing I did was grab all of the images, I was done “scanning.” Next, I needed to add them all to the site.

Dave had spent about 5 hours in total adding around 100 cards. We still had 140 to go, and let’s face it…I’m lazy. Well, not lazy. I just prefer scripting and saving time where I can. It’s like the old saying around work: “Work Smart.”

 Since I had a standard naming convention for the image files, I was able to use those as a basis for my import. My hosting provider give me SQL access through PHPMyAdmin, so I can run SQL scripts…I just needed some SQL queries and stuff to run.

Product information is stored in 3 tables in the database for ZenCart. These tables are “products”, “products_description”, and “product_to_categories.” Products has a TON of columns. The others have 5 and 2, respectively. Now, as I was saying, I had a standard image naming convention. That convention was CTDOP_cardname.jpg.

 Based on that, I could do some image manipulation, and fill out some basic data I needed for the product table. The products has a column called products_id that is auto-incremented. This column is referenced by the other two tables. To fill out the products table with the card-specific information, I needed the following:

Product name, image location, date added, model name, and a few other fields that I could have made static, but chose to use variables for. Since I used that handy naming convention above, I was able to manipulate the names of every image file into something I could insert into the database to keep with the other conventions. For example, my model name convention is CTDOPcardname (no underscores). My image location was…the name of the file. That’s easy enough. Then I had to format some dates, and output my SQL statement. So, I’m tired of blabbing. Here it is.

Edit: OK, I was having issues with my code formatting. I really need a new, code-friendly template. I’m open to suggestions.

Here’s the script: Add-Product.ps1 - PowerShell script to generate ZenCart products

So, you’ll be left with a long list of SQL statements. But, we’ve still got the other two tables. Import that list anyway. Make a note of the FIRST products_id that gets imported, after the import completes.

The next step involves checking that table you just imported all of those products into. Since products_id auto-increments, you need to see where you started, and where you finished and make a note of those numbers.

I’m going to end this one right here and add a second post. This is getting too long, I think. Check here.

www.chaoscollectibles.com and PowerShell system.net.webclient Script

Posted on January 12th, 2008 in PowerShell, Vista by Tom

I finally did it. I got the e-commerce bug and started my own shop. I’m working with Dave K on it, and we’re progressing quite well with a lot of mentoring from Bill and all of his XekoShop experience.

So, PhishThis will contain a lot of posts related to how I’m making like easier for myself as far as batch watermarking, getting images, etc.

Here’s one:

I need to scan all of my cards for Chaotic. But they have them all online and could save me some trouble. However, I don’t feel like right-click-saving 250 times. Enter, you guessed it, PowerShell.

I need to create a web client to connect to the site.
$wc = new-object system.net.webclient
Now, the site requires a login. You might say “CRAP!” However, the webclient supports passing credentials, as long as they’re typed as system.net.networkcredential

So, I can login to the site, from PowerShell with:
$wc.credentials = new-object system.net.networkcredential("username", "password")

Now, there were around 250 images, so I construct a simple for loop that uses $wc.downloadfile(”source”, “location”) and we end up with:

$wc = new-object system.net.webclient
$wc.credentials = new-object system.net.networkcredential("username", "password")
for ($i = 0; $i -lt 250;$i++)
{
  $wc.downloadfile("www.foobar.com/getimages.aspx?ImageID=$($i)", "C:\images\$($i).jpg")
}

This script saved me HOURS of scanning and stuff…and now, even if the card is out of stock, I still have the image. That makes sense in my head.  

After, I set my view for that folder to EXTRA LARGE icons. This shows a readable preview of the jpeg. I renamed the first one, and instead of hitting enter after each one, I hit tab, and it went to the next file to rename it. I didn’t know you could do that, and tried on a whim. Saved me many keystrokes.

Next, I’m going to need to add them all to Zen Cart. Since I’m lazy a script kiddy, I’m going to write a script that will look at all of the product images in a folder, and write my SQL queries based on them. Hopefully I’ll even get it to do all of my formatting, too. We’ll see. Look for that this weekend sometime.

PowerShell Script for Remote Event Log Viewing

Posted on December 13th, 2007 in Microsoft, PowerShell, Server Management by Tom

I had an issue today where I needed to find the frequency of an error on some of my VMs. It seems like I get VMSCSI errors at the same time each which (which probably means high SAN activity, but I’m trying to nail everything down). Either way, I needed to check all of my event logs for EventID 11 and 15. It’s slow…and by slow I mean it took about 30 minutes to scan 10 or so VMs…but it works, and I was able to get a decent idea of the times I’m seeing these errors.

$servers = .\getservernames.ps1 Tom 
 
foreach ($server in $servers) 
{ 
     if ((get-wmiobject -computer $server win32_computersystem).manufacturer -eq "VMware, Inc.") 
     { 
         get-wmiobject -query 
            "select * from Win32_NTLogEvent where LogFile = 'System' AND EventCode = 11 
            OR EventCode = 15" | 
            foreach { add-content c:\temp\$server.log "$_.timegenerated - $_.eventcode" }
     }
}

Aaaand, it’ll return logs for each server, with a time stamp, the event ID, and nothing more. Quick, dirty, but took me 5 minutes and got the info I needed…30 minutes later :p There’s probably a better way. I’ll have to see what I can come up with.

WSUS/WDS Debacle

Posted on October 30th, 2007 in Active Directory, PowerShell, Server Management by Tom

I don’t understand the big issue with the accidental release of WDS (Windows Desktop Search) via WSUS (here). It wasn’t like MS said “Muhuhahaha, let’s release WDS  to the masses via WSUS!” I mean…why? There’s no compelling reason for this besides a simple mistake. Now, the fact that the mistake was made is a little scary. I don’t want some blue-screen causing driver or security update released to 500 servers. That might wreck my month…no, year. Then again, how many critical servers are set to auto-update? Test and QA boxes, but never production, unless you’re load balanced (ie, IIS boxes), and can stagger update times. At least that’s how I see it…

Removal was pretty easy, too. Altiris works wonders. But, let’s say you don’t have Altiris. You could use (ready for this?) PowerShell. They provide the removal instructions on the WDS blog entry. Using another handy utility, PSEXEC, you could very easily run a script to remove WDS. It might take a while, depending on the number of machines, but it’ll work…and without much effort.

For the sake of argument (and typing), let’s say it went to every box on your domain, server and desktop. This will only return 1,000 objects, so you’ll need to break it out by OU or some other method if you have more than that. Here’s my remove wds script (excuse the formatting…)

$root = new-object DirectoryServices.DirectoryEntry
$searcher = new-object DirectoryServices.DirectorySearcher
$searcher.SearchRoot = $root
$searcher.Filter = "(samaccounttype=805306369)"
$machines = $searcher.FindAll()
foreach ($machine in $machines)
{
  psexec.exe "\\$($machine.properties.cn)" -d - c:\windows\`$NtUninstallKB917013`$\spuninst\spuninst.exe /q /norestart
  #run PSEXEC, execute sp uninstaller quietly, with no restart. PSEXEC will not wait for app to finish
  #and will only wait 5 seconds before timing out when attempting to run the remote command
}

Now, you’ve kicked off the task to remove the update from all of your machines…or 1,000 of them.

Get-ServerNames.ps1

Posted on September 28th, 2007 in Active Directory, PowerShell, Server Management by Tom

Here’s the script I metioned a few days ago. I wrote this a while back (Pre-RC0, I think).

 Anyway, if you’ve got a bunch of servers that you need to perform a common task on (copy files, check event logs, etc), this is handy…however, it only works if you’ve got the Managed By field set in AD. Otherwise, you’re SOL. First, it makes sure the account name given exists in AD, then searches AD for and computer objects managed by that account. It uses write-output to return the list of servers. It outputs strings, not objects, since that’s all I needed out of it.

Syntax is: .\get-servernames.ps1 <samaccountname>
$root = new-object DirectoryServices.DirectoryEntry 'LDAP://dc=foo,dc=bar,dc=com'
$searcher = new-object DirectoryServices.DirectorySearcher
$searcher.SearchRoot = $root
$searcher.Filter = "(samaccountname=$($args[0]))"
$results = $searcher.findOne()
if ($results -eq $null) {
 write-host -fore 'blue' -back 'white' "`"$($args[0])`" not found"
 exit(1)
}
else {
 $dn = $results.GetDirectoryEntry().distinguishedname
 $searcher.Filter = "(&amp;(samaccounttype=805306369)(managedby=$($dn)))"
 $servers = $searcher.FindAll()
  if ($($servers.count) -gt 0) {
   foreach ($server in $servers) { write-output "$($server.GetDirectoryEntry().cn)" }
 }
}

As I mentioned, this is pretty handy for copying files to groups of servers, checking error logs via psloglist, doing inventory, and more.

PowerShell Script for Server Hardware Updates

Posted on September 25th, 2007 in PowerShell, Server Management by Tom

No. This script doesn’t do the updates for you, as awesome as that would be. I have a bunch of boxes that I have to do firmware updates on tonight. Apparently the Dell PERC4 has an issue on a certain firmware revision that will cause arrays of 5 or more disks in RAID 5 or 50 to fail during rebuild after replacing a failed disk (and I have a disk to replace). My array isn’t 5 disks but I’m playing it safe, as this is a production server. So, I thought “I don’t want to have to hit this from a file share tonight, or have to copy it tonight…” Go go lazy powers. I wanted to copy this to all of my DELL boxes, but not the VMs or HP machines. Enter, PowerShell.

 .\get-servernames.ps1 <samname>
  | foreach {
      if ((get-wmiobject -computer $_ win32_computersystem).manufacturer -contains “*Dell*”) {
         copy-item c:\SUU \\$_\c$\suu -recurse -force
    }
}

More on get-servernames.ps1 later. But, now my SUU is on all of the servers and waiting for me tonight. I kicked it off and went home. And excuse the formatting, the layout is a work in progress!