I was pair programming with James Brundage, former member of the PowerShell team and  founder of Start Automating (a PowerShell automation company).

We were working on a PowerShell script and in the output pane he did something like this.

$psISE.CurrentFile.Editor.Text = ps|out-string

Super useful! Here is is a a general purpose PowerShell function, now in my ISE $Profile.

You’ve run into the scenario

You’re in ISE, you’re in the output pane and you want to read an about topic. You type in help about_jobs and result just flies by. Then you start scrolling.

HelpAbout

A Great Alternative

You could pipe this to clip, which copies the result to the clipboard, then do a File|New (Ctrl+N) and then paste the results.

A bunch of steps you can do without.

Instead try, Send-ToISE.

It keeps with the philosophy, think, type, get. You can work in the output pane, figure out what you need and then pipe it to Send-ToISE.

SendToISE

Get the Script

Here’s the PowerShell script, give it a whirl.

function Send-ToISE {            
    param(            
        [Parameter(ValueFromPipeline=$true)]            
        $TargetContent            
    )            
            
    Begin   { $targetOutput = @() }            
            
    Process { $targetOutput += $TargetContent }            
            
    End {            
            
        $Editor = $psISE.CurrentPowerShellTab.Files.Add().Editor            
                            
        if("$TargetOutput".Trim().Length -eq 0 -and             
            $TargetContent -isnot  [object[]]) {            
            
            $Editor.Text = "# Created $(Get-Date)"            
        } else {            
            $Editor.Text = ($targetOutput|Out-String) -join "`r`n"            
            $Editor.SetCaretPosition(1, 1)            
        }            
    }            
}

{ 0 comments }

So once I got the Atom Editor, the runner and  PowerShell syntax highlighter up and running (see PowerShell and The Github Atom Editor), I of course wanted more automation.

After editing a PowerShell script, I wanted to press F5 and have Atom save it and run it. The out of the box implementation requires Ctrl-Shift-P (brings up the palette) then type run and then press enter. Plus, the current version of the atom-runner does not save the file (note: A PR was merged in the repo for this feature and should be published soon).

Overall, this was a good exercise. It’s gets you familiar with several aspects of the Atom Editor and its programmability. Namely:

  • init.coffee
  • keymap.cson
  • Coffee script programming

~/.atom

Change directory here and you’ll see the files that need editing.

init.coffee

This file gets called after the Atom Editor initializes. I added the below code.

I create a command (custom:runner), get the active editor, call the save method (saves the content of the file) and then I called the atom runner. To call a Command Palette command from code, you can use atom.workspaceView.trigger and give it the name of the command as a string.

atom.workspaceView.command ‘custom:runner’, ->
  editor = atom.workspace.getActiveEditor()
  editor.save()
  atom.workspaceView.trigger ‘runner:run’

keymap.cson

Here, we wire up the function key f5 (NOTE: it is case sensitive) to the new command.

‘.workspace':
  ‘f5′: ‘custom:runner’

One of the things I like about the runner is it spins up the script as a separate process. For example, I can have a PowerShell while loop that outputs the time running, and Atom still operates, editing files etc.

{ 0 comments }

Yet another editor. Easy to install, run and start customizing.

At GitHub, we’re building the text editor we’ve always wanted. A tool you can customize to do anything, but also use productively on the first day without ever touching a config file. Atom is modern, approachable, and hackable to the core. We can’t wait to see what you build with it.

Install & Configure

The Atom Editor

Atom from Chocolatey (cinst Atom). PowerShell v5.0 preview ships with an early version of OneGet, which has a Chocolatey package provider, but it fails to install the Atom editor.

The Atom Runner

The Atom Editor comes with the Atom Package Manger (apm). With it, you can install more packages. The first one is the atom runner.

image

Configure The Runner

Edit the config.cson file and add these three lines (note: this is 32bit PowerShell):

‘runner':
  ‘extensions':
    ‘ps1′: ‘powershell’

image

The PowerShell Syntax Highlighter

Atom has a package manger, apm, use it to install the PowerShell syntax highlighter.

image

More Atom Packages

Here is the web page, https://atom.io/packages.

image

PowerShell and Atom Editor in Action

From PowerShell, type atom and press enter.

image

Add some PowerShell 1..5 | % {$_ * 2} and save the file (i.e testAtom.ps1).

image

Next, press Ctrl+Shit+P and type r

image

Then, press Enter

image

Wrap Up

  • We installed the Atom Editor
  • Then, installed two packages with apm. Atom-Runner and Language-PowerShell
  • This enabled syntax highlighting and the ability to run PowerShell scripts in the editor

