Friday, June 28, 2013

How to throttle workflow activites in Powershell V4

With the release of Powershell V4, there is a new interesting feature concerning the use of Workflows: the ThrottleLimit property. Until now, there was a fixed hard limit to 5 concurrent activities when a workflow was started with the -parallel switch. This limitation was largely discussed by Jeff Wouters on his blog a few months ago. Jeff also took the time to develop a cool workaround.

Since the throttling of threads has been now built-in inside Workflows, I decided to give it a try.

I wrote a small Throttle-Me workflow which accepts an integer parameter and passes it to 'foreach -parallel'. Inside the foreach block I added two commands. The first one shows the value of a counter and the second one the current time in the form hh:mm:ss. This kind of output makes it easy to understand the way the ThrottleLimit property works because the current time is showed in groups the size of the ThrottleLimit parameter.

Let's start to have a look at the code (it's just an easy example wrote for this purpose, and, to be honest, I re-used part of the code which I saw on a recent Mike's post)
workflow Throttle-Me {

[cmdletbinding()]
    param(
        [int]$ThrottleLimit = 5
        )

foreach -parallel -throttlelimit $ThrottleLimit ($n in 1..5){
   "Working on $n"
   "{0:hh}:{0:mm}:{0:ss}" -f (Get-Date)
   }

}
If we call the Workflow with the limit set to 1 here's what we get:
throttle-me -throttlelimit 1

Working on 1
11:10:21
Working on 2
11:10:21
Working on 3
11:10:21
Working on 4
11:10:21
Working on 5
11:10:21
As you can see, one thread is executed at the time and each group of results (counter + date) is returned before the following thread starts.

If we change the limit value to 2 we get:
throttle-me -throttlelimit 2

Working on 2
Working on 1
11:11:38
11:11:38
Working on 3
Working on 4
11:11:38
11:11:38
Working on 5
11:11:38
Here two threads are started in parallel and the output contains two groups of results. The only exception is the last thread which comes alone for evident reason.

Same with the Throttlelimit set to four:
throttle-me -throttlelimit 4

Working on 4
Working on 3
Working on 2
Working on 1
11:12:16
11:12:16
11:12:16
11:12:16
Working on 5
11:12:16
Or to five:
throttle-me -throttlelimit 5

Working on 5
Working on 4
Working on 3
Working on 2
Working on 1
11:12:47
11:12:47
11:12:47
11:12:47
11:12:47
Now you aks what is the limit of concurrent runnable threads, and, while the real answer depens on your hardware configuration, the theoretical answer is given by the type of value the ThrottleLimit property accepts: Int32.

The largest possible value of Int32 is 2147483647, so if we run it with an higher value we get:
throttle-me -throttlelimit  2147483648

throttle-me : Cannot process argument transformation on parameter 'throttlelimit'. Cannot convert value
"2147483648" to type "System.Int32". Error: "Value was either too large or too small for an Int32."
At line:16 char:29
+ throttle-me -throttlelimit  2147483648
+                             ~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [throttle-me], ParameterBindingArgumentTransformationExceptio
   n
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,throttle-me

In any case take the time to measure the load of, say, 10 threads and see how your hardware reacts. Know that the reaction will depend on what you asked your workflow to do inside the foreach block.

That's all for the ThrotteLimit property. I will come back on Workflows in Powershell v4 in a future post.

Wednesday, June 26, 2013

My powershell quest for the perfect one-liner

After winning the Advanced section of the 2013 Scripting Games, Mike had the good idea of re-gifting one of the his prizes and started off a competition where his readers were tasked with the writing of the shortest possible one-liner to returns a list of PowerShell cmdlet names that don't have repeating characters in them.

I published a 24-chars-long answer which has just been chosen by Mike as shortest answer. Therefore I suppose it is a good idea to detail here the way I proceeded.

