Category Archives: Snippets

Little chunks of code

Friday, Friday. Gotta get down on Friday

A few of you might have spotted this via the Octopus Deploy June newsletter.

Friday

You might be wondering how it’s done, as at least one person has requested via Twitter. Well wait no longer. Here’s how it’s done.

What you’re looking at is a Slack notification from Octopus Deploy, featuring a little image that’s been doing the rounds on Twitter. It exists already as a Capistrano template, and I figured it wouldn’t be too hard to do in Octopus. Continue reading →

On Warmup Scripts and HTTP Methods

So I’m rewriting our venerable GuyGarvie IIS warmup script at the moment. This script started life as a way to warm up a very big .NET application on IIS6 using a list of URLs. Guy would simply hit each URL in turn with a GET request, checking the status thereof and returning an error if a significant number returned a non-200 status.

But Guy is terribly slow. And his list of URLs is full of legacy pages, broken links, duplications and general horror. And the application he warms up has moved on.

For this reason, I’m in the throes of rewriting him, converting his URL list from XML to JSON, cleaning it up and trying to tweak his speed, maybe parallelising him a bit too. And I have called him LiamFray, for reasons explained in the footnote. Continue reading →

PowerShell quickie: Setting IIS App Pool IdleTimeout

I just did this and was frankly awash in a sea of misinformation, so here’s how it’s done.

$ValueToSet = 40
$AppPoolPrefix = "*"


$appPools = gci IIS:\AppPools | ? {$_.Name -like $AppPoolPrefix}

$appPools | % {
    $currentTimeout = $_.processModel.IdleTimeOut
    if($ValueToSet -ne $CurrentTimeout.Minutes)
    {
        $_.processModel.IdleTimeout = [TimeSpan]::FromMinutes($ValueToSet)
        $_ | Set-Item 
        Write-Host "Set" $_.Name "to" $_.processModel.IdleTimeout 
    }

}

What are the gotchas here?

Well one, just calling Set-ItemProperty does nothing but apply your change to an in-memory copy of the object. Not the object itself. Forget that solution

Second, you need to pass in a timespan object, not merely a straight number, or you’ll get unexpected results when it tries to set the timeout in ticks

Third: Do not forget the Set-Item call, or you’re utterly lost.

And that’s about it.

[update: I forgot to say, include:

Import-Module WebAdministration

At the start. I don’t have to, because my servers ipmo that module in their PowerShell profiles. But you’ll need to.]

 

Snippet: Extending Connect-MSTSC for fun and profit

If you’ve ever come across Jaap Brasser’s Connect-MSTSC script, you’ll know it’s a pretty cool script. If you have a cloud service such as AWS, and you haven’t leveraged this script in conjunction with Get-EC2PasswordData, then frankly you’re doing something wrong.

I’ve had several variations around this script in our AWS utility script for a while now. There’s Connect-EC2Instance, Connect-RobotArmyv2Group and a few other variations. And there’s the one I put together today, which demonstrates a couple of things, so I thought I’d share

  1. Using Filters to find EC2 instances with particular extended properties
  2. Leveraging open-source code to make your life exponentially easier.

First of all, filters. If you do a Get-Help on Get-EC2Instance, you’ll see the filter property prominently advertised, but what you won’t immediately see is how to use it. What -Filter expects to be handed is an object array of type Amazon.EC2.Model.Filter.

So let’s have a look at what that is

New-Object -typeName Amazon.EC2.Model.Filter | Get-Member 

   TypeName: Amazon.EC2.Model.Filter

Name        MemberType    Definition
----        ----------    ----------
Value       AliasProperty Value = Values
Equals      Method        bool Equals(System.Object obj)
GetHashCode Method        int GetHashCode()
GetType     Method        type GetType()
ToString    Method        string ToString()
Name        Property      string Name {get;set;}
Values      Property      System.Collections.Generic.List[string] Values {get;set;}

OK, so it expects a Name/Value or Name/Values structure. That’s pretty easy to create in an ad-hoc fashion, like so

@{ Name = "private-ip-address"; Values = "10.123.26.144" }

So, we can use this to find an instance with a given IP address, or a given tag, or a given keypair. There’s a whole list of filter properties in the detailed Get-Help output for Get-EC2Instance. So let’s put this together with Get-EC2PasswordData to give us a simple script that will find the Admin password and connect to an instance immediately

