Ensuring Script Portability with #requires


With the MshSnapIn model in Beta 3, there is no gaurantee that a certain Cmdlet or Provider, apart from those in the default MshSnapIns, is available at any point. There could be a number of reasons. The MshSnapIn may not have been installed. The MshSnapIn could be removed with the remove-mshsnapin Cmdlet or not even added yet. This will cause scripts using the unavailable commands to fail or worse exhibit unpredictable behaviors. Along with the MshSnapIn model, we introduce two flavors of #requires that a script can use to express dependencies on MshSnapIns and Monad version. The former has the following syntax:


#requires -MshSnapIn SomeMshSnapIn [-version N[.n]]  where the parts in square brackets are optional. #requires must be at the beginning of a line.


When only MshSnapIn is specified, the script will run if and only if the MshSnapIn SomeMshSnapIn is already added with the Add-MshSnapIn Cmdlet (or the RunspaceConfiguration.AddMshSnapIn API). Moreover, if the major version N is specified, the added MshSnapin’s major version must match N. Furthermore, if the minor version n is also specified, the added MshSnapin’s minor version must be equal to or higher than n. Failing any of the checks will cause the script not to run. A script can have multiple #requires -MshSnapIn directives. In this case, all MshSnapIn checks will need to pass for the script to run.


The latter’s syntax is as follows.


#requires -version N[.n]  where the parts in square brackets are optional. #requires must be at the beginning of a line.


When only the major version N is specified, the current Monad shell’s version must match N. If the minor version is also n specified, the current Monad shell’s minor version must be equal to or higher than n. Failing any of the checks will cause the script not to run.


Finally, for the custom shell environment, the #requires -ShellId flavor is still available. A script can have any combinations of the three #requires flavors. #requires -version will check the Monad shell version for all combinations. As for the other two flavors, here is the behavior summary:



















If a script has Monad Shell Custom Shell
#requires -MshSnapIn and no #requires -ShellId Check MshSnapIn Script won’t run
#requires -ShellId and no #requires -MshSnapIn Script won’t run Check ShellId
#requires -ShellId and #requires -MshSnapIn Check MshSnapIn Check ShellId


Kevin Loo [MSFT]
Monad Development
Microsoft Corporation
This posting is provided “AS IS” with no warranties, and confers no rights.


Comments (4)

  1. Joe Phan says:

    I was wondering the compatibility story of Monad’s scripting. Now I am pretty clear. Good article.

    Cheers

    JP

  2. Keith Hill says:

    Heck while you’re at it, why don’t you add

    #load MyAssembly.dll and #using IO=System.IO;#using System.WIndows.Forms? :-)

  3. Is it going to be possible for a custom shell to be "MshSnapin compatible" if its RunspaceConfiguration implements the AddMshSnapIn API? (and, I assume, provides its own versions of the snapin related cmdlets since the inbuilt ones depend on the RunspaceConfigForSingleShell)

  4. MSDNArchive says:

    [Response to comment 512099.]

    AddMshSnapIn Api is meant to be called by hosting applications to add snapin’s into a runspaceConfiguration.

    It is not meant to be derived by child RunspaceConfiguration classes.

    This is an Api design issue we probably has to revisit.

    George Xie [MSFT]

    Monad Development

    Microsoft Corporation

    This posting is provided "AS IS" with no warranties, and confers no rights