As you know, the Get-Command cmdlet gets all commands that are installed on your computer, including cmdlets, aliases, functions, workflows, filters, scripts, and applications. So I was going to use this cmdlet to retrieve all the others. Fine. Now what I wanted was the shortest possible alias for this cmdlet. To find it I went this way:
PS C:\> Get-Alias | ? {$_.Definition -match "Get-Command"} | Sort -Property length
which returned:
CommandType     Name   ModuleName
-----------     ----   ----------
Alias           gcm -> Get-Command
Just one alias was returned, but three chars long! I couldn't ask anything better than this!

New parameters in Powershell v4

I have just finished installing my first Windows 2012 R2 Preview and rushed to see what modifications those smart guys have made to Powershell cmdlets and parameters. In fact, as you may have already heard, the last version of Redmond's operating system comes with Powershell V4 (and a new fish as loader logo):

New Windows 2012 R2 preview logo

Powershell v4!!!
To find out the new parameters in v4, I recycled this good old script by Shay Levi and modified a couple of variables to match a compare between v3 and v4 instead of a compare between v2 and v3.

The result I got show that a PipelineVariable has been added to most of the cmdlets. And the following new parameters have been added too:

Get-Module (!)
FullyQualifiedName (+)

Get-Process (!)
IncludeUserName (+)

Get-PSSessionConfiguration (!)
Force (+)

Remove-Computer (!)
Workgroup (-)
WorkgroupName (+)

Write-Output (!)
NoEnumerate (+)

Unfortunately the help articles on Technet haven't been updated yet, so a little bit of investigation must be done before understanding how to properly use some of those parameters, such as FullyQualifiedName or NotEnumerate. Some others are more straightforward (such has the new excellent parameter IncludeUserName for Get-Process).

Tuesday, June 18, 2013

Copying output to clipboard with Clip.exe

Yesterday I run across a wonderful little utility I had never heard of and I wanted to share it with you. The name of this tiny MS-DOS utility is Clip and what it does is paste what comes down the pipeline to the Clipboard.

Here's how to use it. Just fire a Command Prompt and type whatever command you want to redirect to clipboard followed by a pipe (|) and the 'Clip' command:
  • dir c:\windows | clip
  • ipconfig /all | clip
  • netstat -an | clip
  • echo copy this to clipboard for me | clip
Clip is available on any recent Windows version out-of-box and has no dependency. So it doesn't rely on Perl nor on Powershell as others stated.

It can be used from a Powershell environment though:
  • PS C:\> Get-Process | clip
  • PS C:\> Get-Service | clip
  • PS C:\> Import-Module activedirectory
  • PS C:\> Get-ADComputer | clip
Powerful, isn't it? What it does from a Powershell point of view is to take the output out of the pipeline and put it in the Clipboard. So if we pipe the Clip command to Get-Member to see what kind of object is passed, we see that there is none:

PS C:\> Get-Service | clip | Get-Member
Get-Member : No object has been specified to the get-member cmdlet.
At line:1 char:32
+ Get-Service | clip | Get-Member <<<<
    + CategoryInfo          : CloseError: (:) [Get-Member], InvalidOperationEx
   ception
    + FullyQualifiedErrorId : NoObjectInGetMember,Microsoft.PowerShell.Command
   s.GetMemberCommand

This is the same thing that happen with Write-Host, where no object makes it to Get-Member:

PS C:\> Get-Process | Write-Host | Get-Member

That's all for Clip!

Monday, June 3, 2013

Powershell Scripting Games are almost over

The 2013 Powershell Scripting Games are almost over. I have just posted my last script for provisioning Windows 2012 Core Server virtual machines. I am quite happy with the script I have made, though what's most important is the occasion I have been given to learn really a lot of stuff I was not aware of. It's been also very exciting to read other people submissions, compare ways of doing, keep track of all the comments, either on Twitter or on the so many blogs out there. I will come back to analyze my submissions for these games in a few days. For the moment I will focus on commenting others people submissions, waiting for the names of Event 6 winners to be unveiled.
Related Posts Plugin for WordPress, Blogger...