With PowerShell V2 we can now get nearly all the functionality of the PowerShell engine that is available to Cmdlet developers that are using C#. Granted, if you haven’t written any Cmdlets in C#, you probably don’t understand the power that this brings, but trust me, its huge!
Here are just a couple things to think about as we start to build more industrial strength functions. We can do all kinds of cool things with parameters now. We can validate that the entry matches a regular expression. We can tell the parameter to accept a value from the pipeline. We can declare whether or not a parameter is mandatory or not.
In addition to tons of flexibility with parameters, we can also leverage the built in help for functions that we write. Rather than going on and listing every single feature, let me just give an example of what I am talking about.
Now here are some screen shots of how you can use this function, just like a Cmdlet in version 1.
In this first one, we first use the function with a parameter, and then in the pipeline.
In the function, we used the Begin, Process, and End Blocks, so we can do stuff before we send anything down the pipeline, then work on the pipeline objects, and then do anything else we need to do to wrap up. This is why you see the text “Beginning Pipeline” and “End of Pipleline".” This is for demonstration purposes only.
Because we declared that the number parameter is mandatory and we specified a help message, we get this great interactivity for only setting a couple attributes. PowerShell tells the user, “You forgot this mandatory paramter, and if you need help, type !? and you can see what the function author wants you to know about the parameter. Pretty flippin’ awesome!
And finally , of course we get the following when we type help get-evennumber because of all the great code commenting we did at the beginning of the function. Notice how nicely its formatted. It even automagically pulls all the parameters and their types for you in the SYNTAX section.
PowerShell CTP 3 is Released !
Merry Christmas from the PowerShell Team!
Graphical PowerShell, also known as the PowerShell Scripting Environment (ISE) can be customized using an object model.
There is a variable called $psISE in the ISE.
Last week I had the tremendous privilege of going to Redmond to work on a PowerShell project with the PowerShell team. Two colleagues and I represented one of several customers that came to the event.
What was so great about this event was that I was able to show the team what I was working on and they got to see how their product is really being used out in the wild. I was able to learn a lot about the new 2.0 features and implement them in my project with guidance from the PowerShell team.
Being able to finally put faces to names was a wonderful treat. The team is awesome. Hands down, it was the best MS event I have ever been to. Granted, I am a complete PowerShell junky, so for me, just being able to meet the team was fantastic.
What struck me most overall was their passion. I have seen Jeffrey talk and I know he cares deeply about his customers. He absolutely wants to make sure that his team is doing what is best for his customers. But what was so cool was that this passion goes deep throughout the entire team. From development, to test, to documentation, to UI design for ISE…Everyone on the team wants to make it as great as possible for us. These folks really REALLY care about what they are building, and it obviously shows. They have built a phenomenal product.
Needless to say, this was a wonderful opportunity and if anyone has a chance to meet the PS team, I would HIGHLY recommend it. They are great folks!
What struck me most overall was their passion. I have seen Jeffrey talk and I know he cares deeply about his customers and wants to make sure what they are doing is the right thing. But what was so cool was that this passion goes deep throughout the entire team. From development, to test, to documentation, to UI design for ISE…Everyone on the team wants to make it as great as possible for us. These folks really REALLY care about what they are building, and it obviously shows. They have built a phenomenal product.
I came across a situation where I needed a variable (lets call it $a) that I was using in my local PSSession to be available in my remote PSSession. Let’s try this and see what happens.
1: PS C:> "Hello $a"
Notice that $a was there locally but not when we tried to use it remotely in our scriptblock. Lucky for us, there is a –ArgumentList parameter that we can use with invoke-command. This looks promising.
Still no dice, but we are close. Turns out we need to declare $a as a parameter in our scriptblock.
And now we have it!
1: PS C:\> "Hello $a"
Modules in PowerShell, among other things, will allow code to be shared very easily within a community. One of the issues with scripts and dot sourcing right now is that we end up polluting our working session with a lot of variables and functions that we don't really need. These are helper functions and helper variables that are used by larger functions.
Modules solves this problem. You can create a module (Just name a PS1 script to .PSM1) and specify which functions/variables you want to export.
One way to think about this if you have a C# background is public vs private variables or methods in a class. The exported members are analogous to public methods.
You do this with the export-modulemember cmdlet at the end of your module. Notice that I have four distinct function in my module, test.psm1. However, I am only exporting the functions binn and foo. The other two do not show up when I call get-command. Note that when I call bar, it does indeed have access to foo.
BTW, cat2 is an alias I use for Lee Holmes' Syntax Highlighting script. Just wait til you see what else Modules can do, especially Module Manifests. With these we can set all kinds of pre-requisites for our scripts, versions, and a number of other things as well.
Out of the box in PowerShell, you cannot cast a string to a scriptblock.
1: 81# [scriptblock]"A String that can't be a SB"
3: cast from 'System.String' to 'System.Management.Automation.ScriptBlock'."
5: + [scriptblock] <<<< "A String that can't be a SB"
This is actually a good thing. To be able to take a string and arbitrarily execute it could definitely be a security risk. However, there are definitely times when you need to do this.
In my case, I am parsing a Windows Sharepoint list that has a set of ScriptBlocks and our code snippets that I need to execute. However, when I pull them from SharePoint, they are strings.
Using an old V1 method, you can use the following function to convert a string to a script block.
Below is a screen shot of using invoke-command with a string vs the scriptblock that we get back from this function.
As you know, Windows 7 (Demoed at PDC) has PowerShell enabled out of the box. Turns out there is a slightly easier way to do this in the new win7 build and it will very likely be here in CTP3 as well.
There is now a static method in the ScriptBlock class called Create().
So we can write a new V2 function (lets make it an advanced function for fun) using this new method.
Now with the ability to specify the [parameter] attribute and pass it in parameters like ValueFromPipeline we can easily pass in our string from the pipeline or directly via the parameter like we did in the V1 version.
For convert functions, we should use ConvertTo and ConvertFrom as the “verb”. I wanted to point this out and thank Osin because I completely acknowledge that I am guilty as charged and I think it is a BIG DEAL to stick with standards. Consistency is imperative as PS Adoption rates increase.