Use PowerShell
The Shell Is Calling
The Shell Is Calling
Jan 6th
PowerShell Version 3 introduces the concept of Default Parameter Values.
This allows you to specify a value for one or more parameters for one or more commands.
To implement this, you need to populate a new hashtable – $PSDefaultParameterValues
Let’s look at some examples –
First off, we can specify the value for a parameter for a specific command. The pattern used for the hashtable entries is “NameOfCommand:NameOfParameter” = “ValueOfParameter”.
(I’m stealing some of these examples from the samples provided in CTP1.)
$PSDefaultParameterValues = @{"Get-Process:Name"="powershell"}
Get-Process
Get-Process e*
With that set, every time we run Get-Process and do not specify the Name parameter, the PowerShell runtime will stick “powershell” in for that value. A specified parameter will always override a default value.
Let’s go the other way and, instead of specifying one command, set a parameter value on all commands (that have that parameter.
$cred = Get-Credential mydomain\mydomainadminaccount
$PSDefaultParameterValues = @{"*:Credential" = $cred}
This would provide your $cred to any Credential parameter.
We can also use wildcards to match multiple commands.
$PSDefaultParameterValues = @{"*-AD*:Server" = 'MyDomainController'}
This would provide a default value to the Server parameter for any command whose noun started with AD (like everything in the ActiveDirectory module.
Since this is a hashtable, it can hold many different mappings –
$PSDefaultParameterValues = @{
"*:Credential" = $cred
"Get-Process:Name"="powershell"
"*-AD*:Server" = 'MyDomainController'
}
To turn off DefaultParameterValues (without removing everything you have set up), you can set a key “Disabled” equal to $true.
$PSDefaultParameterValues = @{"Disabled" = $true}
This concludes our brief look at DefaultParameterValues for today.
Go grab Version 3 CTP2 and give it a whirl…
Jan 6th
A question came up about the behavior of Import-Module (in the context of this interesting discussion of whether module authors should provide aliases), especially with Version 3 and the auto-loading of modules (what’s that?).
Does the auto-loading of modules in PowerShell Version 3 use Import-Module behind the scenes? If it does, can we use default parameter sets to control what types of things are imported?
So, it turns out that Import-Module does get called behind the scenes and a default parameter set (new feature) can be used to customize the import of new modules.
$PSDefaultParameterValues = @{
"Import-Module:Alias"=@()
"Import-Module:Function"='*'
"Import-Module:Cmdlet"='*'
"Import-Module:Variable"='*'
}
Get-Module
Get-BitsTransfer
Get-Module
This example (when used in PowerShell V3) will (from a base PowerShell session) show you what modules are loaded, attempt to run the Get-BitsTransfer command, and then show you what modules are now loaded (should include the BitsTransfer module now). Since we’ve provided an empty array to the Alias parameter for Import-Module, any module that is imported will import any aliases.
The problem comes in when you specify that only one of the four parameters (Alias, Function, Cmdlet, and Variable).
You might expect that when you specify one parameter (example Alias), that the other portions of the import (Function, Cmdlet, and Variable) would behave just like if you did not specify any of them.
Example -
Open a new PowerShell session (V2 or V3) -
Import-Module BitsTransfer Get-Command -Module BitsTransfer Get-Module
This will import BitsTransfer module and all attendant commands and functions. Note the ExportedCommands in the Get-Module output.
Open a new PowerShell session and try -
Import-Module BitsTransfer -Alias @() Get-Command -Module BitsTransfer Get-Module
This should import the BitsTransfer without any aliases (yes, I know BitsTransfer doesn’t have any aliases, but I wanted a module that most any Windows 7 or Server 2008 R2 machine would have – feel free to test with whatever module you desire).
This did import the BitsTransfer, but no commands or variables were imported. It only attempted to import aliases, and since we specified that aliases were to be an empty array, nothing was imported.
This is counter-intuitive and is not the experience we should have. Specifying one parameter should not change the default value of other parameters (from all to none in this case).
First of all, open PowerShell and try it! If you have one of the CTPs of Version 3, try it there. Also try it in V2 using Import-Module directly.
Then go to Microsoft Connect and vote up https://connect.microsoft.com/PowerShell/feedback/details/716857/module-partially-loads-with-import-module.
Jan 6th
PowerShell V3 includes a new “feature” – Auto-loading of modules.
Module discovery has been updated to make the exported commands for modules that are not loaded visible in a PowerShell session.
In Version 2, if you run Get-Module on a module that is not loaded but in your PSModulePath, you’ll get some metadata about the module, but nothing about the ExportedFunctions, ExportedCmdlets, ExportedAliases, or ExportedVariables.
Version 3 changes this, allowing Get-Module to retrieve information on all the exported features of the module.
This enables tab completion to complete the names of commands from modules that are not loaded. It also provides information to the PowerShell runtime on where to get the command information from, if the module is not loaded.
So, in Version 3, if you run a command from a module that is not loaded, the runtime will search your PSModulePath for the first command that it can find that matches that name and load the module that command is in for you.
I really don’t care for this feature. I like to be in control of what module I import. The order in which modules are automatically imported depends on your PSModulePath. You don’t get to pick what the order is… User specific PSModulePath entries are first, then machine specific PSModulePath entries. This can cause a host of unexpected problems when there are command name collisions.
For example, the new Hyper-V cmdlets for Windows 8 cannot manage down-level Hyper-V machines, so you might need James O’Neil’s Hyper-V module from Codeplex. Both modules have Get-VM. Since James’ module will be in my user PSModulePath (most likely), unless I specifically load the Windows 8 Hyper-V module, running Get-VM will always load James’ module.
Jan 3rd
I’m so excited for 2012, personally and professionally. I started the year with a great honor, I was awarded a Microsoft MVP award for PowerShell.
I started in IT in 2006 as the IT guy for a municipal police department. It was the first such full time position the department had. I immediately became responsible for a public safety network that needed to be operational 24/7. This required me to deal with a lot of intermittent issues or requests and I quickly saw that I needed some tools to get my job done well.
I looked around and found out that the *NIX guys had it pretty well covered with shell scripting, Perl, Python, TCL, sed, awk, etc.. I went looking for the Microsoft equivalent. I found Python and started doing some scripting with that. I loved the syntax and structure, as well as the availability of an interactive interpreter. The biggest pain was in dealing with the COM layer interactions. I explored C# and began to dabble with that as well.
And then I found PowerShell. I’ve been a PowerShell fanatic since the day I discovered it. It was a shell language. It had a scripting capability. I could extend it with .NET and C#. It worked with WMI and COM in a much more interactive manner and I didn’t have to go through some of the hoops that I had to with Python. It was also a Microsoft product (and eventually was available through Windows Update or with newer OSes in the box), which made it easier to deploy (policy-wise and distribution-wise).
Since that point in early 2006, I have been pushing PowerShell to help in all of the varied environments I’ve found myself in. I’ve become a speaker and a trainer and love sharing the capabilities of PowerShell and seeing others find value and make their work easier (or even possible).
I never would have been awarded this without the ceaseless lobbying of Doug Finke and the great interactions I’ve had with various members of the PowerShell team. I know a number of other PowerShell MVPs also were vocal in nominating me (forgive me if I forgot anyone), including Shay Levy, Marco Shaw, Aleksandar Nikolic, and Ravikanth Chaganti. I also had some great support from some of the Clustering MVPs (like Mike Steineke) and team (thanks Rob). Last, but not least, I’ve had great support from my local DPE team. Our local Developer Evangelist, Clark Sell, has never stopped encouraging me in spreading my thoughts on PowerShell and the development of a unified management API to .NET developer groups in our region (and further via his podcast). Our local IT Pro Evangelist, Brian Lewis, has been a stalwart supporter of both user groups we have going in the Milwaukee area, the Greater Milwaukee Script Club and the Greater Milwaukee IT Pro User Community.
I want to thank you, the readers of my blog, the attendees of my script club or IT Pro user group, and any of the various attendees of talks I have given. Thank you for allowing me to share a bit of my experience and thoughts with you and I can’t wait to see where this year goes (PowerShell V3 is on the horizon!!!).