Function Connect-ByIp
{
param
(
  $ip
)

  $instance = Get-EC2Instance -filter @{ Name = "private-ip-address"; Values = $ip }
  $instanceid = $instance.RunningInstance.InstanceId
  $password = Get-EC2PasswordData -InstanceId $instanceid -Decrypt -PemFile \\tsclient\c\pemfiles\keypair.pem 
  Connect-Mstsc -ComputerName $ip -User Administrator -Password $password
}

And there you have it. A valuable script now has added value as an AWS tool. Win.

So you just typed something epic…

… and you want to save it for posterity.

You know what it’s like, you’re prototyping something at the PowerShell command line, and it’s getting a bit complicated. It’s the greatest one-liner in the history of PowerShell, nay! Scripting itself! You’ve been honing this for the last two hours. It’s got fifteen Cmdlets strung together in a giant pipeline, with selecting and sorting and all manner of wizardry. It’s pretty damn awesome.

And you think “Hey, I should be saving this for later re-use or something”

You could copy it out of the host with careful mouse drags, or you could take a screenshot, or you could laboriously re-type it. Except they’re all boooring. And anyway, this one-liner returns such a massive swathe of output that your last command has gone shooting off up the screen somewhere and you can’t find it just by scrolling. And you could always hit the up arrow and everything but who cares? That’s not cool. There has to be a cooler way.

Consider this

Get-History | Select-Object -Last 1 | Out-File History.ps1

Or, better

Get-History | Select-Object -Last 1 -Property CommandLine | Out-File History.ps1

Or, better still

(Get-History | Select-Object -Last 1).CommandLine | Out-File History.ps1

Or, even better than that

(h | select -Last 1).CommandLine | Out-Clipboard

Yes, you can easily access your command history from PowerShell. And just like any other object, you can filter, sort and select or pipe it off to other Cmdlets for consumption. And if you were particularly nerdy and not at all obsessive-compulsive, you could encapsulate this into a cmdlet called “Save-History”, alias that cmdlet to “sh” and put the whole lot into your profile so it’s available onload, and you could save your fiddlings around at the command line for ever and ever and ever. But no-one would be that nerdy, right?

Function Save-History
{
    (Get-History | Select-Object -Last 10).CommandLine | Out-File $home\History.ps1 -Append
}

Write-Host "sh -> Save-History is available"
Set-Alias -Name sh -description "sh -> Save-History" -Value Save-History

 

My current favourite cmdlet is…

Out-Clipboard

Yes, it’s a humble wee cmdlet, but so powerful. So awesome.

When someone emails me a request to, say, check their IAM account’s group membership, I just run the following

Get-IAMGroupForUser -username <namehere> | Out-Clipboard

And then ctrl+v into the email and WE’RE DONE HERE NOTHING MORE TO SEE

 

 

(Oh, I forgot to mention – this command is part of the Powershell Community Extensions. You do have those, right?)

Quickie: Need to quickly reset your IAM user password?

We try to keep logins to the AWS console to a minimum here. Automate as much as you can with PowerShell and CloudFormation, we say. Stay away from the UI, we say. Use the Visual Studio Toolkit if you must, using your access keys, we opine.

Well inevitably sometimes we end up forgetting our passwords when we do need to log into the AWS web console. And we have to reset our passwords.

There are a couple of ways round this. One, you can go grovelling to a colleague who has admin rights and ask them to help, or you can use your valid access keys.

Initialize-AWSDefaults -StoredCredentials storedcrednamehere 
Update-IAMLoginProfile -UserName <username> -Password <password>

This of course opens a further can of worms over whether you’re handling your keys properly if you’re stupid enough to forget your password (as I was this morning), but let’s leave that for another day, because this is just a snippet. Let’s likewise leave alone the high-security practice of only granting yourself a password when you actually need it and then taking it away later. Because this is just a snippet.

Cheers!

Want to learn PowerShell quickly, easily and without getting bored?

Try my two favourite PowerShell learning resources, courtesy of Microsoft Virtual Academy. They’re getting on a bit, but good content ages slowly.

Getting Started with Powershell 3.0 Jump Start

and

Advanced Tools and Scripting with Powershell 3.0 Jump Start

They feature Geoff Snover, the father of PowerShell, and MVP Jason Helmick in a genuinely warm and entertaining back-forth and are an exemplar for how technical content should be presented online. Even if you don’t much care about PowerShell, I still think you should have a look.