23 Feb 2012

Calling Executable Files in PowerShell

I was called out on my approach on this in work today, so I thought I would share my thoughts on this topic.  The actual executable concerned was STSADM command line tool for SharePoint 2010 (yes, STSADM is still useful in SharePoint 2010, for example in enabling self-service site creation). Unfortunately, I don’t have STSADM installed on the machine I’m writing this blog post on, so I use the example of calling Internet Explorer instead. The principal is the same in both cases.

To call Internet Explorer from the command line, you would use the following command:

C:\Program Files\Internet Explorer\iexplore.exe

But if you try and run the above command in PowerShell, you will get the following error:

PowerShell Error

To correct the error, we need to enclose the path to the iexplore.exe file in quotes:

“C:\Program Files\Internet Explorer\iexplore.exe”

But this will not actually result in IE being called; this is because PowerShell treats the input as a string, and will simply write the text enclosed in the quotes to the console.  To run the string as a script whose path is enclosed in quotes, you preface the string with the call operator (ampersand):

& “C:\Program Files\Internet Explorer\iexplore.exe”

Alternatively, we can use the Invoke-Item cmdlet:

Invoke-Item “C:\Program Files\Internet Explorer\iexplore.exe”

And both approaches will successfully start an instance of Internet Explorer.  Alternatively, you could break the statement into two:

CD “C:\Program Files\Internet Explorer\”
iexplore.exe

Which would also work.  Note, if you needed to return to the original directory from which the PowerShell script was called, you could do so using the following code:

Push-Location “C:\Program Files\Internet Explorer\”
iexplore.exe
Pop-Location

The cmdlet Push-Location is virtually identical to the CD command; however, it saves your previous location before moving to a new one.

So, can we now specify at the PowerShell prompt the URL that IE opens with? The command line switch information for IE tells us that we can, by adding an additional parameter:

& “C:\Program Files\Internet Explorer\iexplore.exe” http://www.bbc.co.uk/news/

And again, this successfully works.  Can we now call IE with several parameters?

& “C:\Program Files\Internet Explorer\iexplore.exe” http://www.bbc.co.uk/news/ –private

And this PowerShell statement will call Internet Explorer so that it opens at the BBC News site in p0rn InPrivate mode.  So that we can see that to call STSADM from PowerShell, we could use the following command:

& “C:\Program Files\Common Files\Microsoft Shared\Web server extensions\14\bin\stsadm.exe” -o enablessc -url http://myserver –requiresecondarycontact

And this would work.  Except, of course, that no self respecting software developer would leave should a horribly long line of code in a script.  They would refactor this line of code by using an alias for the STSADM executable, and so avoid having to repeatedly use a hard-coded literal for the executable path.  They would also realise that the location of the common programs varies according to how Windows itself was installed on the target computer, and make use of the %CommonProgramFiles% environment variable:

set-alias STSADM "${env:commonprogramfiles}\Microsoft Shared\Web Server Extensions\14\BIN\STSADM.EXE"
$serverUrl = http://myserver
…
STSADM –o enablessc –url $serverUrl –requiresecondarycontact

The above code is now more easily read and maintained.  If you want to investigate further how PowerShell parses quotes, etc., check out this StackOverFlow question, and Keith Hill’s answer:

13 Feb 2012

Sending Email Using PowerShell

I’ve just been called out on the fact that I didn’t complete my mini-blog series on sending emails using PowerShell.  So, to finally conclude those articles, an example of using the Send-MailMessage cmdlet that was introduced in PowerShell V2.0.

Send-MailMessage –From "recipient@target.com" –To "sender@source.com" –Subject "Test" –Body "A test of the Send-MailMessage cmdlet"  -Attachments "c:\Attachment.xls" –SmtpServer smtpServer.com

In order to send a email with multiple attachments, you need to pass an array with the full file paths of all the attachments to the -Attachments parameter. This is easily done in PowerShell by simply piping the contents to the Send-MailMessage cmdlet.

Get-ChildItem "C:\Folder" -Include *.txt | Where {-NOT $_.PSIsContainer} | foreach {$_.fullname} |
Send-MailMessage -From "recipient@target.com" -To "sender@source.com"  -subject "Test" -smtpServer smtpServer.com

Or to send each attachment separately:

foreach ($attachment in $attachments)
{
	Send-MailMessage -From "recipient@target.com" -To "sender@source.com"  -subject "Test" -smtpServer smtpServer.com -attachments $attachment
}

2 Feb 2012

My Personal Goals for 2012

After reviewing my goals for last year, it is time to reveal my goals for 2012:

  1. Reduce my weight to under 70 kg.
Lose weight now

Over the past few years, my weight has gradually crept up. With a tagline like “will code for cake”, how could my weight not increase?  As a software developer, my job is sedentary, and due to a chronic knee injury, my running days are over.  But this year, I’m going to lose the middle age paunch, and get back in shape.  I’m currently weighing in at 75 kg; back in my University days, when I was running and climbing daily, I weighted 68-69 kg.  I’ve already starting looking seriously at my diet, and I am exercising daily.  You can follow my progress by checking my bodyweight log – I update it daily.

  1. Release a mobile application and a web application.

Over the past few months, I’ve been pretty disheartened about my career in general, and about programming in particular.  After taking some time to reflect on this, I realised it was for a very simple reason – I wasn’t doing any serious coding.  At work, I’ve spent the last 3 years working with SharePoint.  This isn’t the place for a Zed Shaw-esque rant on SharePoint development – suffice to say that the SharePoint isn’t the most stimulating platform to work with, and could definitely count as one of the most frustrating.  In particular, I’ve spent the past two months configuring SharePoint demos, as opposed to actually coding.  At home, I’ve haven’t done in serious coding on personal projects in far too long.

To get my passion for programming back again, I am going to start following Scott Hanselman’s advice and start doing more.  In particular, I will stop watching TV in the weekday evenings, and start work coding my personal projects.  As well more coding, I will be learning a new language – at the minute I'm still deciding whether to learn Python or Ruby. But my first project will be a Android application.  More news to follow soon!

Android Logo
  1. Save 30% of my net income (in addition to pension contributions).

This follows on from my goal to increase my saving to 20% last year.  In the event, I saved 18.76% of my salary in 2011.  To increase my savings to 30% will be a major challenge, but one that will be useful to attempt, even if I fall short of the actual target.

Save Money Vacation

The three goals above definitely reflect the lessons I learnt from last year’s goals.  The new goals are:

  • Limited in number and scope – I’ve only got limited time and attention to focus in specific problems. So I need to focus on a small number of goals that can give the most benefit.  That is the main lesson form one of the best books I read last year – The Power of Less
  • SMART.  I (and for goals 1 and 2, you!) will be able to track my progress.

Hopefully, I will successfully achieve all of my goals – but even if I don’t, I intend to have fun trying!