Blogroll

Search

Portable Powershell – Part 2: Roll your own, plus a challenge

June 19th, 2008 by Karl

UPDATE FEB 2010 We don’t need to rely on things like thinapp or app-v anymore. At ShellTools we have build our own Portable PowerShell framework. Its currently in Beta – see http://www.portablepowershell.com for more details.


Todays Blog entry is going to cover the HOW of how I put together my demos of Portable PowerShell. Tomorrow I’ll move back to clearly defining what I’d like to see from Microsoft. But before I get to the full details a little background:

Background

So what’s stopping PowerShell or practically anything from being portable? dependence on a particular file structure and the registry. Basically the technique I  “HOOK” apis so that whenever the process tries to call certain APIs (the filesystem and registry ones) the code in memory is changed to jump to custom code instead of the address of the DLL function export where DLL has been loaded. From there custom checks are done to see if its a file or registry setting to do with PowerShell, and if so the code delivers it up, as if it were there, even though its not.

This is a technique that as a programmer I have been doing for a long time. It involves a lot of assembler, historically being able to inject a DLL into a process and in memory rewrite the code, but it works great. The first time I worked out this technique as a programmer was back in the days of windows 95 which wasn’t unicode. I made an application that could enable Chinese and Japanese characters on english windows. Effectively I hooked the TextOut API, and if it was a process that had been chosen to say display in Japanese, and the font chosen was one that was chosen for this purpose then I custom drew the Japanese or Chinese Glyph otherwise I just called the real TextOut API call. Another technique when working on VisualJockey many years ago, I wanted to be able to pipe the output on a standalone graphics program into VisualJockey so we could do some video processing on it. The problem is that app drew to fullscreen directX itself, so I had to “hook” the directX apis, so that when it created the surface it didn’t make it fullscreen, and when it rendered it rendered to Texture instead of screen, and then some extra code to retrieve what it had rendered. Another Situation was changing a DB backend of an application without the Applications source, *simply* by hooking the ODBC apis (where we also could discover the password used). Another thing I used this technique for was to add some functionality to abandoned freeware that had no source code.

Fast forward to about 2002, Josua Honger , the main architect of VisualJockey, and also the Hippotiser (I could talk a week just about these amazing programs, the Hippotiser has gone on to become a huge sensation powering realtime effects for live T.V, large concerts, events like the nobel peace prize, broadway shows, and the worlds largest audiovisual setup- Love by Cirque de Soliel in Las Vegas)  were wanting to use the engine of VisualJockey to make a demoscene demo , without the copy protection , and in a portable manner (Demoscene demos aren’t allowed to install anything), and on top of that not scare the Green Hippo (who recently purchased the VisualJockey engine and didn’t want to risk it getting out and reused). We didn’t have time to roll our own solution so we found a rather recent product called Thinstall. Thinstall used the techniques mentioned about, but it stored all the files you choose in its own encrypted virtual file system inside one file – Just what we were needing. Thinstall in those days also was cheap enough for us, even though it was a hobby project, but as a young product it didn’t quite work fully with our VisualJockey because we used some interesting techniques anyhow, but I did gain a lot of respect for it, and for its author Jonathan Clark. Over the years I’ve played with it a few times for some hobby projects , but the cost went up and up and I couldn’t justify using it.

Fast forward to 2008, the complexities and risks of deploying and configuring applications have become a real pain point for many corporations and an abundance of solutions have tried solving this. Thinstall evolved its PR to target this market – and named it Application Virtualization, and most recently got acquired by VMWARE. (and renamed ThinApp) So now that there was a great beta to try. the scary thing is HOW EASY THIS WAS. I expected that I would have to spend many hours manually tweaking what to include/exclude – setting up the behaviour of the registry virtualization, but I had something done in 20 minutes, pretty much just following a few instructions. and Click next / next /next

HOW HOW HOW HOW HOW HOW HOW HOW

So I wanted to make 4 different versions of Portable Powershell

  • Powershell V1 (just powershell, don’t include dotnet 2.0 – thus dotnet 2.0 is needed to be installed on a machine for it to work)
  • Powershell V2 CTP2 (just powershell, don’t include dotnet 2.0 – thus dotnet 2.0 is needed to be installed on a machine for it to work)
  • PowerShell V1 (include the who dotnet 2.0 so it can run even where dotnet isn’t)
  • PowerShell V1 (include the who dotnet 2.0 so it can run even where dotnet isn’t)

