<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PhishThis! &#187; PowerShell</title>
	<atom:link href="http://www.phishthis.com/category/powershell/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.phishthis.com</link>
	<description></description>
	<lastBuildDate>Tue, 22 Feb 2011 05:48:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>How to create DHCP scopes with PowerShell</title>
		<link>http://www.phishthis.com/2010/06/18/how-to-create-dhcp-scopes-with-powershell-2/</link>
		<comments>http://www.phishthis.com/2010/06/18/how-to-create-dhcp-scopes-with-powershell-2/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 20:31:13 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[add scope]]></category>
		<category><![CDATA[DHCP]]></category>
		<category><![CDATA[netsh]]></category>
		<category><![CDATA[PowerShell Script]]></category>

		<guid isPermaLink="false">http://www.phishthis.com/?p=194</guid>
		<description><![CDATA[<p>Recently I was approached by a network engineer who was adding scopes to DHCP for our move to Detroit. He had around 80 of them to configure, including all of the different options for the subnets. I did a little research and couldn&#8217;t find a native snapin for PowerShell to handle creating the scopes [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I was approached by a network engineer who was adding scopes to DHCP for our move to Detroit. He had around 80 of them to configure, including all of the different options for the subnets. I did a little research and couldn&#8217;t find a native snapin for PowerShell to handle creating the scopes and setting options, but I did know that it could be done via netsh dhcp. </p>
<p>So, I went the second best route and wrote a script that would write a script that would add the scopes for me. The network engineer had a spreadsheet with all of the scopes, their subnet mask, name, and VLANID. Also, for each of the types of scope (data, voice, misc), there were certain DHCP options that had to be set. Those weren&#8217;t in the spreadsheet, but he included them in an email and said &#8220;for X type, use these settings.&#8221; </p>
<p>I can probably improve upon my script by having it look at the spreadsheet for the option values, but this suited our needs and worked pretty well.</p>
<p>The script takes in four parameters. </p>
<p><strong>-csvpath</strong> &#8211; The path to the CSV file containing the scope info. Since the script uses import-csv, it&#8217;s important to make sure that the header columns on the csv are &#8220;Subnet&#8221; &#8220;Mask&#8221; &#8220;Name&#8221; and &#8220;VLANID.&#8221; MASK should be in a 255.255.255.0 or 255.255.254.0 format (or 253, etc).<br />
<strong>-scriptpath</strong> &#8211; This is the path where you want to output the script file.<br />
<strong>-logpath</strong> &#8211; This is for debugging, but lets you go through in an organized manner to verify the data used to create the netsh script.<br />
<strong>-reverseScriptPath</strong> &#8211; This creates a &#8220;delete&#8221; script. It&#8217;ll go through and remove all fo the subnets you just created&#8230;you know, just in case.</p>
<p>It&#8217;s worth mentioning that this script is only good for creating scopes with a 24 bit subnet mask. In this case, we were adding to a Class A network with a 24-bit subnet mask. (10.X.Y.0/24) We were adding a bunch of scopes like 10.10.x.0/24. It can easily be modified (by you :) to work for different subnets. </p>
<p>Run this from powershell, use the above arguments, and it&#8217;ll give you something to work with. It took about an hour to create the 75 scopes. </p>
<p>Feel free to post questions and your own results! </p>
<p>The output will look like this, but with your IPs and data&#8230;obviously&#8230;<br />
<code><br />
rem *********************************************<br />
rem Creating script for 3rd Floor North Data<br />
netsh dhcp server 192.168.10.10 add scope 192.168.1.1 255.255.255.0 "3rd Floor North Data"<br />
netsh dhcp server 192.168.10.10 scope 192.168.1.1 add iprange 192.168.1.1 192.168.1.254<br />
netsh dhcp server 192.168.10.10 scope 192.168.1.1 add excluderange 192.168.1.1 192.168.1.10<br />
netsh dhcp server 192.168.10.10 scope 192.168.1.1 add excluderange 192.168.1.225 192.168.1.254<br />
netsh dhcp server 192.168.10.10 scope 192.168.1.1 set optionvalue 003 IPADDRESS 192.168.1.1<br />
netsh dhcp server 192.168.10.10 scope 192.168.1.1 set optionvalue 051 DWORD 691200<br />
netsh dhcp server 192.168.10.10 scope 192.168.1.1 set optionvalue 230 STRING "timeserver=192.168.5.10;timezone=5;dst= -1 8 2 2 1 1 10 2"<br />
netsh dhcp server 192.168.10.10 scope 192.168.1.1 set optionvalue 241 IPADDRESS Vendor="My Vendor Name" 192.168.2.10 192.168.2.11<br />
netsh dhcp server 192.168.10.10 scope 192.168.1.1 set state 1<br />
rem Done creating script for 3rd Floor North Data<br />
rem *********************************************<br />
</code></p>
<p>And here&#8217;s the script:</p>
<pre>
###################################################################################################
#
#  PowerShell script to create a batch script that runs netsh dhcp commands to create new scopes
#  - Tom Moser
#  - Last Modified: 18 June 2010
#
#  - Feel free to reuse, modify, and redistribute, but give credit where credit is due
#
#  http://www.phishthis.com
#
###################################################################################################

param($csvpath, $scriptpath, $logpath, $reverseScriptPath)

$networks = import-csv $csvpath

#for each line in the csv - I call the imported object "network." Maybe $scope would be better...meh.
foreach($network in $networks)
{
    if($network.Name.contains("Data") -or $network.Name.contains("Voice") -eq $false -or $network.Name.contains("Misc") -eq $false)
    {
    	$networktype = "Data"
    }

    if($network.Name.contains("Voice"))
    {
    	$networktype = "Voice"
    }

    if($network.Name.contains("Misc"))
    {
    	$networktype = "Misc"
    }

    #enter your DHCP IP here
    $dhcpServerIp = "X.X.X.X"

    #put info in to vars
    $subnet = $network.subnet
    $mask = $network.mask
    $name = $network.Name
    $vlan = $network.VLANID

    #split subnet address in to octets
    $octets = $subnet.split('.')

    #create a base for the current subnet (a string like 192.168.1)
    $subnetBase = "$($octets[0]).$($octets[1]).$($octets[2])"

    #create DHCP range start and end - change these to fit your needs
    $rangeStart = "$($subnetBase).1"
    $rangeEnd = "$($subnetBase).254"

    #create DHCP exclusion range - This example will exclude 192.168.0.1 - 20 and 192.168.220 - 250.
    #change it to fit your needs. You can also get rid of the exclusionend variable and just have one
    #range if that's all you need
    $exclusionStart = "$($subnetBase).1 $($subnetBase).10"
    $exclusionEnd = "$($subnetBase).220 $($subnetBase).250"

    #sets optionvalue 003 - Router. Assumes that you're using X.X.X.1 for your gateway.
    $optionValue003 = "$($subnetBase).1"

    #I use a switch statement here because I had different option values for each type of scope
    #change this as you need. My scope names actually contained the words data, voice, and misc.
    switch($networkType)
    {
        "Data"
	   {
		  #option 006 is DNS servers - You don't need to set this if you're setting it on the server options. You can override, though.
		  $optionValue006 = "X.X.X.X Y.Y.Y.Y Z.Z.Z.Z"
          #option 015 is DNS Domain Name - Also not needed, unless you're going to change it from the server options.
		  $optionValue015 = "domain.forest.root.com"
          #option 044 is WINS/NBNS Servers - again, not needed unless different than the server options.
		  $optionvalue044 = "X.X.X.X Y.Y.Y.Y Z.Z.Z.Z"
          #option 046 is WINS/NBT Node Type...same deal as above.
		  $optionvalue046 = "8"
          #dhcp lease time in seconds - this is 8 days
          $optionvalue051 = 691200
          #option 020 - Timeserver"
		  $optionvalue230 = "timeserver=X.X.X.X;timezone=5;dst= -1 8 2 2 1 1 10 2"
          #this is an example of adding a vendor and IPADDRESS - see the netsh below for details.
		  $optionvalue241 = "X.X.X.X Y.Y.Y.Y"
	   }
	   "Voice"
       {
          #option 006 is DNS servers
		  $optionValue006 = "X.X.X.X Y.Y.Y.Y Z.Z.Z.Z"
          #option 015 is DNS Domain Name
		  $optionValue015 = "domain.forest.root.com"
          #option 044 - WINS/NBNS Servers
		  $optionvalue044 = "X.X.X.X Y.Y.Y.Y Z.Z.Z.Z"
          #option 046 - WINS/NBT Node Type
		  $optionvalue046 = "8"
          #dhcp lease time in seconds - this is 8 days
          $optionvalue051 = 691200
          #option 020 - Timeserver"
		  $optionvalue230 = "timeserver=X.X.X.X;timezone=5;dst= -1 8 2 2 1 1 10 2"
	   }

	   "Misc"
	   {
          #optionValue006 is different for the misc scopes
    	  $optionValue006 = "A.A.A.A B.B.B.B"
          #optionvalue051 is lease time and set to 8 hours instead of days
          $optionvalue051 = 28800
	   }
    }

    ### output log info - this is just to verify that you wrote out the values you expected. Helps with auditing.
    add-content $logpath "`r`n`r`n*********************************************"
    add-content $logpath "Creating scope with the following parameters: "
    add-content $logpath "Scope name: $name"
    add-content $logpath "   Address: $subnet"
    add-content $logpath "      Mask: $mask"
    add-content $logpath "ScopeClass: $networkType"
    add-content $logpath "   VLAN ID: $vlan"
    add-content $logpath "     Range: $rangeStart to $rangeEnd"
    add-content $logpath "Exclusion1: $exclusionStart"
    add-content $logpath "Exclusion2: $exclusionEnd"
    add-content $logpath "       003: $optionValue003"
    add-content $logpath "       006: $optionvalue006"
    add-content $logpath "       051: $optionvalue051"
    if($networkType -ne "Misc")
    {
    	add-content $logpath "       015: $optionvalue015"
    	add-content $logpath "       044: $optionvalue044"
    	add-content $logpath "       046: $optionvalue046"
    	add-content $logpath "       176: $optionvalue176"
    	add-content $logpath "       230: $optionvalue230"
    }

    if($networkType -eq "Data")
    {
    	add-content $logpath "       241: $optionValue241"
    }
    add-content $logpath "`*********************************************"

    #### end logging

    #### create script
    # This is where we actually write out all of the netsh commands
    # you need to run this from your DHCP server.
    add-content $scriptpath "rem *********************************************"
    add-content $scriptpath "rem Creating script for $name"

    #add scope
    add-content $scriptpath "netsh dhcp server $dhcpServerIp add scope $subnet $mask `"$name`""

    #add distribution range
    add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet add iprange $rangeStart $rangeEnd"

    #add exclusion range 1
    add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet add excluderange $exclusionStart"

    #add exclusion range 2 - remove this if you don't have a second exclusion range
    add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet add excluderange $exclusionEnd"

    #set scope option 003 - Router
    add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet set optionvalue 003 IPADDRESS $optionValue003"

    #this sets the different DNS servers for the Misc scopes
    if($networkType -eq "Misc")
    {
        #set scope option 006 - DNS Servers
        add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet set optionvalue 006 IPADDRESS $optionValue006"
    }

    #set dhcp  option 051 - DHCP Lease length
    add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet set optionvalue 051 DWORD $optionvalue051"

    #these are only set on the data or voice scopes - not on misc.
    if($networkType -ne "Misc")
    {
        #the first three are commented because they aren't needed unless you're overriding the DHCP server options.

        #set scope option 015 - domain Name
        #add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet set optionvalue 015 STRING $optionvalue015"

        #set scope option 044 - WINS/NBNS
        #add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet set optionvalue 044 IPADDRESS $optionValue044"

        #set scope option 046 - Wins/NBNS - 0x8
        #add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet set optionvalue 046 BYTE $optionvalue046"

        #set scope option 230 OnTimeClock
        add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet set optionvalue 230 STRING `"$optionvalue230`""
    }

    #again, only for data
    if($networkType -eq "Data")
    {
        #this is an example of how to set IPs and a vendor class on a scope option
        #the syntax is optionvalue XXX IPADDRESS Vendor=vendor name XXX.XXX.XXX.XXX YYY.YYY.YYY.YYY
    	#set scope option 241 Option43
    	add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet set optionvalue 241 IPADDRESS Vendor=`"My Vendor Name`" $optionvalue241"
    }

    #activate scope
    add-content $scriptpath "netsh dhcp server $dhcpServerIp scope $subnet set state 1"

    #this creates the deletion script - just in case you bork a parameter and need to delete and start over
    #you could also use the script to create a fix, but this might be easier
    add-content $reverseScriptPath "netsh dhcp server $dhcpServerIp delete scope $subnet"

    add-content $scriptpath "rem Done creating script for $name"
    add-content $scriptpath "rem *********************************************`r`n"
    #you're done! Depending on the number of scopes you create, it can take some time. The 75 or so scopes I created took around 30 minutes.
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.phishthis.com/2010/06/18/how-to-create-dhcp-scopes-with-powershell-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to kill all but the newest Excel process with PowerShell</title>
		<link>http://www.phishthis.com/2010/01/09/how-to-kill-all-but-the-newest-excel-process-with-powershell/</link>
		<comments>http://www.phishthis.com/2010/01/09/how-to-kill-all-but-the-newest-excel-process-with-powershell/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 20:40:30 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[End Process]]></category>

		<guid isPermaLink="false">http://www.phishthis.com/?p=157</guid>
		<description><![CDATA[<p>Excel was the example I used, but you could use anything&#8230;Somebody on HardForums.com was asking about a way to kill all but the most recently started Excel process. I came up with this:</p> get-process &#124; where-object { $_.name -eq "excel" } &#124; sort-object -property "Starttime" -descending &#124; select-object -skip 1 &#124; foreach { taskkill [...]]]></description>
			<content:encoded><![CDATA[<p>Excel was the example I used, but you could use anything&#8230;Somebody on HardForums.com was asking about a way to kill all but the most recently started Excel process. I came up with this:</p>
<pre>get-process | where-object { $_.name -eq "excel" } | sort-object -property "Starttime" -descending | select-object -skip 1 | foreach { taskkill /pid $_.id }</pre>
<p>If there is just one excel process running, it will leave that process alone, thanks to the -skip 1 in Select-Object.</p>
<p>I can&#8217;t imagine this is too useful, but who knows? :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phishthis.com/2010/01/09/how-to-kill-all-but-the-newest-excel-process-with-powershell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>get-servernames.ps1 &#8211; Return a List of Computer Objects from Active Directory</title>
		<link>http://www.phishthis.com/2008/12/18/get-servernamesps1-return-a-list-of-computer-objects-from-active-directory/</link>
		<comments>http://www.phishthis.com/2008/12/18/get-servernamesps1-return-a-list-of-computer-objects-from-active-directory/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 18:00:36 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Server Management]]></category>
		<category><![CDATA[get-servernames.ps1]]></category>

		<guid isPermaLink="false">http://www.phishthis.com/?p=57</guid>
		<description><![CDATA[<p>I should have posted this a long, long time ago&#8230;but forgot. Until I got a comment from dvdor about it. </p> <p>In Active Directory, we set the &#8220;Managed By&#8221; field on all of the servers we manage to our primary, non-admin account. This makes it easy for people to find out who manages what [...]]]></description>
			<content:encoded><![CDATA[<p>I should have posted this a long, long time ago&#8230;but forgot. Until I got a comment from dvdor about it. </p>
<p>In Active Directory, we set the &#8220;Managed By&#8221; field on all of the servers we manage to our primary, non-admin account. This makes it easy for people to find out who manages what servers. It also makes it easy to do batch upgrades/file copies/whatever to your own servers. </p>
<p>This script, get-servernames.ps1, has a single parameter. -username. It just returns a text list of your servers&#8230;no objects or anything. I didn&#8217;t see the need, since all I wanted was the names.</p>
<p>Syntax: .\get-servernames.ps1 -username tmoser</p>
<p>Summary: Will take in your username (samaccountname) and first search AD for it. If found, it will search AD for all computer objects that have your account in the &#8220;Managed By&#8221; field. Those are returned in a list. </p>
<p>Uses: Things like: .\get-servernames.ps1 -username tmoser | foreach { copy-item C:\temp\somefile.txt \\$_\c$\temp\somefile.txt } </p>
<p>You can use it for error log checking, copying files, running remote psexec commands&#8230;anything, really. </p>
<pre>
param($username)

$root = new-object DirectoryServices.DirectoryEntry 'LDAP://dc=yourdomain,dc=com'
$searcher = new-object DirectoryServices.DirectorySearcher
$searcher.SearchRoot = $root
$searcher.Filter = "(samaccountname=$username)"

$results = $searcher.findOne()

if ($results -eq $null) {
	write-host -fore 'blue' -back 'white' "`"$($username)`" not found"
	exit(1)
}
else {
	$dn = $results.GetDirectoryEntry().distinguishedname
	$searcher.Filter = "(&#038;(samaccounttype=805306369)(managedby=$($dn)))"
	$servers = $searcher.FindAll()
		if ($($servers.count) -gt 0) {
			foreach ($server in $servers) { write-output "$($server.GetDirectoryEntry().cn)" }
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.phishthis.com/2008/12/18/get-servernamesps1-return-a-list-of-computer-objects-from-active-directory/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Importing product descriptions into ZenCart using PowerShell, Excel, and phpmyadmin &#8211; Part 2</title>
		<link>http://www.phishthis.com/2008/01/17/importing-product-descriptions-into-zencart-using-powershell-excel-and-phpmyadmin/</link>
		<comments>http://www.phishthis.com/2008/01/17/importing-product-descriptions-into-zencart-using-powershell-excel-and-phpmyadmin/#comments</comments>
		<pubDate>Thu, 17 Jan 2008 06:12:48 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[E-Commerce]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Zen Cart]]></category>
		<category><![CDATA[chaoscollectibles]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[Import Products Into ZenCart with PowerShell]]></category>
		<category><![CDATA[www.chaoscollectibles.com]]></category>
		<category><![CDATA[ZenCart]]></category>

		<guid isPermaLink="false">http://www.phishthis.com/2008/01/17/importing-product-descriptions-into-zencart-using-powershell-excel-and-phpmyadmin/</guid>
		<description><![CDATA[<p>If you followed the last post, this one is a continuation.</p> <p>So, you&#8217;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. </p> [...]]]></description>
			<content:encoded><![CDATA[<p>If you followed the last post, this one is a continuation.</p>
<p>So, you&#8217;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. </p>
<p> You&#8217;ll need the products_id of the FIRST product you inserted with the last script.</p>
<p align="center">Check out this PowerShell script:<span id="more-19"></span> <a rel="attachment wp-att-21" target="scriptwindow" href="http://www.phishthis.com/2008/01/17/importing-product-descriptions-into-zencart-using-powershell-excel-and-phpmyadmin/powershell-script-to-generate-zencart-products-descriptions-and-link-categories/" title="PowerShell script to generate ZenCart products descriptions and link categories">PowerShell script to generate ZenCart products descriptions and link categories</a></p>
<p>Edit that and set $i equal to whatever that first products_id was. Run the script from the directory will all of your image files (assuming you&#8217;ve formatted the names), and you&#8217;ll end up with a CSV that contains two columns. The first is the almost-nicely-formatted product name, and the second is the corresponding products_id. The problem is, unless you capitalized each word in the name (EPIC FAIL on my part), you&#8217;ll have all lower case. Doesn&#8217;t look so hot.</p>
<p>I read about this neat feature in Excel tonight.  It&#8217;s called PROPER and it will convert the first letter of each word in a cell to upper case. So, open your CSV in Rxcel, create a formula in C1 that looks like this: =PROPER(A1)</p>
<p>Copy that down column C, and suddenly you&#8217;ll find yourself with nicely formatted and capitalize product titles. Save that CSV somewhere, and check out the next script.</p>
<p align="center"><a href="http://www.phishthis.com/wp-content/uploads/2008/01/build-productcsv.ps1" title="PowerShell script to generate ZenCart products descriptions for import to Excel">PowerShell script to generate ZenCart products descriptions SQL statements</a></p>
<p>This one generates two files, one for the products_description table and one for products_to_categories.  </p>
<p>Import both of those files into PHPMyAdmin, and you&#8217;ve just saved yourself about 10 hours of data entry. Check out <a href="http://www.chaoscollectibles.com/">www.chaoscollectibles.com</a> and see how that hour of scripting saved me all that time :) Work Smart.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phishthis.com/2008/01/17/importing-product-descriptions-into-zencart-using-powershell-excel-and-phpmyadmin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Importing product catalogs into ZenCart using PowerShell, Excel, and phpmyadmin &#8211; Part 1</title>
		<link>http://www.phishthis.com/2008/01/17/importing-product-catalogs-into-zencart-using-powershell-excel-and-phpmyadmin/</link>
		<comments>http://www.phishthis.com/2008/01/17/importing-product-catalogs-into-zencart-using-powershell-excel-and-phpmyadmin/#comments</comments>
		<pubDate>Thu, 17 Jan 2008 05:41:16 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[chaoscollectibles]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[Import Products Into ZenCart with PowerShell]]></category>
		<category><![CDATA[www.chaoscollectibles.com]]></category>
		<category><![CDATA[ZenCart]]></category>

		<guid isPermaLink="false">http://www.phishthis.com/2008/01/17/importing-product-catalogs-into-zencart-using-powershell-excel-and-phpmyadmin/</guid>
		<description><![CDATA[<p>I&#8217;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 &#8220;scanning.&#8221; Next, I needed to add them all to the site.</p> <p>Dave had spent about 5 hours in total adding around 100 cards. We still [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;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 &#8220;scanning.&#8221; Next, I needed to add them all to the site.</p>
<p>Dave had spent about 5 hours in total adding around 100 cards. We still had 140 to go, and let&#8217;s face it&#8230;I&#8217;m lazy. Well, not lazy. I just prefer scripting and saving time where I can. It&#8217;s like the old saying around work: &#8220;Work Smart.&#8221;</p>
<p> 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&#8230;I just needed some SQL queries and stuff to run.</p>
<p>Product information is stored in 3 tables in the database for ZenCart. These tables are &#8220;products&#8221;, &#8220;products_description&#8221;, and &#8220;product_to_categories.&#8221; 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.</p>
<p> 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:</p>
<p>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&#8230;the name of the file. That&#8217;s easy enough. Then I had to format some dates, and output my SQL statement. So, I&#8217;m tired of blabbing. Here it is.</p>
<p><strong>Edit</strong>: OK, I was having issues with my code formatting. I really need a new, code-friendly template. I&#8217;m open to suggestions.</p>
<p align="center">Here&#8217;s the script: <a href="http://www.phishthis.com/wp-content/uploads/2008/01/add-products.ps1" title="Add-Product.ps1 - PowerShell script to generate ZenCart products">Add-Product.ps1 &#8211; PowerShell script to generate ZenCart products</a></p>
<p>So, you&#8217;ll be left with a long list of SQL statements. But, we&#8217;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.</p>
<p>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.</p>
<p>I&#8217;m going to end this one right here and add a second post. This is getting too long, I think. Check <a href="http://www.phishthis.com/2008/01/17/importing-product-descriptions-into-zencart-using-powershell-excel-and-phpmyadmin/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phishthis.com/2008/01/17/importing-product-catalogs-into-zencart-using-powershell-excel-and-phpmyadmin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>www.chaoscollectibles.com and PowerShell system.net.webclient Script</title>
		<link>http://www.phishthis.com/2008/01/12/wwwchaoscollectiblescom-and-powershell-systemnetwebclient-script/</link>
		<comments>http://www.phishthis.com/2008/01/12/wwwchaoscollectiblescom-and-powershell-systemnetwebclient-script/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 05:47:18 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[chaoscollectibles]]></category>
		<category><![CDATA[Image Grabbing Script]]></category>
		<category><![CDATA[system.net.networkcredential]]></category>
		<category><![CDATA[system.net.webclient]]></category>
		<category><![CDATA[www.chaoscollectibles.com]]></category>

		<guid isPermaLink="false">http://www.phishthis.com/2008/01/12/wwwchaoscollectiblescom-and-powershell-systemnetwebclient-script/</guid>
		<description><![CDATA[<p>I finally did it. I got the e-commerce bug and started my own shop. I&#8217;m working with Dave K on it, and we&#8217;re progressing quite well with a lot of mentoring from Bill and all of his XekoShop experience.</p> <p>So, PhishThis will contain a lot of posts related to how I&#8217;m making like easier [...]]]></description>
			<content:encoded><![CDATA[<p>I finally did it. I got the e-commerce bug and started my own shop. I&#8217;m working with Dave K on it, and we&#8217;re progressing quite well with a lot of mentoring from <a href="http://www.billparker.org">Bill</a> and all of his <a href="http://www.xekoshop.com">XekoShop</a> experience.</p>
<p>So, PhishThis will contain a lot of posts related to how I&#8217;m making like easier for myself as far as batch watermarking, getting images, etc.</p>
<p>Here&#8217;s one:</p>
<p>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&#8217;t feel like right-click-saving 250 times. Enter, you guessed it, PowerShell.</p>
<p>I need to create a web client to connect to the site.</p>
<pre>
$wc = new-object system.net.webclient
</pre>
<p>Now, the site requires a login. You might say &#8220;CRAP!&#8221; However, the webclient supports passing credentials, as long as they&#8217;re typed as system.net.networkcredential</p>
<p>So, I can login to the site, from PowerShell with:</p>
<pre>
$wc.credentials = new-object system.net.networkcredential("username", "password")
</pre>
<p>Now, there were around 250 images, so I construct a simple for loop that uses $wc.downloadfile(&#8220;source&#8221;, &#8220;location&#8221;) and we end up with:</p>
<pre>
$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")
}
</pre>
<p>This script saved me <strong>HOURS</strong> of scanning and stuff&#8230;and now, even if the card is out of stock, I still have the image. That makes sense in my head.  </p>
<p>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&#8217;t know you could do that, and tried on a whim. Saved me many keystrokes.</p>
<p>Next, I&#8217;m going to need to add them all to Zen Cart. Since I&#8217;m <del dateTime="2008-01-12T05:29:04+00:00">lazy</del> a script kiddy, I&#8217;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&#8217;ll even get it to do all of my formatting, too. We&#8217;ll see. Look for that this weekend sometime.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phishthis.com/2008/01/12/wwwchaoscollectiblescom-and-powershell-systemnetwebclient-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell Script for Remote Event Log Viewing</title>
		<link>http://www.phishthis.com/2007/12/13/powershell-script-for-remote-event-log-viewing/</link>
		<comments>http://www.phishthis.com/2007/12/13/powershell-script-for-remote-event-log-viewing/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 04:27:52 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Server Management]]></category>
		<category><![CDATA[PowerShell Script]]></category>
		<category><![CDATA[WMI]]></category>
		<category><![CDATA[WMI Query]]></category>

		<guid isPermaLink="false">http://www.phishthis.com/2007/12/13/powershell-script-for-remote-event-log-viewing/</guid>
		<description><![CDATA[Either way, I needed to check all of my event logs for EventID 11 and 15. [...]]]></description>
			<content:encoded><![CDATA[<p>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&#8217;m trying to nail everything down). Either way, I needed to check all of my event logs for EventID 11 and 15. It&#8217;s slow&#8230;and by slow I mean it took about 30 minutes to scan 10 or so VMs&#8230;but it works, and I was able to get a decent idea of the times I&#8217;m seeing these errors.<br />
[source language='c#']<br />
$servers = .\getservernames.ps1 Tom </p>
<p>foreach ($server in $servers)<br />
{<br />
     if ((get-wmiobject -computer $server win32_computersystem).manufacturer -eq &#8220;VMware, Inc.&#8221;)<br />
     {<br />
         get-wmiobject -query<br />
            &#8220;select * from Win32_NTLogEvent where LogFile = &#8216;System&#8217; AND EventCode = 11<br />
            OR EventCode = 15&#8243; |<br />
            foreach { add-content c:\temp\$server.log &#8220;$_.timegenerated &#8211; $_.eventcode&#8221; }<br />
     }<br />
}<br />
[/source]<br />
Aaaand, it&#8217;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&#8230;30 minutes later :p There&#8217;s probably a better way. I&#8217;ll have to see what I can come up with.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phishthis.com/2007/12/13/powershell-script-for-remote-event-log-viewing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WSUS/WDS Debacle</title>
		<link>http://www.phishthis.com/2007/10/30/wsuswds-debacle/</link>
		<comments>http://www.phishthis.com/2007/10/30/wsuswds-debacle/#comments</comments>
		<pubDate>Wed, 31 Oct 2007 02:47:11 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Server Management]]></category>
		<category><![CDATA[powershell psexec foreach]]></category>
		<category><![CDATA[PowerShell Script]]></category>
		<category><![CDATA[WDS]]></category>
		<category><![CDATA[Windows Desktop Search]]></category>
		<category><![CDATA[Windows Desktop Search Removal]]></category>
		<category><![CDATA[Windows Desktop Search Removal Script]]></category>
		<category><![CDATA[WSUS]]></category>

		<guid isPermaLink="false">http://www.phishthis.com/2007/10/30/wsuswds-debacle/</guid>
		<description><![CDATA[<p>I don&#8217;t understand the big issue with the accidental release of WDS (Windows Desktop Search) via WSUS (here). It wasn&#8217;t like MS said &#8220;Muhuhahaha, let&#8217;s release WDS  to the masses via WSUS!&#8221; I mean&#8230;why? There&#8217;s no compelling reason for this besides a simple mistake. Now, the fact that the mistake was made is a little scary. [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t understand the big issue with the accidental release of WDS (Windows Desktop Search) via WSUS (<a href="http://blogs.technet.com/wsus/archive/2007/10/25/wds-update-revision-follow-up.aspx">here</a>). It wasn&#8217;t like MS said &#8220;Muhuhahaha, let&#8217;s release WDS  to the masses via WSUS!&#8221; I mean&#8230;why? There&#8217;s no compelling reason for this besides a simple mistake. Now, the fact that the mistake was made is a little scary. I don&#8217;t want some blue-screen causing driver or security update released to 500 servers. That might wreck my month&#8230;no, year. Then again, how many critical servers are set to auto-update? Test and QA boxes, but never production, unless you&#8217;re load balanced (ie, IIS boxes), and can stagger update times. At least that&#8217;s how I see it&#8230;</p>
<p>Removal was pretty easy, too. Altiris works wonders. But, let&#8217;s say you don&#8217;t have Altiris. You could use (ready for this?) PowerShell. They provide the removal instructions on the WDS blog entry. Using another handy utility, <a href="http://www.microsoft.com/technet/sysinternals/Security/PsExec.mspx">PSEXEC</a>, you could very easily run a script to remove WDS. It might take a while, depending on the number of machines, but it&#8217;ll work&#8230;and without much effort.</p>
<p>For the sake of argument (and typing), let&#8217;s say it went to every box on your domain, server and desktop. This will only return 1,000 objects, so you&#8217;ll need to break it out by OU or some other method if you have more than that. Here&#8217;s my remove wds script (excuse the formatting&#8230;)</p>
<p><code><br />
$root = new-object DirectoryServices.DirectoryEntry<br />
$searcher = new-object DirectoryServices.DirectorySearcher<br />
$searcher.SearchRoot = $root<br />
$searcher.Filter = "(samaccounttype=805306369)"<br />
$machines = $searcher.FindAll()<br />
foreach ($machine in $machines)<br />
{<br />
  psexec.exe "\\$($machine.properties.cn)" -d - c:\windows\`$NtUninstallKB917013`$\spuninst\spuninst.exe /q /norestart<br />
  #run PSEXEC, execute sp uninstaller quietly, with no restart. PSEXEC will not wait for app to finish<br />
  #and will only wait 5 seconds before timing out when attempting to run the remote command<br />
}<br />
</code></p>
<p>Now, you&#8217;ve kicked off the task to remove the update from all of your machines&#8230;or 1,000 of them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phishthis.com/2007/10/30/wsuswds-debacle/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Get-ServerNames.ps1</title>
		<link>http://www.phishthis.com/2007/09/28/get-servernamesps1/</link>
		<comments>http://www.phishthis.com/2007/09/28/get-servernamesps1/#comments</comments>
		<pubDate>Sat, 29 Sep 2007 00:14:42 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Server Management]]></category>

		<guid isPermaLink="false">http://www.phishthis.com/2007/09/28/get-servernamesps1/</guid>
		<description><![CDATA[<p>Here&#8217;s the script I metioned a few days ago. I wrote this a while back (Pre-RC0, I think).</p> <p> Anyway, if you&#8217;ve got a bunch of servers that you need to perform a common task on (copy files, check event logs, etc), this is handy&#8230;however, it only works if you&#8217;ve got the Managed By field [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s the script I metioned a few days ago. I wrote this a while back (Pre-RC0, I think).</p>
<p> Anyway, if you&#8217;ve got a bunch of servers that you need to perform a common task on (copy files, check event logs, etc), this is handy&#8230;however, it only works if you&#8217;ve got the Managed By field set in AD. Otherwise, you&#8217;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&#8217;s all I needed out of it.</p>
<p>Syntax is: .\get-servernames.ps1 &lt;samaccountname&gt;</p>
<pre>
$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)" }
 }
}
</pre>
<p><font face="Georgia">As I mentioned, this is pretty handy for copying files to groups of servers, checking error logs via <a href="http://www.microsoft.com/technet/sysinternals/Security/PsLogList.mspx">psloglist</a>, doing inventory, and more. </font></p>
]]></content:encoded>
			<wfw:commentRss>http://www.phishthis.com/2007/09/28/get-servernamesps1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell Script for Server Hardware Updates</title>
		<link>http://www.phishthis.com/2007/09/25/powershell-script-for-server-hardware-updates/</link>
		<comments>http://www.phishthis.com/2007/09/25/powershell-script-for-server-hardware-updates/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 00:38:59 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Server Management]]></category>

		<guid isPermaLink="false">http://www.phishthis.com/?p=6</guid>
		<description><![CDATA[<p>No. This script doesn&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>No. This script doesn&#8217;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&#8217;t 5 disks but I&#8217;m playing it safe, as this is a production server. So, I thought &#8220;I don&#8217;t want to have to hit this from a file share tonight, or have to copy it tonight&#8230;&#8221; Go go lazy powers. I wanted to copy this to all of my DELL boxes, but not the VMs or HP machines. Enter, PowerShell.</p>
<pre>
 .\get-servernames.ps1 &lt;samname&gt;
  | foreach {
      if ((get-wmiobject -computer $_ win32_computersystem).manufacturer -contains "*Dell*") {
         copy-item c:\SUU \\$_\c$\suu -recurse -force
    }
}
</pre>
<p>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!</p>
<blockquote></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.phishthis.com/2007/09/25/powershell-script-for-server-hardware-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

