Windows PowerShell CTP2 to CTP3 Conversion Guide

I write a lot of scripts, and, since I blog some of what I write, my home computer has been running Windows PowerShell CTP2 since it came out.  Since CTP3 has a number of changes from CTP2, I’ve got to update my home script library to work with CTP3.  While this guide might not have every change that happened in between CTP2 and CTP3 (because I script with most, but not all, of PowerShell), I hope that this record of conversion steps helps everyone else moving from Windows PowerShell CTP2 to CTP3.  Oisin Grehan has posted a fairly complete list of cmdlet name changes on his blog, Nivot Ink.  This document only details what I’ve had to do to update my own scripts from CTP2 to CTP3, but not everything that has changed between the two releases.

Here’s a list of all of the changes I’ve had to make to my personal script collection so far.

  1. Graphical PowerShell is now the PowerShell Integrated Scripting Environment, the profile name for this user interface has changed.  If you made a profile in Graphical PowerShell, simply rename the file from Microsoft.GPowerShell_profile.ps1 to Microsoft.PowerShellISE_profile.ps1
  2. Modules were in a packages directory, and are now in a modules directory, rename the packages directory (if you have one) to modules
  3. You’re Importing Modules, not adding them, so Add-Module is now renamed Import-Module
  4. Script Cmdlets are now technically called “advanced functions”, and so the cmdlet keyword has been removed from the language.  If you built a script cmdlet by starting with the word cmdlet (e.g. cmdlet foo), rename cmdlet to function. If you simply designated a function to be a script cmdlet by adding the cmdlet keyword before the parameter declaration, remove it.  If you happened to have a default parameter set, then you’ll have to specify the default parameter set by adding a CmdletBinding attribute: CTP2:

    cmdlet `
      -DefaultParameterSet Type `



    Note that it’s DefaultParameterSetName, not DefaultParameterSet.  In my script collection, this was the most tedious thing to change out.

  5. The New-PSEvent cmdlet is now New-Event
  6. The New API to invoke PowerShell from within C# (this was used in my WPF post series) underwent a number of transitions.  First and foremost, because things in the top-level namespace were easier to find, we’ve moved the class from the System.Management.Automation.Runspaces namespace to System.Management.Automation.  Also, since there were a lot of different overloads for Creating PowerShell API instances and for adding parameters, we’ve consolidated the code significantly.  As in CTP2, Adding parameters or commands returns the Powershell object, so you can chain a few commands together rather than storing a variable. Oisin pointed out that there are type accelerators for the PowerShell API, Runspace, and RunspaceFactory


    $psCmd = [Management.Automation.Runspaces.PowerShell]::Create(Command, IsScript)





  7. The PowerShell API also no longer has GetRunspace/SetRunspace or GetRunspacePool/SetRunspacePool methods.  Instead, it has a runspace property and a runspace pool property.  Here’s what a hello world in WPF would look like in CTP2 vs CTP3

    # Create a runspace to run Hello World
    $rs = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
    $rs.ApartmentState, $rs.ThreadOptions = “STA”, “ReuseThread”
    # Reference the WPF assemblies
    $psCmd = {Add-Type}.GetPowerShell()
    $psCmd.AddParameter(“AssemblyName”, “PresentationCore”).Invoke()
    $psCmd = $psCmd.AddCommand(“Add-Type”)
    $psCmd.AddParameter(“AssemblyName”, “PresentationFramework”).Invoke()
    $psCmd = $psCmd.AddCommand(“Add-Type”)
    $psCmd.AddParameter(“AssemblyName”, “WindowsBase”).Invoke()
    $sb = $executionContext.InvokeCommand.NewScriptBlock(
    (Join-Path $pwd “HelloWorld.ps1″)
    $psCmd = $sb.GetPowerShell()
    $null = $psCmd.BeginInvoke()


    # Create a runspace to run Hello World
    $rs = [RunspaceFactory]::CreateRunspace()
    $rs.ApartmentState, $rs.ThreadOptions = “STA”, “ReuseThread”
    $psCmd = {Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase}.GetPowerShell()
    $psCmd.Runspace = $rs
        $window = New-Object Windows.Window
        $window.Title = $window.Content = “Hello World.  Check out PowerShell and WPF Together.”
        $window.FontSize = ’24’
        $window.SizeToContent = “WidthAndHeight”
        $null = $window.ShowDialog()

  8. $commandLineParameters, a variable that held what named parameters were bound to the current function, is now $psBoundParameters
  9. Get-PSCallStack no longer returns strings.  It now returns a more detailed command object.  The value of $myInvocation at each level of the callstack is stored in a property called InvocationInfo
  10. The Exports property of a PSModuleInfo (the class returned from Get-Module) is gone.  Exports was a bunch of strings indicating the commands exported from a module.  The exports has been replaced by several dictionaries containing more detailed export information: ExportedAliases, ExportedCmdlets, ExportedFunctions, and ExportedVariables.

Once again, this is only the changes that I’ve made to my personal script collection at home.  This post doesn’t contain all that is new or cool with CTP3 (and there’s a lot of new coolness in CTP3), but it does contain the changes that broke my CTP2 scripts that I am aware of. I will update as I make more changes, and, if you’ve had any issues converting your CTP2 scripts to CTP3, please post a comment to this blog and I’ll update the conversion guide.

Hope this Helps,

James Brundage [MSFT]