Learn about PowerGUI on .NET Rocks!, dnrTV and RunAs Radio

During the past two weeks I’ve had the pleasure of sitting down and chatting with Carl Franklin, Richard Campbell and Greg Hughes of .NET Rocks!, RunAs Radio and dnrTV fame about PowerShell, PowerGUI and the Quest AD Cmdlets.  For those of you who don’t know, .NET Rocks! is an internet audio talk show about .NET and dnrTV is the equivalent in an internet screencast format.  Both of these are targeted at the .NET developer.  RunAs Radio is an internet audio talk show for IT professionals who work with Microsoft products.

I didn’t know what to expect from any of these interviews, but fortunately Carl, Richard and Greg are real pros at this and it was a real treat to chat with them.  I believe the end result is much better than what you get from the typical webcast or screencast because they ask the right questions and great conversation comes out as a result.

I was planning on blogging about this before any of these were posted, but these guys are really on top of things and to my surprise this morning I found out that Carl already posted the recording from dnrTV, so you can watch the episode #99 now.  It is simply called “Kirk Munro on PowerGUI”, and can be found here.  The .NET Rocks! and RunAs Radio sessions are not posted yet, but they should be later this week.  I’ll post an update once they are available.

Whether you’re interested in PowerGUI, PowerShell, .NET or working with Microsoft products in general, I encourage you to watch dnrTV and listen to RunAs Radio and .NET Rocks!  What a great way to spend your morning and evening commute in the subway, on the bus, or in your car (although please don’t watch dnrTV while driving your car…that’s just not a good idea; no matter how much you want to learn what PowerGUI and PowerShell can do for you, they won’t fix your car).

Thanks again to Carl and Richard for getting in touch with me and setting this up!  It’s been a great experience!

Lastly, if you’re interested in listening to a bi-weekly podcast that is specifically about PowerShell, you should also check out the PowerScripting Podcast.  The PowerScripting Podcast is hosted by Jonathan Walz and Hal Rottenberg and if you’re into all things PowerShell like I am, this gives you one more way to stay informed about PowerShell during the daily commute.

Thanks for listening!

Kirk out.

Technorati Tags: , , , , , , ,

Quest AD Cmdlets gone gold!

It’s official!

The Quest AD Cmdlets are now RTM!  And they’re still 100% free!  If you are doing any scripting with Active Directory and PowerShell, these cmdlets are absolutely indispensable.

You can download the RTM version here.

Note: The initial post of the RTM version still had “ReleaseCandidate” as part of the msi filename.  This is still the RTM release.  The filename will be corrected shortly.

Kirk out.

Technorati Tags: , , ,

Sometimes you just want a property

On the PowerShell newsgroup I often (really often) see users new to PowerShell getting stuck transitioning from the point where they have a set of objects to creating an array of the values of one of the properties on those objects.  For example, if you are using the free Quest AD cmdlets and you want to retrieve a list of group names to which a member belongs, you can do this:

(Get-QADUser “Poshoholic”).memberOf | Get-QADGroup | ForEach-Object {$_.Name}

This seems simple enough but many people get stuck going from a collection such as that returned by Get-QADGroup to an array of names such as that returned by the ForEach-Object cmdlet shown in this exanple.  The missing piece of knowledge is usually understanding how to use ForEach-Object to extract the member you want.  Also, even when you know how to use ForEach-Object, I find it a little inconvenient to use ForEach-Object with a script block just to pull out a property name, or to put brackets around part of a command so that I can access members on the result.  And I find myself doing this quite regularly in my PowerShell work.

To both save myself from having to use ForEach-Object or brackets when all I want is to invoke a member on an individual object or a collection of objects, and to share this convenience with others, I have created an Invoke-Member function that makes the one-liner I listed above a little more elegant and PowerShelly.  Here’s an updated version of the one-liner I used above, revised to use the Invoke-Member function:

Get-QADUser “Poshoholic” | Invoke-Member memberOf | Get-QADGroup | Invoke-Member name

This one-liner retrieves an AD user named Poshoholic and from that user it retrieves the memberOf member value.  That value contains an array of DNs for groups to which the user belongs.  For each of those DNs, the one-liner then retrieves the AD group object and once it has that it extracts the name of that group.

The Invoke-Member function can be used to invoke any type of member, including both properties and methods (e.g. Invoke-Member “Open()”).  It can also be used to invoke nested members (e.g. Invoke-Member parameters.parameter).  And it can take input from the pipeline or alternatively through the InputObject parameter.  When using the InputObject parameter, the object is passed in as one object, even if it is a collection.  When using the pipeline collections are passed into Invoke-Member one item at a time.

[Update] Since this was originally posted, Xaegr pointed out in the comments that the PowerShell team already had published a function on their blog that does this, and that he has modified that function to support multiple members.  You can find that blog entry here, and Xaegr’s modifications can be found in the comments in this blog entry.  The problem with those two implementations of the … function  is that they don’t support calling methods and they don’t support nesting members, both of which are supported by the Invoke-Member function.  I liked Xaegr’s idea to support retrieving multiple members at once though, which I think could be useful for simplified output of member values without member names attached to that output.  I also think it would be useful when working with certain datasets that have different members with the same type that you want to do something with in one pass through that data set, or when you want to execute multiple methods in sequence during one pass through a dataset.  I added support to the Invoke-Member function so that it would support multiple members as well.

Here is the updated source code for the Invoke-Member function as well as a script to create im and … aliases for the Invoke-Member function:

Function Invoke-Member {
    param (
        [string[]]
$name = $(throw $($(Get-PSResourceString -BaseName ‘ParameterBinderStrings’ -ResourceId ‘ParameterArgumentValidationErrorNullNotAllowed’) -f $null,‘Name’)),
       
$inputObject = $null
   
)
    BEGIN {
    }
    PROCESS {
       
if ($inputObject -and $_) {
           
throw $(Get-PSResourceString -BaseName ‘ParameterBinderStrings’ -ResourceId ‘AmbiguousParameterSet’)
           
break
        } elseif ($inputObject) {
            foreach ($member in $name) {
               
Invoke-Expression “`$inputObject.$member”
           
}
        }
elseif ($_) {
           
foreach ($member in $name) {
               
Invoke-Expression “`$_.$member”
           
}
        } else {
           
throw $(Get-PSResourceString -BaseName ‘ParameterBinderStrings’ -ResourceId ‘InputObjectNotBound’)
        }
    }
    END {
    }
}
if (-not (Get-Alias -Name im -ErrorAction SilentlyContinue)) {
    New-Alias -Name im -Value Invoke-Member -Description ‘Invokes a member of each of a set of input objects.’
}
if (-not (Get-Alias -Name-ErrorAction SilentlyContinue)) {
    New-Alias -Name … -Value Invoke-Member -Description ‘Invokes a member of each of a set of input objects.’
}

Note that this function uses the Get-PSResourceString function that I published recently in my Cmdlet Extension Library (you can read more about what this library contains here).  If you want to use the Invoke-Member function by itself, you will have to change the calls to Get-PSResourceString with static strings that you want to throw on error instead.  To simplify sharing the Invoke-Member function with the community I have added it to my Cmdlet Extension Library and uploaded the updated version to the PowerShell Community site.

Thanks to Joel Bennett for his article about writing functions that can also be executed in the pipeline.  I didn’t end up using Joel’s template as is because I wanted Invoke-Member to follow the model of other cmdlets that have the InputObject parameter, but it was my starting point before I went through numerous revisions and ended up with the final version shown above in the Invoke-Member function code.

Comments/suggestions are welcome and appreciated, as always.

Kirk out.

Technorati Tags: , , , , ,