The Key this is to have a Fresh OS to start from, so that you don’t miss any important files , and don’t get rubbish either, so the place to build this is most definately in a VM.

So what did i do?

  1. Predownloaded what was needed
    1. XP SP2 install CD
    2. VMWARE THINAPP BETA (plus free beta key)
    3. DOTNET 2.0 redistributable
    4. Powershell V1 for XP installer
    5. Powershell V2 CTP2 installer
  2. Setup the OS in a VM.
  3. Installed ThinAPP
  4. Made a snapshot of the VM
  5. started the thinapp process
  6. Installed dotnet 2.0
  7. Installed PowerShell V2CTP2
  8. Copied over PowerShell Analyzer
  9. Completed the thinapp process , and build the Portable EXE for my V2 with dotnet Portable Powershell
  10. Copied my portable powerShell off the VM
  11. Reverted the snapshot
  12. Repeated the process but for PowerShell V1
  13. Reverted the snapshot
  14. Installed dotnet 2.0
  15. Made a new snapshot
  16. repeated the process but just installing Powershell V1 (to make a smaller less heavy portable powershell that didn’t contain dotnet 2.0)
  17. reverted and repeated the process for Powershell V2

There there you have it, 4 different flavors on a Portable Powershell made in just a few hours. I can’t give them enough praise for how far Thinstall has come and how easy the process was.

Are there any other options?

Definately! Thinstall is not the sole player in this now “application virtualization” arena. The management , configuration and deployment has been bundled into apps and called “Application Streaming“. Citrix added Application Streaming, Symantec has Altiris, and Microsoft bought out SoftGrid. The “streaming techniques aren’t typically really portable since they have some sort of agent or client/server architecture but the interesting one in this mix is software, Which i think is now renamed Microsoft Application Virtualization or APP-V for short. You can read their blog here. Actually the release candidate was just released YESTERDAY.

With thinstall, I’m interesting what the pricing is going to be under VMWARE. When its in beta its definitely financially feasible for me to have my own personal portable powershell for personal use, but that’s probably not the case post RTM.

I didn’t have time to play with APP-V yet. SO MUCH CHALLENGE IS WILL SOMEBODY TRY TO VIRTUALIZE POWERSHELL WITH APP-V AND TELL US HOW IT GOES. I presume Microsoft will be more likely to allow redistribution of PowerShell through one of their own technologies ;)

Another cheap option I would challenge somebody is to try it in sandboxie , see if sandboxie is up to the job, as its very cheap, but i don’t know if it does full “portable”

Finally there is another way, that I might implement, and that is roll my own. I wouldn’t include the dotnet framework in this one (just too much work), but I can whip up a DLL in C++ and Assembler in no time to take care of powershell’s filesystem and registry needs. Of course I couldn’t redistribute portable PowerShell but I could make it into a small PORTABLEPOWERSHELLBUILDER.EXE app, that has a button that will build a portable PowerShell for you on any computer that has PowerShell installed in a similar manner to how BartPE or ReatogoXPE can build a bootable XP CD based on the files on a particular OS install.

Apart from the challenge of doing that, and doing some fun techniques that I’ve almost forgotten, and as a PowerShell tool vendor and partner of MS, I don’t want to do that. I want MS to allow PowerShell to be redistributed, in a portable manner, and if they can fit it into their schedule, do some minor reachitecture of PowerShell V2 to be naturally portable, but more on that in my next blog post.

Over and Out,

Karl Prosser / ShellTools

Technorati Tags: ,,,,

Posted in Bare Metal, Powershell, pscom | 14 Comments »

Portable PowerShell – v1 and v2 side by side – even on Server Core.

June 17th, 2008 by Karl

UPDATE FEB 2010We don’t need to rely on things like thinapp or app-v anymore. At ShellTools we have build our own Portable PowerShell framework. Its currently in Beta – see http://www.portablepowershell.com for more details.


So I’ve loved portable apps from time memorial and have valued making my own apps as portable as possible – XCOPY friendly. I’ve valued this over some fancy installer. But what about PowerShell? Why can’t PowerShell be portable. Its the sort of tool that begs to be portable. Admins want a power tool, like powershell to be portable, to be able to be run on any computer without installing anything (changing ,even contaminating the state of the computer). Admins don’t want to have to worry about installing prerequisites such as dotnet 2.0 everywhere and neither do I. I want something that can be self contained , where I can run PowerShell v1 and v2 side by side if I choose, and as a builder of PowerShell hosts, I want to be able to embed, or distribute the PowerShell runtime along with my app, just like I can with a multitude of dotnet libraries and components.