These are the early days but the editor is looking interesting and worth keeping an eye on.

Day one, in very little time, PowerShell integration was up an running.

Bonus

Steve Murawski, Chris Hunt and I were tweeting about running 64bit PowerShell, Pester Tests and PowerShell snippets.

64 bit

‘runner':
  ‘extensions':
    ‘ps1′:’c:\\windows\\sysnative\\windowspowershell\\v1.0\\powershell.exe –file’

Running PowerShell Pester Tests

‘runner':
  ‘extensions':

    ‘Tests.ps1′:’c:\\windows\\sysnative\\windowspowershell\\v1.0\\powershell.exe -command Invoke-Pester -path ‘

Atom Snippets

Atom PowerShell snippets on GitHub.

{ 3 comments }

Jeffrey Snover, creator of PowerShell, re-tweeted a tweet and added “more people should be doing this”.

The tweet was about a post using Update-TypeData to drive the solution.

Date Time Dimension In Action

It Got Me Thinking

Back in the day when we did dimensional analysis, we would want to take a date and break it down into parts, Month, Day, Year, WeekOfyear, etc. This enabled us to answer questions like, how many items were sold in the 23rd week of a particular year. Or, how many were sold on a Wednesday.

In the past, when I needed this date/time granularity, I would whip up some PowerShell script to calculate these elements of from Get-Date. I’d squirrel them away in scripts, profiles and modules.

After seeing the re-tweet about Update-TypeData, I figured it was time to add a new property to the System.DateTime type, calling it DateTimeDimension.

Here is the simplest way to get the the DateTimeDimension. It returns a PowerShell object with propertues

image

Scaling up

Here, we can look out at the next 10 days from today and get all the details on a date just by calling the single property DateTimeDimension.

image

And Of Course

Since we’re working in PowerShell, we can save this to a CSV file.

image

We can also convert the objects produced by DateTimeDimension by piping it to ConvertTo-Json.

image

Building The DateTimeDimension Property

The meat of the following is the scriptblock passed to the –Value parameter, it is standard PowerShell with a little tweak, using the $this automatic variable. $This refers to the object being extended. In our case, it is the Get-Date.

We gather together all the key elements of the dimension (Month, Day, Year, DayOfWeek). This already exists on the object. We then calculate the Quarter (using a scriptblock) and WeekOfYear (using a VisualBasic .NET component).

Update-TypeData -TypeName System.Datetime ` -MemberName DateTimeDimension -Force ` -MemberType ScriptProperty -Value { $Quarter = { param([datetime]$targetDate) switch -Regex ($targetDate.Month) { "^1$|^2$|3" {1} "4|5|6" {2} "7|8|9" {3} "10|11|12" {4} } } Add-Type -AssemblyName Microsoft.VisualBasic $fdow=[Microsoft.VisualBasic.FirstDayOfWeek]::Sunday $fwoy=[Microsoft.VisualBasic.FirstWeekOfYear]::Jan1 $woy=[Microsoft.VisualBasic.DateAndTime]::DatePart("ww", $this, $fdow, $fwoy) [pscustomobject]@{ Month = $this.Month Day = $this.Day Year = $this.Year Hour = $this.hour Minute = $this.Minute Second = $this.Second DayOfWeek = $this.DayOfWeek DayOfYear = $this.DayOfYear Quarter = &$Quarter $this WeekOfYear = $woy } }

{ 0 comments }


Adam Ralph created configr, Write your .NET configuration files in C#. It uses ScriptCS.

Following his lead, I created a way to do the same thing, but using PowerShell.

  • Create a .NET console application in Visual Studio (other project types are also supported)
  • Install ConfigPS from NuGet
  • Add a new file named the same as your project output file with a ps1 extension, e.g. ConsoleApplication1.exe.ps1 and in the file properties set Copy to Output Directory to Copy always
  • Add some configuration to the ps1 file e.g.
Add-ConfigItem Count 123
Add-ConfigItem uri [uri]"https://dougfinke.com/blog"

# Retrieve JSON from the Web
Add-ConfigItem json (Invoke-RestMethod www.whitehouse.gov/facts/json).url_title
  • Add some code to your project which uses the configuration, e.g.:
void Main()
{ 
    dynamic global = new ConfigPS.Global();

    var count = global.count; // case insensitive
    var uri = global.Uri;

    Console.WriteLine("Count: {0}", count);
    Console.WriteLine("Uri: {0}", uri); // GetType == Uri

    foreach (var item in global.json)
    {
        Console.WriteLine(item);
    }

}

