<?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>theboywonder.co.uk</title>
	<atom:link href="http://theboywonder.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://theboywonder.co.uk</link>
	<description>... ok, well at least I&#039;m trying.</description>
	<lastBuildDate>Sat, 09 Mar 2013 16:30:54 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Yet Another Invoke-SSH PowerShell Function (thanks PS Fab)</title>
		<link>http://theboywonder.co.uk/2013/03/07/yet-another-invoke-ssh-powershell-function/</link>
		<comments>http://theboywonder.co.uk/2013/03/07/yet-another-invoke-ssh-powershell-function/#comments</comments>
		<pubDate>Thu, 07 Mar 2013 12:54:17 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[Geek Stuff]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://theboywonder.co.uk/?p=786</guid>
		<description><![CDATA[As part of a writing a decommission server PowerShell script at work, I had a requirement for a quick and easy SSH function to connect to our NetBackup server at work and remove the server from the backup system (Symantec if you&#8217;re reading this, please can we have a PowerShell module? *wishful thinking*&#8230;). Not quite [...]]]></description>
				<content:encoded><![CDATA[<p>As part of a writing a decommission server PowerShell script at work, I had a requirement for a quick and easy SSH function to connect to our NetBackup server at work and remove the server from the backup system (Symantec if you&#8217;re reading this, please can we have a PowerShell module? *wishful thinking*&#8230;). Not quite needing the entire functionality provided by <a href="http://www.powershelladmin.com/wiki/SSH_from_PowerShell_using_the_SSH.NET_library" title="PowerShell SSH module" target="_blank">this module</a> (based on the SSH.NET Library), I came across a function on <a href="http://www.zerrouki.com/invoke-ssh/" title="PS Fab: Invoke-SSH" target="_blank">PS Fab</a>. One fantastic thing about this function is that supports the automatic acceptance of an SSH key when you connect to a host for the first time.</p>
<p>I made a few changes to the code, amended comments that referenced plist rather than plink and put it into a more standard function form with examples (that you might be able to add to an existing library). This is the result:</p>
<pre class="brush: powershell; title: ; notranslate">
Function Invoke-SSH 
{
	&lt;#
	.SYNOPSIS 
	Uses Plink.exe to SSH to a host and execute a list of commands.
	.DESCRIPTION
	Uses Plink.exe to SSH to a host and execute a list of commands.
	.PARAMETER hostname
	The host you wish to connect to.
	.PARAMETER username
	Username to connect with.
	.PARAMETER password
	Password for the specified user account.
	.PARAMETER commandArray
	A single, or list of commands stored in an array object.
	.PARAMETER plinkAndPath
	The location of the plink.exe including the executable (e.g. F:\tools\plink.exe)
	.PARAMETER connectOnceToAcceptHostKey
	If set to true, it will accept the remote host key (use when connecting for the first time)
	.EXAMPLE
	Invoke-SSH -username root -hostname centos-server -password Abzy4321! -plinkAndPath &quot;F:\tools\plink.exe&quot; -commandArray $commands -connectOnceToAcceptHostKey $true
	.EXAMPLE
	Invoke-SSH -username root -hostname centos-server -password Abzy4321! -plinkAndPath &quot;F:\tools\plink.exe&quot; -commandArray ifconfig -connectOnceToAcceptHostKey $true
	.NOTES
	Author: Robin Malik
	Source: Modified from: http://www.zerrouki.com/invoke-ssh/
	#&gt;
	
	Param(
		[Parameter(Mandatory=$true,HelpMessage=&quot;Enter a host to connect to.&quot;)]
		[string]
		$hostname,
		
		[Parameter(Mandatory=$true,HelpMessage=&quot;Enter a username.&quot;)]
		[string]
		$username,
		
		[Parameter(Mandatory=$true,HelpMessage=&quot;Enter the password.&quot;)]
		[string]
		$password,
		
		[Parameter(Mandatory=$true,HelpMessage=&quot;Provide a command or comma separated list of commands&quot;)]
		[array]
		$commandArray,
		
		[Parameter(Mandatory=$true,HelpMessage=&quot;Path to plink (e.g. F:\tools\plink.exe).&quot;)]
		[string]
		$plinkAndPath,
		
		[Parameter(HelpMessage=&quot;Accept host key if connecting for the first time (the default is `$false)&quot;)]
		[string]
		$connectOnceToAcceptHostKey = $false
	)
	
	$target = $username + '@' + $hostname
	$plinkoptions = &quot;-ssh $target -pw $password&quot;
	 
	# On first connect to a host, plink will prompt you to accept the remote host key. 
	# This section will login and accept the host key then logout:
	if($ConnectOnceToAcceptHostKey)
	{
		$plinkCommand  = [string]::Format('echo y | &amp; &quot;{0}&quot; {1} exit', $plinkAndPath, $plinkoptions )
		$msg = Invoke-Expression $plinkCommand
	}
	
	# Build the SSH Command by looping through the passed value(s). Append exit in order to logout:
	$commandArray += &quot;exit&quot;
	$commandArray | % { $remoteCommand += [string]::Format('{0}; ', $_) }
	
	# Format the command to pass to plink:
	$plinkCommand = [string]::Format('&amp; &quot;{0}&quot; {1} &quot;{2}&quot;', $plinkAndPath, $plinkoptions , $remoteCommand)
	 
	# Execute the command and display the output:
	$msg = Invoke-Expression $plinkCommand
	Write-Output $msg
}
</pre>
<p>Copy and paste this function into a PowerShell window, and then test it with the below code (changing where appropriate of course):</p>
<pre class="brush: powershell; title: ; notranslate">
$plinkAndPath = &quot;F:\tools\plink\plink.exe&quot;
$username = &quot;root&quot;
$password = &quot;Adk3453#5341!&quot;
$hostname = &quot;centos-server&quot;
# Commands to execute:
$Commands = @()
$Commands += &quot;ifconfig&quot;
$Commands += &quot;ls&quot;
Invoke-SSH -username $username -hostname $hostname -password $password -plinkAndPath $plinkAndPath -commandArray $Commands -connectOnceToAcceptHostKey $true
</pre>
]]></content:encoded>
			<wfw:commentRss>http://theboywonder.co.uk/2013/03/07/yet-another-invoke-ssh-powershell-function/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Derby 10K 2013 Start List</title>
		<link>http://theboywonder.co.uk/2013/02/23/derby-10k-2013-start-list/</link>
		<comments>http://theboywonder.co.uk/2013/02/23/derby-10k-2013-start-list/#comments</comments>
		<pubDate>Sat, 23 Feb 2013 17:36:08 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[Daily life]]></category>

		<guid isPermaLink="false">http://theboywonder.co.uk/?p=781</guid>
		<description><![CDATA[Though the Sporting-Futures website has improved greatly over the past few years I still had a bit of trouble finding the start list. Here is it (a link that is present on the actual entry form page but nowhere else): https://secure.onreg.com/onreg2/startlist/index.php?id=1566 Good luck everyone :)]]></description>
				<content:encoded><![CDATA[<p>Though the Sporting-Futures website has improved greatly over the past few years I still had a bit of trouble finding the start list. Here is it (a link that is present on the actual entry form page but nowhere else):</p>
<p><a href="https://secure.onreg.com/onreg2/startlist/index.php?id=1566" title="Derby 10K 2013 Start List" target="_blank">https://secure.onreg.com/onreg2/startlist/index.php?id=1566</a></p>
<p>Good luck everyone :)</p>
]]></content:encoded>
			<wfw:commentRss>http://theboywonder.co.uk/2013/02/23/derby-10k-2013-start-list/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Barack and Michelle Obama</title>
		<link>http://theboywonder.co.uk/2012/12/29/barack-and-michelle-obama/</link>
		<comments>http://theboywonder.co.uk/2012/12/29/barack-and-michelle-obama/#comments</comments>
		<pubDate>Sat, 29 Dec 2012 14:49:03 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[love]]></category>
		<category><![CDATA[obama]]></category>
		<category><![CDATA[relationships]]></category>

		<guid isPermaLink="false">http://theboywonder.co.uk/?p=767</guid>
		<description><![CDATA[How perfect is this set?]]></description>
				<content:encoded><![CDATA[<p>How perfect is this set?<br />
<img src="http://24.media.tumblr.com/tumblr_md4iv8mu5V1qlpkoio11_r1_250.gif" width="245" height="150" class="alignleft" /><img src="http://24.media.tumblr.com/tumblr_md4iv8mu5V1qlpkoio2_250.jpg" width="245" height="150" class="alignright" /><img src="http://25.media.tumblr.com/tumblr_md4iv8mu5V1qlpkoio3_250.jpg" width="245" height="150" class="alignleft" /><img src="http://24.media.tumblr.com/tumblr_md4iv8mu5V1qlpkoio5_250.gif" width="245" height="150" class="alignright" /><img src="http://24.media.tumblr.com/tumblr_md4iv8mu5V1qlpkoio1_250.gif" width="245" height="150" class="alignleft" /><img src="http://24.media.tumblr.com/tumblr_md4iv8mu5V1qlpkoio7_250.jpg" width="245" height="150" class="alignright" /><img src="http://24.media.tumblr.com/tumblr_md4iv8mu5V1qlpkoio6_250.jpg" width="245" height="150" class="alignleft" /><img src="http://24.media.tumblr.com/tumblr_md4iv8mu5V1qlpkoio12_r1_250.gif" width="245" height="150" class="alignright" /></p>
]]></content:encoded>
			<wfw:commentRss>http://theboywonder.co.uk/2012/12/29/barack-and-michelle-obama/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Catching Virtual Machine questions with PowerCLI</title>
		<link>http://theboywonder.co.uk/2012/10/19/catching-virtual-machine-questions-with-powercli/</link>
		<comments>http://theboywonder.co.uk/2012/10/19/catching-virtual-machine-questions-with-powercli/#comments</comments>
		<pubDate>Fri, 19 Oct 2012 10:34:23 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[Geek Stuff]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[powercli]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[vmware]]></category>

		<guid isPermaLink="false">http://theboywonder.co.uk/?p=756</guid>
		<description><![CDATA[As part of our VM-template, template-VM conversion process at work (which I&#8217;ve automated via a webpage as discussed in my previous post &#8220;Executing Powershell using PHP and IIS&#8220;), I had to find a way to handle the VM question &#8220;This VM has questions that must be answered before the operation can continue&#8221; when attempting to [...]]]></description>
				<content:encoded><![CDATA[<p>As part of our VM-template, template-VM conversion process at work (which I&#8217;ve automated via a webpage as discussed in my previous post &#8220;<a href="http://theboywonder.co.uk/2012/07/29/executing-powershell-using-php-and-iis/" target="_blank">Executing Powershell using PHP and IIS</a>&#8220;), I had to find a way to handle the VM question &#8220;This VM has questions that must be answered before the operation can continue&#8221; when attempting to power the VM on via Start-VM. </p>
<p>I found that handling the question was not possible using a simple try/catch block (the explanation can be found in this <a href="http://outputredirection.blogspot.co.uk/2010/04/powershells-trycatchfinally-and.html" target="_blank">excellent post</a> by Clint Bergman). I was however able to catch it using the following block:</p>
<pre class="brush: powercli; title: ; notranslate">
try
{
	try
	{
		Start-VM -VM $serverName -ErrorAction Stop -ErrorVariable custErr
	}
	catch [System.Management.Automation.ActionPreferenceStopException]
	{
		throw $_.Exception
	}
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.VMBlockedByQuestionException]
{
	Write-Output &quot;Power on operation triggered a VMBlockedByQuestionException. Answering question with `&quot;I moved it`&quot;. &lt;br /&gt;&quot;
	Get-VMQuestion -VM $serverName | Set-VMQuestion –Option &quot;I moved it&quot; -Confirm:$false	
}
</pre>
<p>It may seem like a lot of work to convert between a VM and template (and vice versa) but in our environment there are a couple of critical steps to the conversation process that must be followed to ensure deploys from these templates don&#8217;t break. As there are users outside of the team who update various templates I wanted to provide an easy way for everyone to ensure consistency when doing this, and the best way to do this is of course, automation :)</p>
]]></content:encoded>
			<wfw:commentRss>http://theboywonder.co.uk/2012/10/19/catching-virtual-machine-questions-with-powercli/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Executing Powershell using PHP and IIS</title>
		<link>http://theboywonder.co.uk/2012/07/29/executing-powershell-using-php-and-iis/</link>
		<comments>http://theboywonder.co.uk/2012/07/29/executing-powershell-using-php-and-iis/#comments</comments>
		<pubDate>Sun, 29 Jul 2012 12:48:47 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[Daily life]]></category>
		<category><![CDATA[iis]]></category>
		<category><![CDATA[iis 7]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[shell_exec]]></category>

		<guid isPermaLink="false">http://theboywonder.co.uk/?p=603</guid>
		<description><![CDATA[This is an article on how to develop a PHP page to execute a Powershell script on IIS 7.5 (7.0 is fine) as logged on user. In short, it makes use of shell_exec in PHP to launch Powershell, grab the output and display it to the browser. It details the server setup as I have [...]]]></description>
				<content:encoded><![CDATA[<p>This is an article on how to develop a PHP page to execute a Powershell script on IIS 7.5 (7.0 is fine) as logged on user. In short, it makes use of shell_exec in PHP to launch Powershell, grab the output and display it to the browser. It details the server setup as I have not tested this on other configurations, and provides the most basic possible PHP and Powershell script for you to test it out. Hopefully some find this useful!</p>
<ul>
<li><a href="#part1">Part 1: Introduction</a></li>
<li><a href="#part2">Part 2: Server Configuration</a></li>
<li><a href="#part3">Part 3: Writing the PHP Page</a></li>
<li><a href="#part4">Part 4: Writing the Powershell Script</a></li>
<li><a href="#part5">Part 5: Use Cases</a></li>
<li><a href="#part6">Part 6: Caveats</a></li>
</ul>
<p>&nbsp;</p>
<p><a name="part1"><strong><u>Introduction:</u></strong></a></p>
<p>I&#8217;ve been using Powershell fairly regularly at work for about a year now and it&#8217;s <strong>fantastic</strong>. Many tasks that our team have to perform are now scripted using Powershell, and we&#8217;re actively trying to turn away from VBS. Given the comparative ease of this language and it&#8217;s integration with the .NET framework, we started toying with the idea of being able to provide an IIS website front end to our service desk to execute Powershell scripts behind the scenes.</p>
<p>Essentially we wanted a website that would allow for an Active Directory user to login over HTTPS, enter some data into a web page, submit the data to a digitally signed Powershell script as parameters and have it execute on the very same server <strong>as the logged on user</strong>, finally returning the result back to the web page. Initially the solution needed to execute Powershell scripts that would make at least make use of the Microsoft Active Directory Module and VMware&#8217;s PowerCLI Snap-in, later expanding to utilise the Exchange 2010 and Netapp DataONTAP snap-ins.</p>
<p>After initially looking at a Perl wrapper for executing Powershell with a colleague and making little progress, I decided to have a shot at doing it with PHP. I have a little experience with PHP and within 30 minutes or so I had it working using shell_exec. Game on!</p>
<p>&nbsp;</p>
<p><a name="part2"><strong><u>Server Configuration:</u></strong></a></p>
<p>The working solution is based on the following platform:</p>
<ul>
<li>Windows Server 2008 R2 with IIS 7.5.</li>
<li>Powershell v2 (the default on the above OS).</li>
<li>.NET 4 (not necessary but this is our setup).</li>
<li>PHP (x64 preferred, though x86 will work &#8211; <a href="#phpnote" title="x64php">discussed below</a>).</li>
<li>Visual C++ 2008 SP1 Redistributable Package &#8211; choose the package to match the version of PHP (<a href="http://www.microsoft.com/en-us/download/details.aspx?id=2092" title="x64" target="_blank">x64</a>) (<a href="http://www.microsoft.com/en-us/download/details.aspx?id=5582" title="x86" target="_blank">x86</a>).</li>
<li><a href="http://technet.microsoft.com/en-us/library/dd391908%28WS.10%29.aspx" title="ADWS" target="_blank">Active Directory Web Services</a> installed on one of our 2008 DCs. This allows for the use of the Active Directory module (cmdlets) on a 2008 R2 or Windows 7 machine in a non 2008 R2 domain controller environment.</li>
</ul>
<p>I won&#8217;t cover securely signing Powershell scripts here as it&#8217;s widely documented. If you wish to do this, it&#8217;s useful to remember to run Set-ExecutionPolicy on both versions:</p>
<ul>
<li>C:\Windows\SysWOW64\WindowsPowerShell\v1.0\Powershell.exe</li>
<li>C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe</li>
</ul>
<p><strong>1. Install IIS with the following:</strong></p>
<ul>
<li>CGI</li>
<li>Basic Authentication</li>
<li>Recommended: URL authorization (if you want to limit access to particular Active Directory users or groups).</li>
<li>Optional: IP and Domain Restrictions (if you want to limit access to a particular IP range on your LAN).</li>
<li>Install any Windows patches that may be needed by adding IIS to your server.</li>
</ul>
<p><strong>2. Install PHP:</strong><br />
<a name="phpnote">Note</a>: PHP.net only compile and officially support x86 versions of PHP. Unfortunately this means that the x86 version of Powershell is launched and may prove a limitation for you; in our case we wanted to load Exchange 2010 snap-ins which require the x64 version of Powershell, and so needed x64 PHP. Anindya over at <a href="http://www.anindya.com/" target="_blank">http://www.anindya.com/</a> very kindly compiles these as x64 when PHP releases a new version.</p>
<ol>
<li>Download and extract the latest &#8220;VC9 x64 Non Thread Safe&#8221; version of PHP from <a href="http://www.anindya.com/" target="_blank">http://www.anindya.com/</a>. Put this somewhere you want to keep PHP (e.g. F:\PHP).</li>
<li>Install PHP Manager from <a href="http://phpmanager.codeplex.com/" target="_blank">http://phpmanager.codeplex.com/</a>.</li>
<li>Add the location of PHP (e.g. F:\PHP;) to the <a href="http://msdn.microsoft.com/en-us/library/ee537574.aspx" title="Path variable editing" target="_blank">Path environment variable</a>.</li>
</ol>
<p><strong>3. Configure IIS:</strong></p>
<ol>
<li>Within IIS Manager, right click on &#8220;Sites&#8221; and choose &#8220;Add Web Site&#8230;&#8221;. When trying to think of an acronym for the test website I came up with WAM (Web Automated Management) and that stuck. Specify your website name, a physical path (e.g. C:\inetpub\wwwroot\wam), hostname and IP address binding.</li>
<li>Select the website and within the Authentication module for the new site, enable Basic and disable the Anonymous authentication. Remember, if your website is not secured using HTTPS, passwords will be sent over the network in plain text. This may not worry you but I need to point it out. There are many guides online on how to create a self signed SSL certificate for your IIS server.</li>
<li>Again within the website, select the PHP Manager module and click &#8220;Register new PHP version&#8221; and locate your php-cgi.exe executable.</li>
</ol>
<p><strong>4. Configure PHP:</strong></p>
<ol>
<li>Open PHP.ini. You will likely have to change some of these depending on your setup. I&#8217;ve described what I changed by specifying the initial value which you can search for, then the pipe symbol and the new value (e.g. search for | modify to):
<ul>
<li>error_log = &#8220;C:\Windows\Temp\php-5.4.3_errors.log&#8221; | error_log = &#8220;F:\php-errors\php-5.4.3_errors.log&#8221;</li>
<li>max_execution_time = 300 | max_execution_time = 600</li>
<li>display_errors = Off | display_errors = On</li>
<li>date.timezone = &#8220;Europe/Minsk&#8221; = | date.timezone = Europe/London</li>
</ul>
</li>
<li>Grant the local IIS_IUSRS group modify NTFS permission on the log folder for the PHP error log.</li>
</ol>
<p>&nbsp;</p>
<p><a name="part3"><strong><u>Writing the PHP Page:</u></strong></a></p>
<p>Now, our PHP pages are a little more complicated than the example I&#8217;m going to give here. We only display certain pages to certain groups of users. We validate our submitted data using PHP functions. We return information to the screen if required fields aren&#8217;t filled in before submitting the form. We use jQuery mobile to present a mobile version to mobile users (I love this ability). The list goes on. You can make your PHP as advanced (but user friendly!) as you want; that&#8217;s the fun in developing websites :) Here I&#8217;ll just show how you can write an extremely simple page to pass the data to a Powershell script. If you want to take thing into a production environment I suggest you expand on this as we have done, but this serves as a proof of concept :)</p>
<p><strong>Example PHP Page:</strong></p>
<p>Let&#8217;s call this page &#8220;get-process.php&#8221;, and save it into the root of the created website:</p>
<pre class="brush: php; title: ; notranslate">
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Testing Powershell&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php

// If there was no submit variable passed to the script (i.e. user has visited the page without clicking submit), display the form:
if(!isset($_POST[&quot;submit&quot;]))
{
	?&gt;
	&lt;form name=&quot;testForm&quot; id=&quot;testForm&quot; action=&quot;get-process.php&quot; method=&quot;post&quot; /&gt;
		Your name: &lt;input type=&quot;text&quot; name=&quot;username&quot; id=&quot;username&quot; maxlength=&quot;20&quot; /&gt;&lt;br /&gt;
		&lt;input type=&quot;submit&quot; name=&quot;submit&quot; id=&quot;submit&quot; value=&quot;Do stuff&quot; /&gt;
	&lt;/form&gt;
	&lt;?php	
}
// Else if submit was pressed, check if all of the required variables have a value:
elseif((isset($_POST[&quot;submit&quot;])) &amp;&amp; (!empty($_POST[&quot;username&quot;])))
{
	// Get the variables submitted by POST in order to pass them to the Powershell script:
	$username = $_POST[&quot;username&quot;];
	// Best practice tip: We run out POST data through a custom regex function to clean any unwanted characters, e.g.:
	// $username = cleanData($_POST[&quot;username&quot;]);
		
	// Path to the Powershell script. Remember double backslashes:
	$psScriptPath = &quot;F:\\get-process.ps1&quot;;

	// Execute the Powershell script, passing the parameters:
	$query = shell_exec(&quot;powershell -command $psScriptPath -username '$username'&lt; NUL&quot;);
	echo $query;	
}
// Else the user hit submit without all required fields being filled out:
else
{
	echo &quot;Sorry, you did not complete all required fields. Please go back and try again.&quot;;
}
?&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>&nbsp;</p>
<p><a name="part4"><strong><u>Writing the Powershell Script:</u></strong></a></p>
<p>Call this get-process.ps1. Save it to the location specified in the above PHP script (It can be anywhere you like, but I recommend they are outside the website root. We actually store ours on a different drive). Naming conventions are useful and in this instance it&#8217;s handy to use the same name for both PHP and PS1 script for troubleshooting.</p>
<pre class="brush: powershell; title: ; notranslate">
#*=============================================================================
#* Script Name: get-process.ps1
#* Created: 	2012-01-01
#* Author: 	Robin Malik
#* Purpose: 	This is a simple script that executes get-process.
#*			
#*=============================================================================

#*=============================================================================
#* PARAMETER DECLARATION
#*=============================================================================
param(
[string]$username
)
#*=============================================================================
#* REVISION HISTORY
#*=============================================================================
#* Date: 
#* Author:
#* Purpose:
#*=============================================================================

#*=============================================================================
#* IMPORT LIBRARIES
#*=============================================================================

#*=============================================================================
#* PARAMETERS
#*=============================================================================

#*=============================================================================
#* INITIALISE VARIABLES
#*=============================================================================
# Increase buffer width/height to avoid Powershell from wrapping the text before
# sending it back to PHP (this results in weird spaces).
$pshost = Get-Host
$pswindow = $pshost.ui.rawui
$newsize = $pswindow.buffersize
$newsize.height = 3000
$newsize.width = 400
$pswindow.buffersize = $newsize

#*=============================================================================
#* EXCEPTION HANDLER
#*=============================================================================

#*=============================================================================
#* FUNCTION LISTINGS
#*=============================================================================

#*=============================================================================
#* Function: 	function1
#* Created: 	2012-01-01
#* Author: 	My Name
#* Purpose: 	This function does X Y Z
#* =============================================================================

#*=============================================================================
#* END OF FUNCTION LISTINGS
#*=============================================================================

#*=============================================================================
#* SCRIPT BODY
#*=============================================================================
Write-Output &quot;Hello $username &lt;br /&gt;&quot;

# Get a list of running processes:
$processes = Get-Process

# Write them out into a table with the columns you desire:
Write-Output &quot;&lt;table&gt;&quot;
Write-Output &quot;&lt;thead&gt;&quot;
Write-Output &quot;	&lt;tr&gt;&quot;
Write-Output &quot;		&lt;th&gt;Process Name&lt;/th&gt;&quot;
Write-Output &quot;		&lt;th&gt;Id&lt;/th&gt;&quot;
Write-Output &quot;		&lt;th&gt;CPU&lt;/th&gt;&quot;
Write-Output &quot;	&lt;/tr&gt;&quot;
Write-Output &quot;&lt;/thead&gt;&quot;
Write-Output &quot;&lt;tfoot&gt;&quot;
Write-Output &quot;	&lt;tr&gt;&quot;
Write-Output &quot;		&lt;td&gt;&amp;nbsp;&lt;/td&gt;&quot;
Write-Output &quot;		&lt;td&gt;&amp;nbsp;&lt;/td&gt;&quot;
Write-Output &quot;		&lt;td&gt;&amp;nbsp;&lt;/td&gt;&quot;
Write-Output &quot;	&lt;/tr&gt;&quot;
Write-Output &quot;&lt;/tfoot&gt;&quot;
Write-Output &quot;&lt;tbody&gt;&quot;
foreach($process in $processes)
{
Write-Output &quot;	&lt;tr&gt;&quot;
Write-Output &quot;		&lt;td&gt;$($process.Name)&lt;/td&gt;&quot;
Write-Output &quot;		&lt;td&gt;$($process.Id)&lt;/td&gt;&quot;
Write-Output &quot;		&lt;td&gt;$($process.CPU)&lt;/td&gt;&quot;
Write-Output &quot;	&lt;/tr&gt;&quot;
}
Write-Output &quot;&lt;/tbody&gt;&quot;
Write-Output &quot;&lt;/table&gt;&quot;
#*=============================================================================
#* END SCRIPT BODY
#*=============================================================================

#*=============================================================================
#* END OF SCRIPT
#*=============================================================================
</pre>
<p>&nbsp;</p>
<p><a name="part5"><strong><u>Use Cases:</u></strong></a></p>
<p>That&#8217;s all there is to it! You can visit the webpage, enter your name and submit the form. What you do from here is really up to you and only limited by your talent and imagination :) We&#8217;ve created pages that save an incredible amount of work for both us and the service desk and so finally, some examples on how we use them which may (or may not) inspire you.</p>
<p>It&#8217;s worth noting here that where applicable, the Powershell scripts also log this data to our &#8220;changelog&#8221; website (a bespoke system/website to record changes made to servers/devices) via an API call using <a href="http://msdn.microsoft.com/en-us/library/system.net.webclient%28v=vs.80%29.aspx" target="_blank">System.Net.WebClient</a>. This saves a *lot* of fiddly manual work, remembering to record the changes after you&#8217;ve made them(!) and allows for a consistent method of recording changes for specific actions.</p>
<p>Just some of the pages we have in use at the moment allow for:</p>
<ul>
<li>Creation of different kinds of AD accounts to be created (service accounts, admin accounts, remote accounts).</li>
<li>Resetting a user&#8217;s password (generating a new one).</li>
<li>Retrieval of detailed information on an AD user (e.g. name, phone number, email, true last logon, locked out status, enabled status, Exchange email quota, mailbox size, home drive usage etc.).</li>
<li>Adding/removing users to/from AD groups or local groups on computers/servers.</li>
<li>Retrieval of detailed server information (installed software, local admins/remote desktop users, configured IP addresses, accessible shares etc.).</li>
<li>Granting full access and send as permissions on an Exchange mailbox to another user.</li>
<li>Increasing a user&#8217;s email quota.</li>
<li>Resetting the permissions on a user&#8217;s home drive (calling setacl.exe).</li>
<li>Changing of a user&#8217;s display name.</li>
</ul>
<p>&nbsp;</p>
<p><a name="part6"><strong><u>Caveats:</u></strong></a></p>
<ul>
<li>Obviously the webpage is going to wait while the Powershell script is executing. I&#8217;ve had to increase the max_timeout value in php.ini from 300 to 600 to allow for 10 minutes of PHP execution time before quitting. I encounted this when resetting the permissions on a user&#8217;s home drive that was *quite large*. If the PHP timeout value is reached, you&#8217;ll receive an error 500. The Powershell process will continue to run and complete, but it&#8217;s nice to avoid this.</li>
<li>If you want your displayed output to be nice, you will need to write HTML within Powershell. In the above Powershell script you will notice use of HTML so that when PHP displays the result we get a table. </li>
<li>If you&#8217;re considering using Start-Transcript to log within your Powershell script, it doesn&#8217;t work. Launching Powershell via shell_exec *within a PHP page* (not from the PHP command line) will result in a transcript file that has a header, footer, but no content.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://theboywonder.co.uk/2012/07/29/executing-powershell-using-php-and-iis/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Importing VEM500-201201140102-BG-release.zip to VUM results in an error</title>
		<link>http://theboywonder.co.uk/2012/03/26/importing-vem500-201201140102-bg-release/</link>
		<comments>http://theboywonder.co.uk/2012/03/26/importing-vem500-201201140102-bg-release/#comments</comments>
		<pubDate>Mon, 26 Mar 2012 15:25:56 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[Geek Stuff]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[vem]]></category>
		<category><![CDATA[vmware]]></category>
		<category><![CDATA[vmware update manager]]></category>
		<category><![CDATA[vum]]></category>

		<guid isPermaLink="false">http://theboywonder.co.uk/?p=728</guid>
		<description><![CDATA[In order to install cross_cisco-vem-v140-4.2.1.1.5.1.0-3.0.1.vib to our vCenter 5 / ESXi 5 / Cisco 1000V environment we attempted to add the following VEM to VMware Update Manager (VUM): VEM500-201201140102-BG-release.zip (extracted from Nexus1000v.4.2.1.SV1.5.1.zip). Unfortunately on first attempt we received an error along the lines of &#8220;invalid vendor code CSCO in patch metadata, another vendor code with [...]]]></description>
				<content:encoded><![CDATA[<p>In order to install cross_cisco-vem-v140-4.2.1.1.5.1.0-3.0.1.vib to our vCenter 5 / ESXi 5 / Cisco 1000V environment we attempted to add the following VEM to VMware Update Manager (VUM): VEM500-201201140102-BG-release.zip (extracted from Nexus1000v.4.2.1.SV1.5.1.zip). Unfortunately on first attempt we received an error along the lines of &#8220;invalid vendor code CSCO in patch metadata, another vendor code with different code already exists&#8230;&#8221; (I didn&#8217;t save the error and only googled it in partiality so I can&#8217;t copy it here I&#8217;m afraid). In short, it stopped us from importing the patch.</p>
<p>This was solved by extracting the VEM500-201201140102-BG-release.zip, opening index.xml (wordpad is suitable) and modifying the <code>code</code> XML node from CSCO to csco. We then rezipped the folder contents and imported it successfully.</p>
<p>Thanks to <a href="http://www.thatcouldbeaproblem.com/?p=341" title="http://www.thatcouldbeaproblem.com/?p=341" target="_blank">http://www.thatcouldbeaproblem.com/?p=341</a> for the nod in the right direction :)</p>
]]></content:encoded>
			<wfw:commentRss>http://theboywonder.co.uk/2012/03/26/importing-vem500-201201140102-bg-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speeding up Get-WinEvent in Powershell by using FilterHashTable</title>
		<link>http://theboywonder.co.uk/2012/03/15/speeding-up-get-winevent-in-powershell-by-using-filterhashtable/</link>
		<comments>http://theboywonder.co.uk/2012/03/15/speeding-up-get-winevent-in-powershell-by-using-filterhashtable/#comments</comments>
		<pubDate>Thu, 15 Mar 2012 22:45:14 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[Geek Stuff]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[efficiency]]></category>
		<category><![CDATA[eventlogs]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://theboywonder.co.uk/?p=659</guid>
		<description><![CDATA[At work I&#8217;ve been working on a website to collate various bits of reporting information about our infrastructure. I wanted one of these reports to be selected eventlog entries of our servers, split up by WSUS patch phases (i.e. one report per AD security group). The idea behind this was that we could arrive at [...]]]></description>
				<content:encoded><![CDATA[<p>At work I&#8217;ve been working on a website to collate various bits of reporting information about our infrastructure. I wanted one of these reports to be selected eventlog entries of our servers, split up by WSUS patch phases (i.e. one report per AD security group). The idea behind this was that we could arrive at work in the morning knowing that Phase X had patched overnight and take a look at a jQuery sortable HTML table showing any issues with servers in that phase/group. If this was quick enough, we could even execute it live against a single server via another website I&#8217;ve been working on (I&#8217;ll post about that later). I also want to say that while have a Solarwinds monitoring solution (APM) and their Windows based log forwarder application, the forwarded eventlogs are sent to a SQL database as syslog messages which simply don&#8217;t have the same level of detail as a Powershell event object. Anyway back on topic.</p>
<p>Two approaches sprang to mind:</p>
<ul>
<li>Invoke-Command by way of WinRM</li>
<li>The remote capabilities of either Get-WinEvent or Get-EventLog</li>
</ul>
<p>Rolling out WinRM is an ongoing project and so the latter it was. A read around online and Get-WinEvent was touted a quickest especially when querying remote computers so I started with that. I constructed my query to retrieve any errors or critical messages in the application eventlog since 4am which is the time of patching:</p>
<pre class="brush: powershell; title: ; notranslate">
$computerName = &quot;remoteserver&quot;
# Create a timestamp after which to retrieve events. This should be from 4am on the current day:
$currDatetime = Get-Date
$day = $currDatetime.Day
$month = $currDatetime.Month
$year = $currDatetime.Year
$patchDateTime = New-Object -TypeName System.DateTime($year,$month,$day,04,00,00)
$appLog = Get-WinEvent -LogName &quot;Application&quot; -ComputerName $computerName -ErrorAction SilentlyContinue | Where-Object { ( ($_.LevelDisplayName -eq &quot;Error&quot; -or $_.LevelDisplayName -eq &quot;Critical&quot;) -and ($_.TimeCreated -ge $patchDateTime) ) } | Select-Object TimeCreated,LogName,ProviderName,Id,LevelDisplayName,Message
</pre>
<p>It took <em>forever</em> to run. Ok not quite, but it took 11 minutes! Very slow.</p>
<p>&#8220;Back to basics&#8221; I thought. Let&#8217;s test the execution time of a simpler query on my local machine:</p>
<pre class="brush: powershell; title: ; notranslate">
$yesterday = (get-date) - (new-timespan -day 1)
Measure-Command -Expression { Get-WinEventLog -LogName &quot;Application&quot; -ErrorAction SilentlyContinue | Where-Object { ($_.TimeCreated -ge $yesterday) -and ($_.LevelDisplayName -eq &quot;Error&quot;) } }
</pre>
<p>22 seconds for 1 result (out of 104 records in the last 24 hours). Hmmm.</p>
<p>How about against the original server?:</p>
<pre class="brush: powershell; title: ; notranslate">
Measure-Command -Expression { Get-WinEventLog -LogName &quot;Application&quot; -ErrorAction SilentlyContinue | Where-Object { ($_.TimeCreated -ge $yesterday) -and ($_.LevelDisplayName -eq &quot;Error&quot;) } }
</pre>
<p>330 seconds (5.5 minutes) for 2 results (out of 128 records in the last 24 hours). Very disappointing. We have 140 servers and querying them all was not going to happen using this approach and standard sequential / synchronous processing. While it would be possible to save time by using asynchronous processing (background jobs or multiple threads) I was certain that this command should be orders of magnitude faster.</p>
<p>I did a little more reading and discovered the -FilterHashTable parameter of the Get-WinEvent cmdlet. This filters the objects while being retrieved on the server, rather than retrieving all the objects and then filtering as happens with Where-Object. </p>
<pre class="brush: powershell; title: ; notranslate">Get-Help Get-WinEvent -Parameter FilterHashTable</pre>
<p> showed the key:value pairs accepted by the parameter. The user friendly &#8220;LevelDisplayName&#8221; key was not one of these, but luckily &#8220;Levels&#8221; of events (error,warning,information etc.) are also given the &#8220;Level&#8221; property which <em>is</em> accepted by FilterHashTable. &#8220;Error&#8221; = Level 2. If you want to know how to see this sort of information the easiest way is to double click an eventlog entry, click the &#8220;details&#8221; tab and then select XML view.</p>
<p>A new, equivalent query was born using this new method and executed against my local computer:</p>
<pre class="brush: powershell; title: ; notranslate">
Measure-Command -Expression { Get-WinEvent -FilterHashTable @{LogName='Application'; Level=2; StartTime=$yesterday} -ErrorAction SilentlyContinue }
</pre>
<p>0.09 seconds! Some 244x faster. I stripped off the Measure-Command to find it was indeed pulling back the same single error record as previously (without -FilterHashtable). Fantastic!</p>
<p>Now against the remote server:</p>
<pre class="brush: powershell; title: ; notranslate">
Measure-Command -Expression { Get-WinEvent -FilterHashTable @{LogName='Application'; Level=2; StartTime=$yesterday} -ErrorAction SilentlyContinue -ComputerName $remoteserver }
</pre>
<p>0.43 seconds.</p>
<p>So back to my original command. As we&#8217;re not allowed duplicate keys in a hash table two queries were needed:</p>
<pre class="brush: powershell; title: ; notranslate">
$appErrors = Get-WinEvent -FilterHashTable @{LogName='Application'; Level=2; StartTime=$yesterday} -ErrorAction SilentlyContinue -ComputerName $remoteserver | Select-Object TimeCreated,LogName,ProviderName,Id,LevelDisplayName,Message
$appCritical = Get-WinEvent -FilterHashTable @{LogName='Application'; Level=1; StartTime=$yesterday} -ErrorAction SilentlyContinue -ComputerName $remoteserver | Select-Object TimeCreated,LogName,ProviderName,Id,LevelDisplayName,Message
# Combine and sort the arrays
$appCombined = $appErrors + $appCritical | Sort TimeCreated
</pre>
<p>1.85 seconds. Outstanding :)</p>
<p>I then went on my merry way about creating a fully fledged script. Ultimately it worked very well and against a batch of 20 servers took 3.89 minutes with some 18,000 records returned, although it did complain with many &#8220;There are no more endpoints available from the endpoint mapper.&#8221; error messages which I noticed were against our 2003 servers. It appears that Get-WinEvent doesn&#8217;t work against 2003 but at least from a 2008R2 server it happily works against 2008+ with -FilterHashTable. I may have to construct a different, equivalent Get-EventLog query purely for the 2003 servers.</p>
]]></content:encoded>
			<wfw:commentRss>http://theboywonder.co.uk/2012/03/15/speeding-up-get-winevent-in-powershell-by-using-filterhashtable/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Behind the Barriers &#8211; All Videos</title>
		<link>http://theboywonder.co.uk/2011/12/29/behind-the-barriers-all-videos/</link>
		<comments>http://theboywonder.co.uk/2011/12/29/behind-the-barriers-all-videos/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 14:05:38 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[Documentaries]]></category>
		<category><![CDATA[Entertainment]]></category>
		<category><![CDATA[Training]]></category>
		<category><![CDATA[cyclocross]]></category>
		<category><![CDATA[jeremy powers]]></category>
		<category><![CDATA[tim johnson]]></category>

		<guid isPermaLink="false">http://theboywonder.co.uk/?p=637</guid>
		<description><![CDATA[As finding episodes for this show isn&#8217;t that easy on Vimeo (try a search for &#8220;behind the barriers episode 2&#8243; 2and you won&#8217;t find what you&#8217;re looking for) I decided to make a list of all the episodes so that I could easily view them when I found time. Hope this makes things easier for [...]]]></description>
				<content:encoded><![CDATA[<p>As finding episodes for this show isn&#8217;t that easy on Vimeo (try a search for &#8220;behind the barriers episode 2&#8243; 2and you won&#8217;t find what you&#8217;re looking for) I decided to make a list of all the episodes so that I could easily view them when I found time. Hope this makes things easier for a few people.</p>
<p><strong>Season 1 (2010-2011):</strong><br />
S01E01: <a href="http://vimeo.com/15415166" target="_blank">http://vimeo.com/15415166</a><br />
S01E02: <a href="http://vimeo.com/15454445" target="_blank">http://vimeo.com/15454445</a><br />
S01E03: <a href="http://vimeo.com/15594701" target="_blank">http://vimeo.com/15594701</a><br />
S01E04: <a href="http://vimeo.com/16053701" target="_blank">http://vimeo.com/16053701</a><br />
S01E05: <a href="http://vimeo.com/16275951" target="_blank">http://vimeo.com/16275951</a><br />
S01E06: <a href="http://vimeo.com/16579221" target="_blank">http://vimeo.com/16579221</a><br />
S01E07: <a href="http://vimeo.com/16885681" target="_blank">http://vimeo.com/16885681</a><br />
S01E08: <a href="http://vimeo.com/17308783" target="_blank">http://vimeo.com/17308783</a><br />
S01E09: <a href="http://vimeo.com/17529112" target="_blank">http://vimeo.com/17529112</a><br />
S01E10: <a href="http://vimeo.com/17842734" target="_blank">http://vimeo.com/17842734</a><br />
S01E11: <a href="http://vimeo.com/17943375" target="_blank">http://vimeo.com/17943375</a><br />
S01E12: <a href="http://vimeo.com/18127798" target="_blank">http://vimeo.com/18127798</a><br />
S01E13: <a href="http://vimeo.com/18389897" target="_blank">http://vimeo.com/18389897</a><br />
Season Finale Teaser: <a href="http://vimeo.com/18575849" target="_blank">http://vimeo.com/18575849</a><br />
S01E14: <a href="http://vimeo.com/18823159" target="_blank">http://vimeo.com/18823159</a></p>
<p><strong>Summer 2011 Specials:</strong><br />
Special Summer Edition E01: <a href="http://vimeo.com/24366749" target="_blank">http://vimeo.com/24366749</a><br />
Special Summer Edition E02: <a href="http://vimeo.com/28468730" target="_blank">http://vimeo.com/28468730</a><br />
Special Summer Edition E03: <a href="http://vimeo.com/29124040" target="_blank">http://vimeo.com/29124040</a></p>
<p><strong>Season 2 (2011-2012):</strong><br />
S02E01: <a href="http://vimeo.com/29546161" target="_blank">http://vimeo.com/29546161</a><br />
S02E02: <a href="http://vimeo.com/29956978" target="_blank">http://vimeo.com/29956978</a><br />
S02E03: <a href="http://vimeo.com/30376013" target="_blank">http://vimeo.com/30376013</a><br />
S02E04: <a href="http://vimeo.com/30785035" target="_blank">http://vimeo.com/30785035</a><br />
S02E05: <a href="http://vimeo.com/30940214" target="_blank">http://vimeo.com/30940214</a><br />
S02E06: <a href="http://vimeo.com/31241633" target="_blank">http://vimeo.com/31241633</a><br />
S02E07: <a href="http://vimeo.com/31572937" target="_blank">http://vimeo.com/31572937</a><br />
S02E08: <a href="http://vimeo.com/32101765" target="_blank">http://vimeo.com/32101765</a><br />
S02E09: <a href="http://vimeo.com/32565236" target="_blank">http://vimeo.com/32565236</a><br />
S02E10: <a href="http://vimeo.com/33215252" target="_blank">http://vimeo.com/33215252</a><br />
S02E11: <a href="http://vimeo.com/33974273" target="_blank">http://vimeo.com/33974273</a><br />
S02E12: <a href="http://vimeo.com/34463673" target="_blank">http://vimeo.com/34463673</a><br />
S02E13: <a href="http://vimeo.com/34849718" target="_blank">http://vimeo.com/34849718</a><br />
S02E14: <a href="http://vimeo.com/35230996" target="_blank">http://vimeo.com/35230996</a><br />
S02S01: <a href="http://vimeo.com/35438844" target="_blank">http://vimeo.com/35438844 (Hoogerheide World Cup Bar Cam Footage)</a><br />
S02E15: <a href="http://vimeo.com/35561309" target="_blank">http://vimeo.com/35561309</a><br />
S02S02: <a href="http://vimeo.com/35681607" target="_blank">http://vimeo.com/35681607 (Koksijde World Championships Bar Cam Footage)</a><br />
S02E16: <a href="http://vimeo.com/35858803" target="_blank">http://vimeo.com/35858803</a><br />
S02E17: <a href="http://vimeo.com/36767922" target="_blank">http://vimeo.com/36767922</a><br />
S02E18: <a href="http://vimeo.com/37671745" target="_blank">http://vimeo.com/37671745</a></p>
]]></content:encoded>
			<wfw:commentRss>http://theboywonder.co.uk/2011/12/29/behind-the-barriers-all-videos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Capdase 180A MKeeper Camera Case</title>
		<link>http://theboywonder.co.uk/2011/12/05/capdase-180a-mkeeper-camera-case/</link>
		<comments>http://theboywonder.co.uk/2011/12/05/capdase-180a-mkeeper-camera-case/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 21:02:09 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[Daily life]]></category>

		<guid isPermaLink="false">http://theboywonder.co.uk/?p=630</guid>
		<description><![CDATA[The lovely fellows over at Love Cases kindly offered to send me a free Nikon D3100 case to review for the camera that I bought in March; I didn&#8217;t say no! It&#8217;s called the &#8220;Capdase 180A MKeeper&#8221;. Goodness knows who came up with that name but that doesn&#8217;t matter! I have to say I&#8217;m extremely [...]]]></description>
				<content:encoded><![CDATA[<p>The lovely fellows over at Love Cases kindly offered to send me a free <a href="http://www.lovecases.co.uk/camera-cases-bags/nikon/dslr/nikon-d3100-cases.html" target="_blank">Nikon D3100 case</a> to review for the camera that I bought in March; I didn&#8217;t say no! It&#8217;s called the <a href="http://www.lovecases.co.uk/capdase-180a-mkeeper-camera-bag.html" target="_blank">&#8220;Capdase 180A MKeeper&#8221;</a>. Goodness knows who came up with that name but that doesn&#8217;t matter! I have to say I&#8217;m extremely impressed with it and wouldn&#8217;t hesitate to buy it at it&#8217;s current price of £17.95. My brother has subsequently bought one after seeing mine, and my Dad is going to purchase one for his new camera also.</p>
<p>Note that the case is only big enough for 1 lens though. If you have two lenses (which I can&#8217;t justify) then perhaps the larger model would suit: <a href="http://www.lovecases.co.uk/capdase-270a-mkeeper-camera-bag.html" target="_blank">Capdase 270A</a>.</p>
<p>From the front, minus the main strap (which attaches via study plastic clips to the side):<br />
<a href="http://theboywonder.co.uk/wp-mm/capdase/DSC_0101.JPG" target="_blank" width="600"><img src="http://theboywonder.co.uk/wp-mm/capdase/DSC_0104.JPG" alt="0104" /></a></p>
<p>A close up showing the quality of the fabric/weave. It seems resistant to buffs, scuffs and nicks so far:<br />
<a href="http://theboywonder.co.uk/wp-mm/capdase/DSC_0102.JPG" target="_blank" width="600"><img src="http://theboywonder.co.uk/wp-mm/capdase/DSC_0102.JPG" alt="0102" /></a></p>
<p>The front pocket. Large enough for a few batteries and other bits:<br />
<a href="http://theboywonder.co.uk/wp-mm/capdase/DSC_0103.JPG" target="_blank" width="600"><img src="http://theboywonder.co.uk/wp-mm/capdase/DSC_0103.JPG" alt="0103" /></a></p>
<p>The inside. Additional pocket inside the top flap, and a removable velcro fitting in case you want to keep the lens separate from the body:<br />
<a href="http://theboywonder.co.uk/wp-mm/capdase/DSC_0104.JPG" target="_blank" width="600"><img src="http://theboywonder.co.uk/wp-mm/capdase/DSC_0104.JPG" alt="0104" /></a></p>
<p>From a tiny zip pocket at the back, a pull out waterproof(?)/resistant cover!<br />
<a href="http://theboywonder.co.uk/wp-mm/capdase/DSC_0105.JPG" target="_blank" width="600"><img src="http://theboywonder.co.uk/wp-mm/capdase/DSC_0105.JPG" alt="0105" /></a></p>
<p>For a wider range of bags for all cameras check out: <a href="http://www.lovecases.co.uk/camera-cases-bags/slr-and-dslr-1.html" target="_blank">dslr camera bag</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://theboywonder.co.uk/2011/12/05/capdase-180a-mkeeper-camera-case/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Fight Back to Fitness, Part 2</title>
		<link>http://theboywonder.co.uk/2011/11/03/the-fight-back-to-fitness-part-2/</link>
		<comments>http://theboywonder.co.uk/2011/11/03/the-fight-back-to-fitness-part-2/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 16:37:05 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[Ego]]></category>
		<category><![CDATA[Training]]></category>

		<guid isPermaLink="false">http://theboywonder.co.uk/?p=614</guid>
		<description><![CDATA[I wrote quite some time ago about my attempt to find some fitness after almost 10 years off the bike. To be clear, I&#8217;m never ever going to stand on a podium. I probably won&#8217;t ever make the top 20 in the local cross league but I do want to better myself and crucially, my [...]]]></description>
				<content:encoded><![CDATA[<p>I wrote <a href="http://theboywonder.co.uk/2010/03/02/the-fight-back-to-fitness/" target="_blank">quite some time ago</a> about my attempt to find some fitness after almost 10 years off the bike. To be clear, I&#8217;m never ever going to stand on a podium. I probably won&#8217;t ever make the top 20 in the local cross league but I <em>do</em> want to better myself and crucially, my previous self. This year I think I&#8217;ve reached a notable milestone in this aim and so it&#8217;s time for a (rather long self indulged) update.</p>
<p>To summarise previous writing I took up cycling again in April 2009 and managed just 4 races in the 2009-2010 <a href="http://ndcxl.org.uk/" target="_blank">Notts and Derby Cyclocross</a> (NDCXL) season before deciding to take some time off. I felt weak, wasn&#8217;t enjoying it and for a while other things took priority over cycling entirely. In all honesty I felt pretty demoralized. By March 2010 when I wrote the last post I was feeling chipper again and other issues had settled a little. I was ready to hit the bike! Before that though I needed to reassess things slightly and have a think about &#8220;what went wrong&#8221;. I came up with a few ideas:</p>
<ul>
<li>Holding unrealistic expectations; while I managed to find reasonable form as a junior in just 12 weeks, the 4 months off the bike prior to that was preceded by roughly 3 years of consistent riding and cross seasons as a juvenile rider. To expect to get even close to that after 5/6 months of training after 10 years off was too much!</li>
<li>Not riding enough base miles: Effectively I was starting from scratch and hadn&#8217;t yet accumulated any decent mileage. I simply didn&#8217;t have the years of conditioning that result in a form of &#8220;inherent&#8221; stamina (which is my weak point anyway). This kind of thing takes time.</li>
<li>Not enough hills, and not enough hills with vengeance!</li>
</ul>
<p>So with those thoughts in mind I started to focus on the 2010-2011 season and gradually increased the miles from around April onwards (trying to balance it with a little training for the Derby 10K). Over the summer I managed more of the elusive 100+ mile weeks that I&#8217;d been chasing the previous year. I rode more hills and I rode them <em>what I thought</em> was hard. Being half a stone heavier and still weaker than my 18 year old self I still couldn&#8217;t come close to matching my best time up <a href="http://g.co/maps/u4jrp" target="_blank">Sandy Lane</a> but I <em>was</em> making progress. I entered the 2010-2011 season feeling &#8220;ok&#8221; and in an attempt to manage expectations I told myself that any performance better than last year would be good enough. Hahahaha! Right. Well despite this notion, comparisons to my former self were ultimately inevitable. As a junior I&#8217;d finished 16th / 130 odd in the same league on a few occasions; a placing that along with the Sandy Lane time had remained stuck in my head and been a focal point ever since starting cycling again. All in all I managed 8 races that season &#8220;trundling&#8221; round in around 60-70th place and being lapped EASILY. Best result? 46th at Sinfin which I was fairly happy with, but 25th was 10 minutes down and everyone after that was lapped. Still lacking. Now I *completely* understand that many people would be happy to finish 70th but equally some would be gutted to place 17th or maybe even 7th. It&#8217;s all relative isn&#8217;t it? We&#8217;re all just seeking to improve on what we know we&#8217;re capable of. Of course those who would complain about only finishing 7th would be slightly more annoying to the majority of us ;) Anyway I couldn&#8217;t figure out what I was doing wrong. The thoughts were persistent:</p>
<blockquote><p>&#8220;I&#8217;m only 28! I&#8217;m not past my peak yet!&#8221;<br />
&#8220;It shouldn&#8217;t be impossible. It can&#8217;t just be because I work a full time job surely?&#8221;</p></blockquote>
<p>Thankfully I didn&#8217;t feel as disappointed as before but more thinking was definitely required.</p>
<p>At the end of the 2010-2011 season (about 8 months ago in March 2011) I switched focus a little to getting a few more running miles in the legs as I wanted to do my second 10K in under 40 minutes. Thankfully <a href="http://theboywonder.co.uk/2011/04/03/derby-10k-2011/" target="_blank">I did just that</a> :) I started to look over my training logs and thought about the kinds of rides I&#8217;d done the previous summer and what I did as a junior. What was missing? Base miles and hard hills can&#8217;t have been the answer. Then something hit me. It wasn&#8217;t raw data or training statistics but a memory. A particular section of road and a particular feeling associated with it: pain. When I was younger I used to do rides of around 45 minutes but flat out, race place. I think somehow I&#8217;d tapped into the youthful desire to prove myself and used that often to ride flat out and really hurt myself. I remembered this one section of road just a mile from home which was a real drag. I&#8217;d be giving it everything just to increase my average by 0.1mph, legs and lungs screaming all the way to the doorstep. This was something I was completely missing and the realization of this made me feel utterly stupid. Base miles and special interval sessions on the turbo can&#8217;t and wont replace 45 minutes to 1 hour of constant hard pushing on the pedals when you&#8217;re training for something that involves almost exactly that. Graeme Obree training in a nutshell. Not only that but I felt like I was holding off slightly whenever I did ride hard. I was missing that extra impetus. So, new training objectives were put in place for late Spring and Summer ready for the 2011-2012 season.</p>
<ul>
<li>Start riding the chaingang to replace the 1 hour non stop hard rides I used to do.</li>
<li>Ride hills and ride them harder (note: having learnt once again how to hurt myself *properly* (thanks chaingang beasts) I could ride them harder than I did previously. Improvement in form = more repeats).</li>
<li>Do some strength training (either road or intervals) involving big (high) gears. I&#8217;d felt my legs were lacking strength in previous seasons and I&#8217;d resorted to spinning too low a gear. &#8220;Back in the day&#8221; (heh) I didn&#8217;t have a compact chainset on my road bike and so actually pushed a big gear and this was something I hadn&#8217;t been doing much at all even on hills. I knew this was essential.</li>
</ul>
<p>It&#8217;s worth mentioning that by this time I was also in a new and happier relationship &#8211; this allowed me to crunch all the training my body could take over the following 5-6 months (an *additional* 1000 miles over the previous year) without worry or compromise &#8211; after all I don&#8217;t really train that much as the schedules of far more dedicated riders prove! A few 170 mile weeks taught me a thing or two about over training. In June I did the Great Notts Bike Ride &#8211; 76 miles in 3:52. In July I managed a particular route of mine at 20.8mph ave. 0.1mph faster than when I was 17. I was <em>really</em> over the moon with this! While still not as fast on the hills I had proved that overall I was pretty much just as fast (all things considered). Finally after 2 years I felt like I could actually relax a bit!</p>
<p>And so, fast forward a little to the time of writing, part way through the 2011-2012 NDCXL season! I&#8217;m quite happy with my performance so far. All in all I think I trained as much as possible (for my mediocre body), and *almost* as smartly as I could have done and so I can&#8217;t expect any more just yet (that&#8217;s next year haha). I was fixated on my placing for a bit but I&#8217;ve realised that cyclocross races are not only attracting bigger fields but they&#8217;re a lot more competitive these days. More riders. Better riders. While I was 16th / 130 once upon a time, I was still 6 minutes down on the top league riders on a fast course. This season I&#8217;ve been 6 minutes down on fast courses and placed in the late 40s / early 50s. The top league riders will always be roughly of the same ability so it&#8217;s the &#8220;time down&#8221; that is a more accurate representation of your actual athletic performance, although finishing with a better position is always a bonus as it means more points! I&#8217;ve been able to race all of the races so far except for one (which I got average points for) and have been lucky enough to scrape enough to get into box 1. No more rushing to the start 15 minutes early to get a place at the front of box 2! I feel quite settled and content with my ability at the moment, but I&#8217;m still very much looking forward to seeing what I can do next year. If I could reduce that time gap from 6 to 4 minutes I&#8217;d be ecstatic, though I realise this may take a considerable amount of extra training. Now, if only this chest cold would go so I can get back on the bike and make myself hurt with a high cadence long interval turbo session&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://theboywonder.co.uk/2011/11/03/the-fight-back-to-fitness-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