Well is this possible. Yes, I’ve done it. In this blog post I’ll show some screenshots and a video about it, and talk about the WHAT and the WHY, and try to whelm up some passion in the community to encourage Microsoft to allow the PowerShell engine to be redistributed freely, easily , and portably. I know that many people will ask me – Can I download this, and I have to say NO – because we don’t have rights from MS to redistribute PowerShell, especially outside of its official packages, but the good news is that you can make this yourself, but I’m not going to tell you HOW to until tomorrow, hoping that instead of running of to recreate your own personal PowerShell nirvana you might read the rest of my rant and join the movement for a Microsoft endorsed Portable PowerShell.

But before we proceed here is a screenshot:

servercore2

This beauty shows Server Core Enterprise – you can verify this isn’t a trick but is indeed server core by the operatingsystemSKU of 14 shown in the top window. (MSDN reference. ) Server Core does not have dotnet 2.0 (a prerequisite of PowerShell) installed and we haven’t applied any cool hacks or Russian reverse engineering  to get it working therefore we haven’t compromised the secure state of our servercore by installing any untested potential lasting security hole on it. We purely XCOPY across our files, or we can even run it off a USB drive. Another great benefit you see here is on the same machine we are running PowerShell V1 and V2 side by side. How many of us have had to set up a whole new machine or VM just to play with V2 CTP!!!!! and how many cough*cough have installed v2 on a production machine when we should have for lack of patience in setting up a dedicated v2 test machine?

So what are the features of this technique.

  • Fully Portable
  • versions that presume dotnet 2.0s preexistence (about 3MB to 10MB)
  • Versions that don’t need dotnet 2.0 at all (about 100MB)
  • Can run V1 and V2 side by side.
  • Can run on a machine with PowerShell already installed, and your portable version has its own execution-policy and other settings.
  • Can be packaged with SnapIns (so the SnapIns are portable also, no need to install or register them).
  • Can be used with a custom Host , so you can have a Portable PowerShell Plus or PowerShell Analyzer.

Here is a 3 minute video showing Portable Powershell v1 and v2 and PowerShell Analyzer running side by side on a virgin XP SP2 box that doesn’t have dotnet 2.0 preinstalled.

Portable PowerShell from karl prosser on Vimeo.

So now you are saying, GIVE THIS TO ME NOW. Sorry but I can’t but in my next blog entry within a couple of days I will tell you how you can roll your own Portable PowerShell.

Please leave a comment on this blog if you are in favor of Microsoft relaxing its redistributable rules when it comes to PowerShell. Technically PowerShell doesn’t have much to stop it being Portable. Its fully dotnet, and although its installed in windows\system32 directory that is more a “political” feature , earlier betas would install elsewhere, and technically it wouldn’t be hard to make it a control in VS.NET that a custom host could merge into their project and be fully portable. There are many many possible use-cases for such portable uses  (both from the perspective of admins as well as developers creating PowerShell enabled and powered applications in the growing PowerShell ecosystem). If MS can’t make any changes technically to make it as easy as i suggest in V2, can they at least GIVE FULL REDISTRIBUTABLE RIGHTS FOR POWERSHELL as they do things such as the SQL server client side report viewer control in VS.NET.

All in favor say so in a comment!

And come back for more in a day or two.

Over and Out,

Karl Prosser / ShellTools.

Technorati Tags: ,,,,

Posted in Powershell, pscom | 46 Comments »

generating a "PropertyBag" aka PScustomObject in C#

June 12th, 2008 by Karl

Based on the performance testing and work being done by myself , mow , Brandon Shell and others the question has come up what is the quickest way to generate a PSCustomObject, whether in script , on in C#, and how do you even do it in C#?

Some typical ways of doing in PowerShell have been either something like the following trick:

$a = 1 | select a , b , c , d

or with using the Add-member cmdlet as below:

$a | add-member -membertype noteproperty -name status -value done

however both are really slow. There is another way to do it in script, and that is directly with the PSobject, but still PowerShell (especially version 1) has a huge overhead when creating new objects with new-object but below is an example none the less.

$obj = new-Object system.Management.Automation.PSObject
$note = new-object System.Management.Automation.PSnoteproperty "karl" , "a value"
$obj.psobject.members.add( $note );

But if you really want to do speed, or if you have need to generate these objects in a cmdlet regardless of speed here is how you can do it in C#.