Congratulations! No more XML! Plus, it’s way more powerful.

Fork It On GitHub

Star it, fork it or make a pull request – config-ps on github

Happy coding.

{ 2 comments }

This post, Apple’s Swift programming language inspired by Groovy, caught my attention and it got me thinking about PowerShell. When I first started playing with PowerShell, I knew it was a programmable as Ruby, Python and Perl. So it’s  natural to look at other languages like Groovy and now Swift for comparison.

Syntax for Lists and Maps

Here we see Swift and Groovy.image

Here’s how we do it in PowerShell.

Array

# PowerShell Array            
$shoppingList = "catfish", "water", "tulips", "blue paint"            
$shoppingList[1] = "bottle of water"

Hashtable

#PowerShell hash table $occupations = @{

"Malcolm"= "Captain"

"Kaylee" = "Mechanic"

} $occupations.Jayne = "Public Relations" $occupations["John"] = "TeamLead" $emptyMap = @{} $emptyList = @()

Closures

A closure as defined in Wikipedia “are functions evaluated in an environment containing bound variables.”

image

In PowerShell we call them ScriptBlocks.

This is a block of script code that exists as an object reference but doesn’t require a name. – Bruce Payette “Windows PowerShell In Action”

The expression in braces— { 3 * $PSItem } — is actually a scriptblock.

3 | ForEach {3 * $PSItem}

Here are the Where and ForEach cmdlets and two scriptblocks.

1..10 |             
    Where {$PSItem % 2 -eq 0} |             
    Foreach { $PSItem * 2 }

These are basic PowerShell examples. You can go deeper and do metaprogramming in PowerShell as well.

Named Parameters

PowerShell parameters (and parameter binding) are a key strength of PowerShell. Here we can see a comparison across all three languages.

image

function TriangleAndSquare ($size, $name) { }            
            
$triangleAndSquare = TriangleAndSquare -name "another test shape" -size 10

Safe Navigation and Nullable Types

The upcoming version of C# will get a safe navigation operator “?.” In the PowerShell example below, the script doesn’t throw an error when we try to access RoomCount because Residence is null.

image

$code = @"
namespace TryPS
{
    public class Person
    {
        public Residence Residence { get; set; }
    }

    public class Residence
    {
        public int NumberOfRooms { get; set; }
    }
}
"@            
            
Add-Type -TypeDefinition $code # Compile C# on the fly       
            
$john = New-Object TryPS.Person            
            
# Uncomment to see roomCount print            
# $john.Residence = [TryPS.Residence]@{NumberOfRooms=3}            
            
$roomCount = $john.Residence.NumberOfRooms            
            
if($roomCount)            
{            
    "John's residence has ${roomCount} room(s)."            
} else             
{            
    "Unable to retrieve the number of rooms."            
}

PowerShell has had these features for a while and it’s great to see these concepts in other languages and scripting environments. We are polyglots and this certainly helps grease the wheels as we try new languages and approaches to development.

{ 0 comments }

I was invited to the Techorama Developers Conference to give two talks on PowerShell. One titled “PowerShell for Developers” and the other “PowerShell in a DevOps Environment”.

It was a great conference. The organizers did a terrific job, the attendees were fantastic and the Belgium chocolate didn’t disappoint.

I’ll be speaking again, on PowerShell, at the Alt.Net meet up in New York City at the end of June.

14277058026_5c6fdf1d21_z

{ 0 comments }

Initial availability of a CTP for Windows PowerShell Desired State Configuration for Linux!

{ 0 comments }

The PowerShell Humanizer

by Doug Finke on April 13, 2014

in PowerShell

I started wrapping Mehdi Khalili .NET Humanizer HERE.

Humanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities http://humanizr.net

TryPowerShellHumanizer

{ 2 comments }

I’m working in Visual Studio and in one of the C# applications it writes hundreds of messages to the output window. Sometimes the messages I’m looking for are strewn across the log and I need do repeated finds to get to the details I want.

So I hit on the idea to copy the text from the output window. Now, instead of pasting it to a file or in a PowerShell string, I decided to search the clipboard directly. Here’s the function and a video of it in action

function Find-OnClipboard {            
            
    param(            
        [Parameter(Mandatory=$true)]            
        $pattern            
    )            
            
    Add-Type -AssemblyName System.Windows.Forms            
                
    [System.Windows.Forms.Clipboard]::GetText() -split "`r`n" |             
        Select-String $pattern                
}            

Video

Call to Action

Add this function to your PowerShell profile, copy your favorite text to the clipboard and find info quickly and easily in any PowerShell host.

{ 0 comments }