<?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>Josh Erickson &#187; code</title>
	<atom:link href="http://josherickson.org/category/code/feed" rel="self" type="application/rss+xml" />
	<link>http://josherickson.org</link>
	<description>And as you tread the halls of sanity...</description>
	<lastBuildDate>Wed, 17 Mar 2010 23:50:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Logon UI Background Changer Revisited</title>
		<link>http://josherickson.org/2010/03/17/765/logon-ui-background-changer-revisited</link>
		<comments>http://josherickson.org/2010/03/17/765/logon-ui-background-changer-revisited#comments</comments>
		<pubDate>Wed, 17 Mar 2010 23:50:46 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[Background]]></category>
		<category><![CDATA[backgroundDefault]]></category>
		<category><![CDATA[imageprocessor]]></category>
		<category><![CDATA[info]]></category>
		<category><![CDATA[LogonUI]]></category>
		<category><![CDATA[OEMBackground]]></category>
		<category><![CDATA[oobe]]></category>
		<category><![CDATA[wallpaper]]></category>
		<category><![CDATA[Windows 7]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=765</guid>
		<description><![CDATA[In a recent Hak5 episode (704, at 9 minutes) they covered changing the Logon UI background, which reminded me of my own little script.
Since last working the script, I&#8217;d like to think I&#8217;ve learned more and it was about to time clean up the code and make it a little more user friendly. It still [...]]]></description>
			<content:encoded><![CDATA[<p>In a recent Hak5 episode (<a href="http://www.hak5.org/episodes/episode-704">704</a>, <a href="http://www.youtube.com/watch?v=YtEBbnQCo9c#t=9m">at 9 minutes</a>) they covered changing the Logon UI background, which reminded me of my own little <a href="http://josherickson.org/2009/08/19/556/windows-7-powrrshell-logonui-changer">script</a>.</p>
<p>Since last working the script, I&#8217;d like to think I&#8217;ve learned more and it was about to time clean up the code and make it a little more user friendly. It still relies on the original ImageProcessor.dll, but this time, I moved the files around so you just need to unzip the archive and changing your background. If you&#8217;re as paranoid as I am, the source for ImageProcessor.dll is still included, as well as the build.bat file.</p>
<p>Download <a href='http://josherickson.org/wp-content/uploads/win7logonui1.zip'>win7logonui</a> now!</p>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2010/03/17/765/logon-ui-background-changer-revisited/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inverse ARP</title>
		<link>http://josherickson.org/2010/03/04/758/inverse-arp</link>
		<comments>http://josherickson.org/2010/03/04/758/inverse-arp#comments</comments>
		<pubDate>Thu, 04 Mar 2010 04:25:31 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[InARP]]></category>
		<category><![CDATA[Inverse Address Resolution Protocol]]></category>
		<category><![CDATA[Inverse ARP]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=758</guid>
		<description><![CDATA[While researching fast ways to find a relationship between a MAC and IP address, I dug up some info on Inverse ARP and found out that it isn&#8217;t widely a supported protocol. Basically, it&#8217;s only used in frame relay networks, which doesn&#8217;t help matters.
So I did what any sensible geek does, I hacked something together.
This [...]]]></description>
			<content:encoded><![CDATA[<p>While researching fast ways to find a relationship between a MAC and IP address, I dug up some info on <a href="http://en.wikipedia.org/wiki/InARP#Inverse_ARP_and_Reverse_ARP">Inverse ARP</a> and found out that it isn&#8217;t widely a supported protocol. Basically, it&#8217;s only used in frame relay networks, which doesn&#8217;t help matters.</p>
<p>So I did what any sensible geek does, I hacked something together.</p>
<p>This is just the proof of concept, and I do hope to someday have it more self contained. At the moment it relies on WinPcap and SharpPcap, which makes it quite large and cumbersome to deploy.</p>
<p>So far, there are two parts, inarp.exe and inarpd.exe. Inarp.exe gets the IP associated with the specified MAC, while inarpd.exe intercepts InARP packets and sends the appropriate replies.</p>
<p>Basic use:</p>
<pre>
//remote machine
inarpd.exe

//your machine
inarp "ma-ca-dd-re-ss-s0" //sends queries on all network interfaces
inarp "ma-ca-dd-re-ss-s0" "Network interface GUID" //Sends on a specific interface
No interface specified or matched criteria.
[ARPPacket: 8 AAAAAAAAAAAA -> BBBBBBBBBBBB, 0.0.0.0 -> 0.0.0.0] //InARP Request
[ARPPacket: 9 BBBBBBBBBBBB -> AAAAAAAAAAAA, 192.168.1.101 -> 0.0.0.0] //InARP Reply
</pre>
<p><a href='http://josherickson.org/wp-content/uploads/inarp.zip'>inarp code and binaries</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2010/03/04/758/inverse-arp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Of IPs &amp; Subnets</title>
		<link>http://josherickson.org/2010/01/27/723/of-ips-subnets</link>
		<comments>http://josherickson.org/2010/01/27/723/of-ips-subnets#comments</comments>
		<pubDate>Wed, 27 Jan 2010 16:57:41 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[Ip address]]></category>
		<category><![CDATA[range]]></category>
		<category><![CDATA[subnet]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=723</guid>
		<description><![CDATA[While if you look, there are tools to calculate a IP subnet/address range, they all seem to rely on string splitting and converting the address to binary manually. Which I think is bulky, hard to maintain, and more importantly, not that elegant. So pulling to mind my Cisco CCNA classes where my instructor would drill [...]]]></description>
			<content:encoded><![CDATA[<p>While if you look, there are tools to calculate a IP subnet/address range, they all seem to rely on string splitting and converting the address to binary manually. Which I think is bulky, hard to maintain, and more importantly, not that <em>elegant</em>. So pulling to mind my Cisco CCNA classes where my instructor would drill into us the binary ands and ors of IP and subnet addressing, I got down to work.</p>
<p>All examples are in Powershell, however they could be translated to C#, any .NET language or even some other language quite easily.</p>
<h3>Examples</h3>
<p>Including System.net. This may not be necessary, but I&#8217;ve mucked with my Powershell settings way too much to know about a vanilla install.</p>
<pre>
#Powershell v1.0
[reflection.assembly]::LoadWithPartialName("system.net");
#Powershell v2.0
Add-Type -AssemblyName System.Net;
</pre>
<p>A common plight for me is finding out if two different IP addresses are on the same local network.</p>
<pre>
$router = [net.ipaddress]::Parse("192.168.1.254");
$subnet = [net.ipaddress]::Parse("255.255.255.0");
$IP_one = [net.ipaddress]::Parse("192.168.1.23");
$IP_two = [net.ipaddress]::Parse("192.168.1.55");
$IP_three = [net.ipaddress]::Parse("33.21.9.1");

#get the network ID
#in this case it's 192.168.1.0
$network = $router.address -band $subnet.Address

($network -band $IP_one.Address) -eq $network #True
($network -band $IP_two.Address) -eq $network #True
($network -band $IP_three.Address) -eq $network #False
</pre>
<p>Of course there are also times where I need to know how many addresses there are in the network or what they are.</p>
<pre>
$seed = [net.ipaddress]::Parse("192.168.23.45");
$subnet = [net.ipaddress]::Parse("255.255.252.0");

$begin = ($seed.address -band $subnet.address)
$end = (([net.ipaddress]::Broadcast.Address -bxor $subnet.Address) -bor $seed.address)

#It's the same for both start and ending IP's
#We convert from a 64 to 32 bit integer (8 to 4 bytes) and then reverse it so we can do addition/subtraction math to later on.
$start_bytes = new-object byte[] 4;
[array]::copy([bitconverter]::getBytes(($seed.address -band $subnet.address)), $start_bytes, 4);
[array]::Reverse($start_bytes);
$start_int = [bitconverter]::ToInt32($start_bytes,0);

$end_bytes = new-object byte[] 4;
[array]::copy([bitconverter]::getBytes((([net.ipaddress]::Broadcast.Address -bxor $subnet.Address) -bor $seed.address)), $end_bytes, 4);
[array]::Reverse($end_bytes);
$end_int = [bitconverter]::ToInt32($end_bytes,0);

#Entire range including the network ID and Broadcast addresses
[math]::Abs($start_int - $end_int) + 1

#Just the number of usable addresses
[math]::Abs($start_int - $end_int) - 1

#Address list!
for($i=0; $i -le [math]::abs($start_int - $end_int); $i++) {
    $tba = [bitconverter]::getbytes($i + $start_int);
	[array]::Reverse($tba)
    (new-object net.ipaddress ([bitconverter]::ToInt64($tba + [byte[]]@(0,0,0,0),0))).tostring();
}
</pre>
<h3>Conclusion</h3>
<p>As you can see, using bitwise operations greatly reduces the complexity required to calculate network addresses. By simplifying the process, it makes it much easier to maintain the code and build on it later!</p>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2010/01/27/723/of-ips-subnets/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Restoring Hyper-V VM with snapshot tree</title>
		<link>http://josherickson.org/2010/01/27/728/restoring-hyper-v-vm-with-snapshot-tree</link>
		<comments>http://josherickson.org/2010/01/27/728/restoring-hyper-v-vm-with-snapshot-tree#comments</comments>
		<pubDate>Wed, 27 Jan 2010 15:44:06 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[concepts]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[avhd]]></category>
		<category><![CDATA[differencing]]></category>
		<category><![CDATA[Hyper-V]]></category>
		<category><![CDATA[restore]]></category>
		<category><![CDATA[snapshots]]></category>
		<category><![CDATA[vhd]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=728</guid>
		<description><![CDATA[For whatever reason, you&#8217;ve lost your virtual machine settings in Hyper-V and it just so happened they are snapshots. I sure hope that this was a test server and not a production one! Tsktsk! By now, you&#8217;ve probably scoured the interweb searching for a cure, and you&#8217;re in luck, you&#8217;ve found a way to get [...]]]></description>
			<content:encoded><![CDATA[<p>For whatever reason, you&#8217;ve lost your virtual machine settings in Hyper-V and it just so happened they are snapshots. I sure hope that this was a test server and not a production one! Tsktsk! By now, you&#8217;ve probably scoured the interweb searching for a cure, and you&#8217;re in luck, you&#8217;ve found a way to get back your snapshot tree instead of just merging the disks! Oh joy!</p>
<p>It would seem everyone out there is happy with just merging their VHDs and getting back to work, but not me, no sir! I want things back the way they were! It took me about half a day to get this, so hopefully, this will save you some time for more important things, like <a href="http://www.firstpersontetris.com/">tetris</a>!</p>
<h3>Steps</h3>
<ol>
<li>Create same number of pre-existing snapshots using the Hyper-V MMC.</li>
<li>Replace new snapshots with old snapshots while renaming the old to the same as the new, except the file extension should be &#8220;vhd&#8221; instead of &#8220;avhd&#8221;. The reason we&#8217;ll see later, but the Hyper-V tool to repair VHD chains auto-appends .vhd! (Grr <a href="http://blogs.technet.com/virtualization/">Hyper-V Team</a>, grr!)</li>
<li>Repair the vhd&#8217;s. Because of our renaming we&#8217;ve broken the differencing chain. To fix this, go to open  Hyper-V, go to the VM&#8217;s Settings and then the hard drive. Change the VHD to the new one (simply changing the extension should work) and click &#8220;inspect disk&#8221;. This will walk you through fixing the chain.</li>
<li>Modify the ACL to include the VM specific account. This you must to in Powershell since the Explorer GUI can&#8217;t seem to find the account. I don&#8217;t know why and there may be a way, but I&#8217;m to lazy to dig into it and this works. (Below you can find some sample code.) The account to add from the old VHD, is the one that starts with &#8220;NT VIRTUAL MACHINE&#8221; and ends with a GUID.
<pre>##START POWERSHELL CODE
#get the old vhd's permissions
$vm_perm = (get-acl .\old.vhd).access | where { $_.IdentityReference.tostring().contains("NT VIRTUAL MACHINE") }

#Load the new vhd's acl into memory
$newvhd = get-acl .\new.vhd

$newvhd.AddAccessRule($vm_perm)

$newvhd | set-acl .\new.vhd
##END POWERSHELL CODE</pre>
</li>
<li>Open all the VM&#8217;s XML setting files and make sure that any settings related the the VHD&#8217;s is correct. This should only be the filename. If you need to edit these files be sure to turn off the Hyper-V Management Service, this will not affect the VM&#8217;s running, only the managing of them. The XML files can be found wherever you made the VM.</li>
<li>You should now have a restored VM with the snapshot tree! Woo! Go you!</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2010/01/27/728/restoring-hyper-v-vm-with-snapshot-tree/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My first cmdlet, Out-Web</title>
		<link>http://josherickson.org/2009/11/12/626/my-first-cmdlet-out-web</link>
		<comments>http://josherickson.org/2009/11/12/626/my-first-cmdlet-out-web#comments</comments>
		<pubDate>Thu, 12 Nov 2009 06:04:43 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[blah]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=626</guid>
		<description><![CDATA[It&#8217;s been a while since I&#8217;ve done a for fun computer project, so I decided I wanted to learn how to make PowerShell Cmdlets. The problem was that I couldn&#8217;t think of really anything I wanted to make! Then one day I was reading Lee Holmes&#8217; blog, saw the &#8220;Out-Web&#8221; and had a project.
Download the [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I&#8217;ve done a for fun computer project, so I decided I wanted to learn how to make PowerShell Cmdlets. The problem was that I couldn&#8217;t think of really anything I wanted to make! Then one day I was reading <a href="http://www.leeholmes.com/blog/">Lee Holmes&#8217;</a> blog, saw the &#8220;Out-Web&#8221; and had a project.</p>
<p>Download the source and binaries <a href='http://josherickson.org/wp-content/uploads/out-web.zip'>here</a>. You should be able to open the solution with both Visual Studio or Visual C# Express, but if you have neither, you can build it from the command line (instructions included!). I don&#8217;t know if it&#8217;ll work with PowerShell V1, but you should have upgraded by now anyway.</p>
<p>I&#8217;d like to thank Mr. Cook from <a href="http://www.cookcomputing.com/">Cook Computing</a> for writing an awesome tool, XML-RPC.NET. And I&#8217;d also like to thank Orbifold for their <a href="http://www.orbifold.net/default/?p=1721">Wordpress XML-RPC</a> library which helped decipher the RPC calls.</p>
<p><a href="http://josherickson.org/2009/11/12/640/out-web-test">Test post.</a><br />
<a href="http://josherickson.org/wp-content/uploads/Capture.PNG"><img src="http://josherickson.org/wp-content/uploads/Capture.PNG" alt="Capture" title="Capture" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2009/11/12/626/my-first-cmdlet-out-web/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cracking the Windows Update API</title>
		<link>http://josherickson.org/2009/10/08/598/cracking-the-windows-update-api</link>
		<comments>http://josherickson.org/2009/10/08/598/cracking-the-windows-update-api#comments</comments>
		<pubDate>Thu, 08 Oct 2009 20:31:48 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[BeginInstall]]></category>
		<category><![CDATA[CreateUpdateSearcher]]></category>
		<category><![CDATA[UpdateSessionClass]]></category>
		<category><![CDATA[Windows Update]]></category>
		<category><![CDATA[WSUS]]></category>
		<category><![CDATA[WUApi]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=598</guid>
		<description><![CDATA[Something that I&#8217;ve been working on for a while is an application or script that checks the availability of other servers to decide if it should start the update/restart steps. Though testing and more testing, I&#8217;ve found that even with the awesome power of Powershell, I still needed the power of a binary to get [...]]]></description>
			<content:encoded><![CDATA[<p>Something that I&#8217;ve been working on for a while is an application or script that checks the availability of other servers to decide if it should start the update/restart steps. Though testing and more testing, I&#8217;ve found that even with the awesome power of Powershell, I still needed the power of a binary to get the best performance and least complexity.</p>
<p>However, unlike with Powershell where you can just set a variable, you gotta put more effort with C# to do something similar, especially when there&#8217;s so little documentation and I know so little about nitty gritty COM programming.</p>
<p>So getting the WUApi working in C# things to know.</p>
<ol>
<li>You need to reference &#8220;c:\windows\system32\wuapi.dll&#8221;</li>
<li>You must have have the resulting &#8220;Interop.WUApi.DLL&#8221; in the same directory as you executable. (I haven&#8217;t figured out a way past this yet.)</li>
<li>WUApi likes to die and quickly if there is the slightest error, and under C# these errors seem to be harder to pick up on.</li>
<li>Some updates don&#8217;t like to report back how far they are in their process. IE8 for example sits at 0% until its done, so you just have to wait and wait some more.</li>
</ol>
<p>The following code you can pretty much copy and paste into a cs file add the necessary hooks into the blank C# project, compile and it should work. It&#8217;s very Alpha and there is little error checking since I haven&#8217;t taken the time to throw test cases its way. It should also work on any OS from XP to 7.</p>
<pre>namespace winupdate_scheduler
{
    /// &lt;remarks&gt;Methods actual shutdown.&lt;/remarks&gt;
    public class grunt
    {
        public void shutdown()
        {
            throw new System.NotImplementedException();
        }

        public void restart()
        {
            throw new System.NotImplementedException();
        }

        /// &lt;summary&gt;
        /// Initiate the update for great justice!
        /// &lt;/summary&gt;
        public void update()
        {
            try
            {
                //Initate the session and begin the search!
                WUApiLib.UpdateSessionClass session = new WUApiLib.UpdateSessionClass();
                WUApiLib.IUpdateSearcher searcher = session.CreateUpdateSearcher();
                WUApiLib.ISearchResult result = searcher.Search("IsInstalled=0 and IsAssigned=1");

                //Initate the interfaces for progress and wholeness.
                InstallProgress progress = new InstallProgress();
                InstallComplete completion = new InstallComplete();

                //Dummy object for installer.BeginInstall
                object t3 = (new object());

                //Do we have anything to do?
                if (result.Updates.Count &gt; 0)
                {
                    //Begin the long wait.
                    //Probably should look into doing that async thing here too....later.
                    Console.WriteLine("Downloading...");
                    WUApiLib.IUpdateDownloader download = session.CreateUpdateDownloader();
                    download.Updates = result.Updates;
                    download.Download();

                    //Finally, get around to installing the suckers!
                    Console.WriteLine("Installing...");
                    WUApiLib.IUpdateInstaller installer = session.CreateUpdateInstaller();
                    installer.Updates = download.Updates;
                    installer.BeginInstall(progress, completion, t3);

                    //Hold your horses! We're not done yet!
                    while (!completion.jobdone)
                    {
                        System.Threading.Thread.Sleep(2000);
                    }
                }

                //Now you can let go of your horses!
                Console.WriteLine("Done");
            }
                //Until I can get a grasp of all the exceptions that can be raised, this will have to do.
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        /// &lt;summary&gt;
        /// Get list of updates
        /// &lt;/summary&gt;
        public void getupdates()
        {
            throw new System.NotImplementedException();
            WUApiLib.UpdateSessionClass session = new WUApiLib.UpdateSessionClass();
            WUApiLib.IUpdateSearcher searcher = session.CreateUpdateSearcher();
            WUApiLib.ISearchResult result = searcher.Search("IsInstalled=0 and IsAssigned=1");
        }
    }

    class InstallProgress : WUApiLib.IInstallationProgressChangedCallback
    {

        public void Invoke(WUApiLib.IInstallationJob job, WUApiLib.IInstallationProgressChangedCallbackArgs args)
        {
            this.job = job;
            this.OverallProgress = this.job.GetProgress().PercentComplete;
            this.UpdateProgress = this.job.GetProgress().CurrentUpdatePercentComplete;
            this.UpdateIndex = this.job.GetProgress().CurrentUpdateIndex;

            this.Update = this.job.Updates[this.UpdateIndex];

            string str = "Update: {0}, UpdateProgress: {1}%, Progress {2}%";
            Console.WriteLine(string.Format(str, (this.UpdateIndex + 1), this.UpdateProgress, this.OverallProgress));
        }

        public WUApiLib.IInstallationJob job;

        public int OverallProgress = 0;
        public int UpdateProgress = 0;
        public int UpdateIndex = 0;
        public WUApiLib.IUpdate Update;

    }

    class InstallComplete : WUApiLib.IInstallationCompletedCallback
    {
        public void Invoke(WUApiLib.IInstallationJob job, WUApiLib.IInstallationCompletedCallbackArgs args)
        {
            //string str = "job.IsCompleted: {0}, args.Progress: {1}% completed";
            //Console.WriteLine(string.Format(str, job.IsCompleted, job.GetProgress().PercentComplete));
            this.jobdone = job.IsCompleted;
        }
        public bool jobdone = false;
    }
}</pre>
<p>More reading:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/aa387292(VS.85).aspx" target="_blank">Windows Update Agent (WUA) API Reference</a>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/aa386065(VS.85).aspx" target="_blank">Interfaces</a></li>
</ul>
</li>
<li><a href="http://msdn.microsoft.com/en-us/library/87d83y5b(VS.80).aspx" target="_blank">C# Interfaces</a></li>
<li><a href="http://josherickson.org/2009/09/15/583/finding-applicable-windows-updates-via-cli">Finding applicable Windows Updates via cli</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2009/10/08/598/cracking-the-windows-update-api/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fixed: fastping, now with working get-help comments</title>
		<link>http://josherickson.org/2009/09/25/591/fixed-fastping-now-with-working-get-help-comments</link>
		<comments>http://josherickson.org/2009/09/25/591/fixed-fastping-now-with-working-get-help-comments#comments</comments>
		<pubDate>Fri, 25 Sep 2009 15:16:42 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=591</guid>
		<description><![CDATA[After getting frustrated with my fastping not displaying anything after using get-help, I asked the twitterverse for help, and they did! Super-duper thanks to @djryan (twitter/web) for the pointers.

&#60;#
.SYNOPSIS
Ping a node as fast as you can.
.DESCRIPTION
Whereas the ping.exe utility keeps steady at 1 ping per second,
this will ping with custom wait periods as low as [...]]]></description>
			<content:encoded><![CDATA[<p>After getting frustrated with my <a href="http://josherickson.org/2009/09/24/586/ping-faster-from-powershell-with-fastping">fastping</a> not displaying anything after using get-help, I asked the twitterverse for help, and they did! Super-duper thanks to @djryan (<a href="http://twitter.com/djryan">twitter</a>/<a href="http://www.djryan.co.uk/">web</a>) for the pointers.</p>
<pre>
&lt;#
.SYNOPSIS
Ping a node as fast as you can.
.DESCRIPTION
Whereas the ping.exe utility keeps steady at 1 ping per second,
this will ping with custom wait periods as low as 0 milliseconds.
.Parameter ip
IP or hostname of network node.
.Parameter count
Number of pings to execute (defaults to 4)
.Parameter wait
Time to wait for a reply.
.Parameter sleep
Time to wait between pings.
.Parameter size
Number of bytes to send (all Null or 0).
.Parameter ttl
Time to live.
.INPUTS
None. You cannot pipe objects to fastping.
.OUTPUTS
Reply from {host}: status={status bytes={bytes} time={tripTime}
(xxx% loss)
.Example
    PS&gt; fastping.ps1 -ip josherickson.org -size 1337 -wait 1
	Reply from josherickson.org: status=Success bytes=1337 time=81
	Reply from josherickson.org: status=Success bytes=1337 time=96
	Reply from josherickson.org: status=Success bytes=1337 time=81
	Reply from josherickson.org: status=TimedOut bytes=1337 time=0
	(25% loss)
.LINK
Original: http://josherickson.org/2009/09/24/586/ping-faster-from-powershell-with-fastping
.Notes
TODO: Add object based return instead of just text strings.
NAME:      verb
AUTHOR:    josherickson.org\josh
LASTEDIT:  09/25/2009
#&gt;
param (
	[string]$ip = "127.0.0.1",
	[int]$count = 4,
	[int]$wait = 5,
	[int]$sleep = 0,
	[int]$size = 32,
	[int]$ttl = 128
)

$ping = new-object System.Net.NetworkInformation.ping
$pingo = new-object System.Net.NetworkInformation.PingOptions $ttl, $false

if($size -gt 65500) {
	throw "`$size must be equal to or less than 65500";
}

$bsize = new-object byte[] $size;

$s = 0;
$f = 0;
for($i = 0; $i -lt $count; $i++) {
	$pr = $ping.Send($ip, $wait, $bsize, $pingo)
	$s += [int][bool]($pr.status -eq "Success");
	$f += [int][bool]($pr.status -ne "Success");

	"Reply from $($ip): status=$($pr.status) bytes=$size time=$($pr.RoundtripTime)" | write-host

	sleep -Milliseconds $sleep;
}

if($f -gt 0) {
	"(" + ((100/$count)*$f) + "% loss)";
} else {
	"(0% loss)";
}
return;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2009/09/25/591/fixed-fastping-now-with-working-get-help-comments/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ping faster from powershell with FastPing!</title>
		<link>http://josherickson.org/2009/09/24/586/ping-faster-from-powershell-with-fastping</link>
		<comments>http://josherickson.org/2009/09/24/586/ping-faster-from-powershell-with-fastping#comments</comments>
		<pubDate>Thu, 24 Sep 2009 21:55:58 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[faster]]></category>
		<category><![CDATA[fastping]]></category>
		<category><![CDATA[ping]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=586</guid>
		<description><![CDATA[I&#8217;ll let the code do most of the talking.
&#60;#
.Synopsis
    Ping a node as fast as you can.
.Description
    Whereas the ping.exe utility keeps steady at 1 ping per second,
	this will ping with custom wait periods as low as 0 milliseconds.
.Parameter ip
	IP or hostname of network node.
.Parameter count
	Number of pings to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll let the code do most of the talking.</p>
<pre>&lt;#
.Synopsis
    Ping a node as fast as you can.
.Description
    Whereas the ping.exe utility keeps steady at 1 ping per second,
	this will ping with custom wait periods as low as 0 milliseconds.
.Parameter ip
	IP or hostname of network node.
.Parameter count
	Number of pings to execute (defaults to 4)
.Parameter wait
	Time to wait for a reply.
.Parameter sleep
	Time to wait between pings.
.Parameter size
	Number of bytes to send (all Null or 0).
.Parameter ttl
	Time to live.
.Example
    PS&gt; fastping.ps1 -ip josherickson.org -size 1337 -wait 1
	Reply from josherickson.org: status=Success bytes=1337 time=81
	Reply from josherickson.org: status=Success bytes=1337 time=96
	Reply from josherickson.org: status=Success bytes=1337 time=81
	Reply from josherickson.org: status=TimedOut bytes=1337 time=0
	(25% loss)

.ReturnValue
    [string]

.Link
.Notes
	TODO: Add object based return instead of just text strings.
NAME:      verb
AUTHOR:    josherickson.org\josh
LASTEDIT:  09/24/2009
#Requires -Version 2.0
#&gt;
param (
	[string]$ip = "127.0.0.1",
	[int]$count = 4,
	[int]$wait = 5,
	[int]$sleep = 0,
	[int]$size = 32,
	[int]$ttl = 128
)

$ping = new-object System.Net.NetworkInformation.ping
$pingo = new-object System.Net.NetworkInformation.PingOptions $ttl, $false

if($size -gt 65500) {
	throw "`$size must be equal to or less than 65500";
}

$bsize = new-object byte[] $size;

$s = 0;
$f = 0;
for($i = 0; $i -lt $count; $i++) {
	$pr = $ping.Send($ip, $wait, $bsize, $pingo)
	$s += [int][bool]($pr.status -eq "Success");
	$f += [int][bool]($pr.status -ne "Success");

	"Reply from $($ip): status=$($pr.status) bytes=$size time=$($pr.RoundtripTime)"

	sleep -Milliseconds $sleep;
}

if($f -gt 0) {
	"(" + ((100/$count)*$f) + "% loss)";
} else {
	"(0% loss)";
}</pre>
<p>Note that the time it takes to ping a place reflects the round trip time, which is how long it takes to get the entire reply, that is why you can see times greater than the specified wait time.</p>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2009/09/24/586/ping-faster-from-powershell-with-fastping/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Finding applicable Windows Updates via cli</title>
		<link>http://josherickson.org/2009/09/15/583/finding-applicable-windows-updates-via-cli</link>
		<comments>http://josherickson.org/2009/09/15/583/finding-applicable-windows-updates-via-cli#comments</comments>
		<pubDate>Tue, 15 Sep 2009 13:37:52 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[command prompt]]></category>
		<category><![CDATA[Microsoft.Update.Session]]></category>
		<category><![CDATA[Updating computers]]></category>
		<category><![CDATA[Windows Update]]></category>
		<category><![CDATA[WSUS]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=583</guid>
		<description><![CDATA[An ongoing project here at work is server maintenance and applying patches. One of the issue we&#8217;ve been facing is how to do windows updates for clusters. While we could do an AD structure and schedule different install and restart times for the different sides, we can&#8217;t include checks to see if the other side [...]]]></description>
			<content:encoded><![CDATA[<p>An ongoing project here at work is server maintenance and applying patches. One of the issue we&#8217;ve been facing is how to do windows updates for clusters. While we could do an AD structure and schedule different install and restart times for the different sides, we can&#8217;t include checks to see if the other side of the cluster is up. </p>
<p>So now, we&#8217;re working on a set of tools that can initiate Windows Updates, check if other servers are up or down, and then restart accordingly. Thus far, I&#8217;ve just finished this script, the rest of the tool will likely be done with C# and set as a service on each machine. With this script, you can check the updates for other machines from the comfort of your desktop/laptop and send it off to a text file for later viewing. You can even initiate the update process! Albeit, only on the machine you&#8217;re running on due to constraints of the Microsoft.Update.Session COM.</p>
<pre>
param (
	$computer = $env:computername,
	[switch]$searchOnly
)
[Reflection.Assembly]::LoadFrom("C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\Microsoft.VisualBasic.dll") | out-null;

#Create an update session
#Using the vb createObject method, we are able to connect to remote machines to view
#it's update list
$updateSession = [microsoft.visualbasic.interaction]::CreateObject("Microsoft.Update.Session", $computer);

"Finding updates on $($computer)"
$updateSearch = $updateSession.CreateUpdateSearcher()
#Here we're only wanting to know what it needs and what it has been assigned.
#IsAssigned should really only apply to networks that utilize WSUS.

$results = $updateSearch.Search('IsInstalled=0 and IsAssigned=1')

if($searchOnly.IsPresent -or $computer -ne $env:computername) {
	$results.Updates
} else {
	"Downloading updates"
	$updateDownload = $updateSession.CreateUpdateDownloader()
	$updateDownload.Updates =$results.Updates
	$updateDownload.Download()

	"Installing updates"
	$installer = $updateSession.CreateUpdateInstaller()
	$installer.Updates = $updateDownload.Updates
	$installer.install()
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2009/09/15/583/finding-applicable-windows-updates-via-cli/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MS-SQL Powershell database backup</title>
		<link>http://josherickson.org/2009/09/09/580/ms-sql-powershell-database-backup</link>
		<comments>http://josherickson.org/2009/09/09/580/ms-sql-powershell-database-backup#comments</comments>
		<pubDate>Wed, 09 Sep 2009 20:25:18 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[dump]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=580</guid>
		<description><![CDATA[Recently one of our SQL clusters decided it was a good idea to not backup databases anymore. So today my boss told me to get something to bandaid the situation until we can fix the situation (which will likely be an upgrade/reinstall).
To learn more check out the MSDN pages on the Microsoft.SqlServer.Management.Smo namespace.

#
#	Temp database backup
#
$d [...]]]></description>
			<content:encoded><![CDATA[<p>Recently one of our SQL clusters decided it was a good idea to not backup databases anymore. So today my boss told me to get something to bandaid the situation until we can fix the situation (which will likely be an upgrade/reinstall).</p>
<p>To learn more check out the MSDN pages on the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.aspx">Microsoft.SqlServer.Management.Smo</a> namespace.</p>
<pre>
#
#	Temp database backup
#
$d = date;

#filename: db_full_MM-DD-YYYY-HH.bak
$backupfile = "db_full_" + ($d.ToShortDateString().replace("/","-")) + "-" + ($d.hour) + "h.bak";

#should you use drive paths (ie c:\) it will save to the SQL server's drive.
$backuppath = "\\path\to\save\location\doesnt\need\to\be\unc\";

[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo");
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended");
$ser = New-Object "Microsoft.SqlServer.Management.Smo.Server" "server\instance";
$backup = New-Object Microsoft.SqlServer.Management.Smo.Backup
$bdevice = New-Object microsoft.sqlserver.management.smo.backupdeviceitem -ArgumentList ($backuppath + $backupfile), "File"

$backup.Action = [Microsoft.SqlServer.Management.Smo.BackupActionType]::Database
$backup.BackupSetName = "Daily Full Database";
$backup.Database = "DatabaseName"

$backup.Initialize = $True
$backup.Checksum = $True
$backup.ContinueAfterError = $true
$backup.Devices.Add($bdevice)
$backup.Incremental = $false
$backup.CopyOnly = $true
$backup.LogTruncation ="NoTruncate" #meant for bandaid approach and for less "impact" on database.
$backup.FormatMedia = $false
$backup.SqlBackup($ser); #save it.
</pre>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2009/09/09/580/ms-sql-powershell-database-backup/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