public static PSObject newPsCustomObject2()
        {
            //Creating a PSobject without any parameters in the constructor creates a PSCustomObjectg
            PSObject obj = new PSObject();
            //PSNoteProperties are not strongly typed but do contain an explicit type.
            obj.Properties.Add(new PSNoteProperty("age",24));
            obj.Properties.Add(new PSNoteProperty("name","jon"));
            //Alias allow you to cast one property as another as well as just plain aliasing
            obj.Properties.Add(new PSAliasProperty("ageasstring","age",typeof(string)));
            return obj;
        }

Some notes about the above, I didn’t show how you could add ScriptProperties or ScriptMethods yet as I wanted to keep it simple and not cover creating scriptblocks. Before I go lets performance test this baby compared to creating this in pure PowerShell.

So in the:

1) first corner we have creating the object with select-object, then setting the properties.(but we can’t set the alias)

2) Creating the object with new-object, then using add-member to add all the properties.

3) calling our static method above.

#select-object version
for($i = 0;$i -lt 50000;$i++) { $a = 1 |Select-Object age, name; $a.age = 24; $a.name = "john" }
#add-member version
for($i = 0;$i -lt 50000;$i++)
  { $a = new-Object psobject;
    $a | add-member -membertype noteproperty -name age -value 24
    $a | add-member -membertype noteproperty -name name -value "john"
    $a | add-member -membertype aliasproperty -name "ageasstring" -value "age" -secondvalue "string"
  }
#Our fast version
for($i = 0;$i -lt 50000;$i++) { $a = [snapinini.newobjecthelper]::newPsCustomObject2(); }

so we are creating 50,000 objects and the results are.

select-object 27.15 seconds.
add-member 118.79 seconds
C# method 1.9 seconds.

and i used to complain with the performance hit of a address lookup for a method in a C++ virtual method table!!

at worst the official add-member technique is over 60 times slower than calling C#, and thats not really RAW C#, thats still powershell invoking a C# method 50,000 times, and powershell managing a loop.

if fact just to test i added another test

$a = [snapinini.newobjecthelper]::newPsCustomObject3();

where newPSCustomObject3() moves the 50,000 loop to inside C#.. and here the speed is 0.95 seconds, so about half the speed of invoking the C# method from powershell each time – this speed difference I am happy with though. The PowerShell team seem to have done a good job of invoking C# methods quickly.

Another day I should investigate the speed of creating objects that have been created with the extended type system.

I’d love if somebody can run these tests in v2.

Also sometime soon I shall share a helper function you can use to quickly generate a PScustomObject with properties and values you specify in script.

-Karl

Posted in Bare Metal, Gotchas Etc, Powershell, performance, pscom, rant | 2 Comments »

Getting serious about performance in PowerShell.

June 12th, 2008 by Karl

I’ve spend a lot of time in the past looking at the performance of PowerShell but have never gotten around to blogging about it. However it has become quite a hot button among MVPs and others in recent days and we’ve been busy testing and comparing the speeds different techniques in PowerShell in both V1 and V2.

In V1 there seems to be extreme slowdowns when invoking cmdlet, functions, any type of scriptblock and when using the pipeline. If you write a one liner that is easy to read, very elegant, but uses a lot of “powershelly” techniques its performance is often terrible, compared to it you write it out as a longer script using more traditional imperative style with “C”ish loops as the like. This brings up the whole concept of what is cheaper and more valuable – CPU cycles that keep getting cheaper, or human time in writing and maintaining code – dynamic languages and especially shells will definitely answer that programmer productivity is more valuable, and thus performance can come second.(read about it in the context of python here.) However 59 millisecond average to call an empty powershell function on a dual core machine is pushing this truth to an absurdity. PowerShell should as a language should NOT be slower than BASIC on my Commodore-64 – an 1MHZ 8 bit machine.

Here is some background of where we are coming from. Brandon Shell Started it all here. And after we spend hours running tests and bantering about the subject on the #powershell IRC room on freenode, Mow covered some cool stuff here.

Basically the results of my tests showed that new-object is very slow in V1, but calling any CMDLET, even a simple C# cmdlet with one line of code is extremely slow, and about 30 to 50 times slower than calling that SAME  line of code from powershell as a static method on a C# assembly. Additionally if you take that 50 times faster static method call, and wrap in it a simple powershell function, you loose all your spend gains and its even slower than calling the new-object CmdLet.

