<?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; concepts</title>
	<atom:link href="http://josherickson.org/category/code/concepts/feed" rel="self" type="application/rss+xml" />
	<link>http://josherickson.org</link>
	<description>And as you tread the halls of sanity...</description>
	<lastBuildDate>Wed, 01 Sep 2010 15:58:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Wake-on-Lan (WOL) via Powershell</title>
		<link>http://josherickson.org/2010/05/07/785/wake-on-lan-wol-via-powershell</link>
		<comments>http://josherickson.org/2010/05/07/785/wake-on-lan-wol-via-powershell#comments</comments>
		<pubDate>Fri, 07 May 2010 18:36:23 +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>
		<category><![CDATA[wake-on-lan]]></category>
		<category><![CDATA[wol]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=785</guid>
		<description><![CDATA[Despite what others may say, Wake-on-LAN isn&#8217;t magic and isn&#8217;t that complicated a feat to do anymore. With Powershell and .NET you can have the power of WOL without having to resort to third-party applications! Code/Script: param ( $targetMac, $network = [net.ipaddress]::Broadcast, $subnet = [net.ipaddress]::Broadcast ) try { if($network.gettype().equals([string])) { $network = [net.ipaddress]::Parse($network); } if($subnet.gettype().equals([string])) [...]]]></description>
			<content:encoded><![CDATA[<p>Despite what others may say, Wake-on-LAN isn&#8217;t magic and isn&#8217;t that complicated a feat to do anymore. With Powershell and .NET you can have the power of WOL without having to resort to third-party applications!</p>
<h2>Code/Script:</h2>
<pre>param (
    $targetMac,
    $network = [net.ipaddress]::Broadcast,
    $subnet = [net.ipaddress]::Broadcast
)
try {
    if($network.gettype().equals([string])) {
        $network = [net.ipaddress]::Parse($network);
    }
    if($subnet.gettype().equals([string])) {
        $subnet = [net.ipaddress]::Parse($subnet);
    }
    $broadcast = new-object net.ipaddress (([system.net.ipaddress]::parse("255.255.255.255").address -bxor $subnet.address -bor $network.address))

    $mac = [Net.NetworkInformation.PhysicalAddress]::Parse($targetMac.toupper().replace(".",""))

    $u = New-Object net.sockets.udpclient
    $ep = New-Object net.ipendpoint $broadcast, 0
    $ep2 = New-Object net.ipendpoint $broadcast, 7
    $ep3 = New-Object net.ipendpoint $broadcast, 9

    $payload = [byte[]]@(255,255,255, 255,255,255);
    $payload += ($mac.GetAddressBytes()*16)

    for($i = 0; $i -lt 10; $i++) {
        $u.Send($payload, $payload.Length, $ep) | Out-Null
        $u.Send($payload, $payload.Length, $ep2) | Out-Null
        $u.Send($payload, $payload.Length, $ep3) | Out-Null
        sleep 1;
    }
} catch {
    $Error | Write-Error;
}</pre>
<h2>Usage:</h2>
<pre>
wol.ps1 "target-MAC"
wol.ps1 "target-MAC" 192.168.1.255
wol.ps1 "target-MAC" 192.168.1.123 255.255.255.0
</pre>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2010/05/07/785/wake-on-lan-wol-via-powershell/feed</wfw:commentRss>
		<slash:comments>1</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 [...]]]></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>1</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 [...]]]></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>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. # [...]]]></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>
		<item>
		<title>Windows 7 Powershell LogonUI Changer</title>
		<link>http://josherickson.org/2009/08/19/556/windows-7-powrrshell-logonui-changer</link>
		<comments>http://josherickson.org/2009/08/19/556/windows-7-powrrshell-logonui-changer#comments</comments>
		<pubDate>Wed, 19 Aug 2009 16:51:14 +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[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=556</guid>
		<description><![CDATA[Based off of the W7C LogonUI Changer, this Powershell script should make changing the LogonUI background easier for the IT admins out there. Download win7logonui.zip (Includes the ImageProcessor source and DLL) Usage: After copying or building imageprocessor.dll move it to the same folder as win7logonui.ps1 (or edit the script). Example: win7logonui.ps1 \path\to\image.jpg Set $DebugPreference to [...]]]></description>
			<content:encoded><![CDATA[<p>Based off of the <a href="http://windows7center.com/news/download-our-windows-7-logonui-background-changer/">W7C LogonUI Changer</a>, this Powershell script should make changing the LogonUI background easier for the IT admins out there.</p>
<p><a href="http://josherickson.org/wp-content/uploads/win7logonui.zip">Download win7logonui.zip</a> (Includes the ImageProcessor source and DLL)</p>
<p>Usage:</p>
<ul>
<li>After copying or building imageprocessor.dll move it to the same folder as win7logonui.ps1 (or edit the script).</li>
<li>Example: win7logonui.ps1 \path\to\image.jpg</li>
<li>Set $DebugPreference to &#8220;Continue&#8221; to watch the script as it runs.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2009/08/19/556/windows-7-powrrshell-logonui-changer/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ad-hoc fileshares</title>
		<link>http://josherickson.org/2009/08/14/546/ad-hoc-fileshares</link>
		<comments>http://josherickson.org/2009/08/14/546/ad-hoc-fileshares#comments</comments>
		<pubDate>Fri, 14 Aug 2009 21:48:10 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[file sharing]]></category>
		<category><![CDATA[user control]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=546</guid>
		<description><![CDATA[A little concept I&#8217;ve been working on every now and again is ad-hoc shares. The reasoning behind it is that committees and other short lived inter-department groups need something to share documents with that can be backed up. Email can be a hassle and quickly fills quotas, IT staff probably hates the idea of users [...]]]></description>
			<content:encoded><![CDATA[<p>A little concept I&#8217;ve been working on every now and again is ad-hoc shares. The reasoning behind it is that committees and other short lived inter-department groups need something to share documents with that can be backed up. Email can be a hassle and quickly fills quotas, IT staff probably hates the idea of users starting shares on their machines (not to mention the backup issue), and a &#8220;public&#8221; share is way to&#8230;public.</p>
<p>A huge part of this idea came from drop.io, which allows anyone to create a place to share files as easily as letting the third parties know the location and password. By utilizing ActiveDirectory and Share and NTFS permissions, you can quickly create a place that people can access files and folders that only they have rights to.</p>
<p>With this script, users can create shares when they need them and limit who has access without having to know anything about share or NTFS permissions. Though at the moment, it would require them to know something about the command line and powershell. However a GUI could be created fairly easily that&#8217;s based off of the code below.</p>
<p>One thing that I haven&#8217;t finished yet is a culling script which would run on the server the main share is on, which is the reasoning behind the hidden xml file. It holds the info on when to delete the share.</p>
<p>adhocshares.ps1</p>
<pre>
param (
	$xml = $(throw "You must supply an XML (text not file) configuration!")
)

#
#	settings
#

$version = .2;
$rootdir = "c:\pbin\adhocshares\shares\";

$xmld = new-object system.xml.xmldocument;
$xmld.LoadXml($xml);

#some xml validation here?
$spec_check = $False;

$spec_check = $spec_check -and [bool]$xmld.root.share.dir
$spec_check = $spec_check -and [bool]$xmld.root.share.dir.name
$spec_check = $spec_check -and [bool]$xmld.root.share.dir.expires

$spec_check = $spec_check -and [bool]$xmld.root.share.acl
$spec_check = $spec_check -and [bool]$xmld.root.share.acl.user

if($xmld.root.version.number -ne $version -or $spec_check) {
	throw "XML should conform to the 0.2 version specs.";
}

#
#	Create share
#
$name = $xmld.root.share.dir.name
$newdir = "$($rootdir)$($name)";

##insert code for random name generation.

if(test-path $newdir) {
	throw "Error: Sorry, but that folder already exists. Please try another name.";
}

New-Item $newdir -type directory | out-null

$dacl = get-acl $newdir;
foreach($u in $xmld.root.share.acl.user) {
	"Adding: $($u.name) with $($u.rights) permissions.";
	$inher = ([System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit) #[System.Security.AccessControl.InheritanceFlags]::none
	$prop = [System.Security.AccessControl.PropagationFlags]::none

	if($u.rights -eq "rw") {
		$new_rights = New-Object System.Security.AccessControl.FileSystemAccessRule(@("contoso\$($u.name)", "FullControl", $inher, $prop, "allow"));
		$dacl.AddAccessRule($new_rights);
	}
	if($u.rights -eq "ro") {
		$new_rights = New-Object System.Security.AccessControl.FileSystemAccessRule(@("contoso\$($u.name)", "ReadAndExecute", $inher, $prop, "allow"));
		$dacl.AddAccessRule($new_rights);
	}
}
set-acl -path $dacl.path -AclObject $dacl;

#Create the "settings" of the folder.
#Management script will delete folder if .ahs.settings.xml is not present.

$xml_text | out-file "$($newdir)\.ahs.settings.xml";
$t = gi "$($newdir)\.ahs.settings.xml";
$t.set_attributes("Hidden")
$t.set_IsReadOnly($True);
</pre>
<p>XML permissions</p>
<pre>
 &lt;?xml version="1.0" encoding='ISO-8859-1'?&gt;
 &lt;!--
	VERSION:0.2
		version:	&lt;version number="adhoc version" /&gt;
			Nothing special here other than to specify the parser version.

		share:	&lt;share&gt;
			Similar to "items" for RSS feeds. Meant to one day allow for multiple shares to be created from one xml file.

		dir:	&lt;dir name="share name" expires="date the share will expire and can be deleted" /&gt;

		acl:	&lt;acl&gt;
			List of users that will have access to the folder.

		user: &lt;user name="ActiveDirectory SAM account name" rights="(rw|ro)" /&gt;
 --&gt;
 &lt;root&gt;
	&lt;version number="0.2" /&gt;
	&lt;share&gt;
		&lt;dir name="tmp1" expires="Friday, July 31, 2009 9:32:33 AM" /&gt;
		&lt;acl&gt;
			&lt;user name="josherickson" rights="rw" /&gt;
			&lt;user name="theboss" rights="ro" /&gt;
			&lt;user name="coworker" rights="ro" /&gt;
		&lt;/acl&gt;
	&lt;/share&gt;
&lt;/root&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2009/08/14/546/ad-hoc-fileshares/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Powershell Site Crawler</title>
		<link>http://josherickson.org/2009/07/16/520/simple-powershell-site-crawler</link>
		<comments>http://josherickson.org/2009/07/16/520/simple-powershell-site-crawler#comments</comments>
		<pubDate>Thu, 16 Jul 2009 19:43:44 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[blah]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=520</guid>
		<description><![CDATA[The following code is a mental recreation with improvements (and thus untested) of a quickly written powershell script from last night. This is simply an example of how to get started, and so it&#8217;s up to you to write your own code for finding what you want. #Set the page you want to start at [...]]]></description>
			<content:encoded><![CDATA[<p>The following code is a mental recreation with improvements (and thus untested) of a quickly written powershell script from last night. This is simply an example of how to get started, and so it&#8217;s up to you to write your own code for finding what you want.</p>
<pre>
#Set the page you want to start at
$tree = @("http://example.com/");
$client = new-object system.net.webclient;

for($i = 0; $i -lt $tree.length + 1; $i++) {
	$page = $client.downloadString($tree[$i]);

	#Assumes that the site is valid html/xhtml
	$xmldocument = new-object system.xml.xmldocument
	$xmldocument.loadxml($page);

	#This filters the links to only anchors with href set and hasn't been captured already.
	#You could include additional filtering conditions in where{}
	#possiblities include only links that contains "/profile" or "/topics".
	$tree += ($xmldocument.getElementsByTagName("a") | where { $_.href -ne $null -and !($tree -contains $_.href.tolower()) } | foreach { $_.href.tolower() })
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2009/07/16/520/simple-powershell-site-crawler/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More chess</title>
		<link>http://josherickson.org/2009/07/13/495/more-chess</link>
		<comments>http://josherickson.org/2009/07/13/495/more-chess#comments</comments>
		<pubDate>Mon, 13 Jul 2009 13:00:15 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://josherickson.org/?p=495</guid>
		<description><![CDATA[I&#8217;ve been finding myself thinking about my chess project from&#8230;a couple a years ago. Most of it&#8217;s been in how to better use OOP principles as well as make it more secure (like take out the eval call for starters). I&#8217;ve yet to make it more secure, but I have added a method (movedSpaces()) that [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been finding myself thinking about my <a href="http://josherickson.org/2007/05/13/6/chess-math">chess project</a> from&#8230;a couple a years ago. Most of it&#8217;s been in how to better use OOP principles as well as make it more secure (like take out the eval call for starters).</p>
<p>I&#8217;ve yet to make it more secure, but I have added a method (movedSpaces()) that lists the board squares that were covered in the move, with the first and last array entries being the starting and end positions.</p>
<p>Probably the next biggest hurdle will be how keep track of the black pieces since the current code that is written for whites. While it would be easier to create two different class sets for black and white, it would mean more equations or methods that are way to specialized for very similar ideas. One idea I&#8217;ve had would be to treat white and black as the same in code, but than reverse the when checking for opposing pieces or for display.</p>
<p>Code:</p>
<ul>
<li><a href="http://josherickson.org/chess/pieces.php">pieces.php</a> (<a href="http://josherickson.org/chess/pieces.php?source">Source</a>)</li>
<li><a href="http://josherickson.org/chess/class.piece.php?source">class.piece.php</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://josherickson.org/2009/07/13/495/more-chess/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