The great thing from Mows tests is that in V2 it seems that on the language side of things, scriptblocks,functions and the pipelines have spend up drastically (in the magnitude of about 2000% to 3000%. And cmdlet invocation has spend up also, but is about 6 times slower than just calling C# static methods. GO V2 GO V2 , but is it enough?

Given that V1 is going to be important for a long time, I think that powershell scripters need to still try to script in a “PowerShelly” way, but when they determine that something really has to be performant , they need to know what workarounds they can do in PowerShell to speed things up, understanding where the bottlenecks in PowerShell are.

But this post isn’t about those performance solutions – I’m sure that we will cover a lot of them over the coming of the months. I want to RANT.

One of the reasons I think PowerShell has so many language quirks (and thus related gotchas when learning to do advanced stuff and solving bugs) is because it is Defined by Implementation instead of being Defined by Specification. To be honest, PowerShell is more of a platform , than a language or even a shell, and as it brings some new ideas and melds existing ideas in totally new ways, almost experimental ways, I don’t think it could have been defined any other way. However its quirks and yes also its performance is a result of that. I believe it needs to be reviewed by traditional language designers and not be excused “because its a shell language”. I believe that the importance of PowerShell is growing phenomenally and being part of Microsoft’s common engineering requirement I strongly believe such close working with the CLR team should be done, and even if PowerShell is defined by Implementation and will likely be in version 2 also – SPEND THE TIME TO AT LEAST DEFINE THE SPECIFICATION, DOCUMENT THE INTENDED (and thus real) BEHAVIOUR, RELEASE A FULL GRAMMAR, RELEASE OFFICIAL XSD SCHEMAS of the XML ELEMENTS, and if specification is what defines it, and that specification is best represented in the automated unit tests – maybe , just maybe even release such tests  , as per other dynamic languages. I think some of this stuff should at least be done BEFORE V2 is released. I mean getting a V2 and not even having a V1 grammar. </end of rant>

Disclaimer:

Despite the above concerns, I love PowerShell, and the general performance doesn’t bother me. Being able to code at the speed of thought, and do things with far less code than C#, and do things interactively and dynamically totally win out. PowerShell does introduce many new tangents on concepts and mash together some amazing things, its amazing they got it as right as they did the first time. I know if I had implemented such a platform/language it would be less consistent and probably slower than a ZX81. PowerShell V2, even though only in CTP2 already shows great performance enhancements.

If that disclaimer gave you the warm fuzzies, don’t get too comfortable, i have another pet peeve to blog about, and that is the fallacy called “Restricted Runspaces” and how the lack of being able to truly sandbox PowerShell has me running in the direction of IronRuby – But that’s for another day.

-Karl / Shell Tools

Posted in Gotchas Etc, Powershell, performance, pscom, rant | 3 Comments »

SnapInini – Lite portable SnapIns with no need of registration/installation.

June 7th, 2008 by Karl

One thing that has bothered me about true cmdlets in contrast scripts is that they lived in SnapIns and couldn’t be deployed with xcopy as scripts can because SnapIns required Registration/Installation. I build my own way to deal with this need some time ago, and thought that I’d start a blog series covering it. I call them Snapininis or SnapIn-Lites. A good thing is you can achieve the same end result in PowerShell V2 with modules – but that is V2 and a while away from being released, and then even further away from being fully deployed.

So how does this work?

1) you have to load an assembly into memory in powershell that contains your snapin.
2) you add the cmdlets directly into the runspace that is running and tell powershell to update its list of cmdlets.

Here is the C# code for a sample barebones SnapInini.

using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
 
namespace Snapinini
{
    public class DynamicCmdLet
    {
        public static void Load()
        {
            CmdletConfigurationEntry conf = new CmdletConfigurationEntry("dummy-cmdlet", typeof(ForeachDictionaryCmdLet), null);
            Runspace.DefaultRunspace.RunspaceConfiguration.Cmdlets.Append(conf);
            Runspace.DefaultRunspace.RunspaceConfiguration.Cmdlets.Update();
            Runspace.DefaultRunspace.CreateNestedPipeline(
                "new-alias dcmd dummy-cmdlet; write-host 'snapinini loaded'",
                false).Invoke();
        }
    }
    [Cmdlet("dummy", "cmdlet")]
    public class ForeachDictionaryCmdLet : System.Management.Automation.PSCmdlet
    {
        protected override void EndProcessing()
        {
            WriteObject("hello from the dummy cmdlet");
        }
    }
}

In the above sample I have a very very simple cmdlet. You can see that i get the defaultrunspace, go into its RunspaceConfiguration and add the cmdlets and update the list. I am additionally running some powershell script that adds an alias to the cmdlet and writes a message to the screen just as an example showing you that you can do more stuff if you wish. In the above code the load is a static method so its easy to call from powershell once you’ve loaded the assembly, but in all honesty the Load() code could just as well have been written in the calling PowerShell.

So how do we load and use this in PowerShell?

[system.Reflection.Assembly]::LoadFrom("snapinini.dll")
[snapinini.DynamicCmdLet]::load()
dummy-cmdlet
dcmd

Where to from here? This example is very simple, you could easily add multiple cmdlets into the equation, specify help files, add custom type definitions etc. Another thing I had experimented with is taking a real snapin and using reflection to see the cmdlets in it and adding them directly, however unless you know exactly what a snapin does this is dangerous because in its registration it might set up a bunch of other things also that are important.

Another thing I should cover next time is a safe way to load assemblies from any location and ensure that all their references get resolved seamlessly.

-Karl

Posted in Bare Metal, Powershell, pscom | No Comments »

SnapInini – Lite portable SnapIns with no need of registration/installation.

June 7th, 2008 by Karl

One thing that has bothered me about true cmdlets in contrast scripts is that they lived in SnapIns and couldn’t be deployed with xcopy as scripts can because SnapIns required Registration/Installation. I build my own way to deal with this need some time ago, and thought that I’d start a blog series covering it. I call them Snapininis or SnapIn-Lites.

So how does this work?

1) you have to load an assembly into memory in powershell that contains your snapin.
2) you add the cmdlets directly into the runspace that is running and tell powershell to update its list of cmdlets.

Here is the C# code for a sample barebones SnapInini.

using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
 
namespace Snapinini
{
    public class DynamicCmdLet
    {
        public static void Load()
        {
            CmdletConfigurationEntry conf = new CmdletConfigurationEntry("dummy-cmdlet", typeof(ForeachDictionaryCmdLet), null);
            Runspace.DefaultRunspace.RunspaceConfiguration.Cmdlets.Append(conf);
            Runspace.DefaultRunspace.RunspaceConfiguration.Cmdlets.Update();
            Runspace.DefaultRunspace.CreateNestedPipeline(
                "new-alias dcmd dummy-cmdlet; write-host 'snapinini loaded'",
                false).Invoke();
        }
    }
    [Cmdlet("dummy", "cmdlet")]
    public class ForeachDictionaryCmdLet : System.Management.Automation.PSCmdlet
    {
        protected override void EndProcessing()
        {
            WriteObject("hello from the dummy cmdlet");
        }
    }
}

In the above sample I have a very very simple cmdlet. You can see that i get the defaultrunspace, go into its RunspaceConfiguration and add the cmdlets and update the list. I am additionally running some powershell script that adds an alias to the cmdlet and writes a message to the screen just as an example showing you that you can do more stuff if you wish. In the above code the load is a static method so its easy to call from powershell once you’ve loaded the assembly, but in all honesty the Load() code could just as well have been written in the calling PowerShell.

So how do we load and use this in PowerShell?

[system.Reflection.Assembly]::LoadFrom("snapinini.dll")
[snapinini.DynamicCmdLet]::load()
dummy-cmdlet
dcmd

Where to from here? This example is very simple, you could easily add multiple cmdlets into the equation, specify help files, add custom type definitions etc. Another thing I had experimented with is taking a real snapin and using reflection to see the cmdlets in it and adding them directly, however unless you know exactly what a snapin does this is dangerous because in its registration it might set up a bunch of other things also that are important.

Another thing I should cover next time is a safe way to load assemblies from any location and ensure that all their references get resolved seamlessly.

-Karl

Posted in Powershell, pscom | 2 Comments »

Determining what version of PowerShell your script is running in.

June 4th, 2008 by Karl

Many people recently have asked how to determine programatically what version of PowerShell their script is running in. Well in version two there is a $psversiontable variable, but this sadly isn’t in V1. All is not lost though, as you can write a simple function to return a version object for v1. Below is a quick function that I wrote that I have been using for the last year or so.

function get-psVersion
{
if ((get-Variable psversiontabl[e]) -eq $null)
   {
     new-Object system.Version "1.0.0.0"
   }
   else
    {
    $psversiontable.psversion
    }
}

-Karl

Posted in Powershell, pscom | No Comments »