<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Nivot Ink - .NET</title>
    <link>http://www.nivot.org/</link>
    <description>PowerShell, SharePoint, WCF, WWF, .NET, ASP.NET, Enterprise Computing and babble from Microsoft MVP Oisin Grehan.</description>
    <language>en-us</language>
    <copyright>Oisin Grehan</copyright>
    <lastBuildDate>Mon, 26 Jul 2010 21:33:21 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>oising@gmail.com</managingEditor>
    <webMaster>oising@gmail.com</webMaster>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=0b623743-f07e-4fd4-891e-35a05c656c4a</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,0b623743-f07e-4fd4-891e-35a05c656c4a.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,0b623743-f07e-4fd4-891e-35a05c656c4a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=0b623743-f07e-4fd4-891e-35a05c656c4a</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Write your own PowerShell provider using only script, no C# required. Module definition
is provided by a Windows PowerShell 2.0 Module, which may be pure script, binary or
a mix of both.
</p>
        <p>
Debugging is as easy as any ordinary ps1 script file:
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/869ac7ef36f5_F659/image_4.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/869ac7ef36f5_F659/image_thumb_1.png" width="846" height="654" />
          </a>
        </p>
        <p>
All functions in backing module reflect the same signature as those found on MSDN.
This means that you go to MSDN documentation on providers to learn about how to write
the corresponding script. 
</p>
        <h4>Current Release <a href="http://psprovider.codeplex.com/releases/view/49025">PSProvider
0.4</a></h4>
        <h4>Samples and Templates
</h4>
        <ul>
          <li>
See <a href="http://psprovider.codeplex.com/documentation?referringTitle=Home">Documentation</a></li>
        </ul>
        <h4>Roadmap
</h4>
        <h5>0.1
</h5>
        <ul>
          <li>
ContainerCmdletProvider support through "ModuleBoundProvider" provider 
</li>
          <li>
Demo provider included navigating a Hashtable 
</li>
          <li>
Can be debugged in the debugger of your choice: console, ISE, PowerGUI.</li>
        </ul>
        <h5>0.2
</h5>
        <ul>
          <li>
NavigationCmdletProvider support 
</li>
          <li>
Providers rename to ContainerScriptProvider and TreeScriptProvider 
</li>
          <li>
Container Sample &amp; Tree Template modules 
</li>
          <li>
Supports: <b>Clear-Item, Copy-Item, Get-Item, Invoke-Item, Move-Item, New-Item, Remove-Item,
Rename-Item, Set-Item</b></li>
        </ul>
        <h5>0.3
</h5>
        <ul>
          <li>
IContentCmdletProvider support 
</li>
          <li>
New Commands: <b>New-ContentReader, New-ContentWriter</b> implement IContentReader,
IContentWriter 
</li>
          <li>
Adds support for: <b>Add-Content, Clear-Content, Get-Content, Set-Content</b></li>
        </ul>
        <h5>0.4 (Current Release)
</h5>
        <ul>
          <li>
IPropertyCmdletProvider support 
</li>
          <li>
Adds support for: <b>Clear-ItemProperty, Copy-ItemProperty, Get-ItemProperty, Move-ItemProperty,
New-ItemProperty, Remove-ItemProperty, Rename-ItemProperty, Set-ItemProperty</b></li>
        </ul>
        <h5>0.5
</h5>
        <ul>
          <li>
Dynamic Parameter support</li>
        </ul>
        <h5>0.6
</h5>
        <ul>
          <li>
Security Interfaces 
</li>
          <li>
Adds support for: <b>Get-ACL, Set-ACL</b></li>
        </ul>
        <p>
          <a href="http://psprovider.codeplex.com/">http://psprovider.codeplex.com/</a>
        </p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=0b623743-f07e-4fd4-891e-35a05c656c4a" />
      </body>
      <title>PowerShell Script Provider</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,0b623743-f07e-4fd4-891e-35a05c656c4a.aspx</guid>
      <link>http://www.nivot.org/2010/07/26/PowerShellScriptProvider.aspx</link>
      <pubDate>Mon, 26 Jul 2010 21:33:21 GMT</pubDate>
      <description>&lt;p&gt;
Write your own PowerShell provider using only script, no C# required. Module definition
is provided by a Windows PowerShell 2.0 Module, which may be pure script, binary or
a mix of both.
&lt;/p&gt;
&lt;p&gt;
Debugging is as easy as any ordinary ps1 script file:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/869ac7ef36f5_F659/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/869ac7ef36f5_F659/image_thumb_1.png" width="846" height="654"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
All functions in backing module reflect the same signature as those found on MSDN.
This means that you go to MSDN documentation on providers to learn about how to write
the corresponding script. 
&lt;/p&gt;
&lt;h4&gt;Current Release &lt;a href="http://psprovider.codeplex.com/releases/view/49025"&gt;PSProvider
0.4&lt;/a&gt;
&lt;/h4&gt;
&lt;h4&gt;Samples and Templates
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
See &lt;a href="http://psprovider.codeplex.com/documentation?referringTitle=Home"&gt;Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Roadmap
&lt;/h4&gt;
&lt;h5&gt;0.1
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;
ContainerCmdletProvider support through "ModuleBoundProvider" provider 
&lt;li&gt;
Demo provider included navigating a Hashtable 
&lt;li&gt;
Can be debugged in the debugger of your choice: console, ISE, PowerGUI.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;0.2
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;
NavigationCmdletProvider support 
&lt;li&gt;
Providers rename to ContainerScriptProvider and TreeScriptProvider 
&lt;li&gt;
Container Sample &amp;amp; Tree Template modules 
&lt;li&gt;
Supports: &lt;b&gt;Clear-Item, Copy-Item, Get-Item, Invoke-Item, Move-Item, New-Item, Remove-Item,
Rename-Item, Set-Item&lt;/b&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;0.3
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;
IContentCmdletProvider support 
&lt;li&gt;
New Commands: &lt;b&gt;New-ContentReader, New-ContentWriter&lt;/b&gt; implement IContentReader,
IContentWriter 
&lt;li&gt;
Adds support for: &lt;b&gt;Add-Content, Clear-Content, Get-Content, Set-Content&lt;/b&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;0.4 (Current Release)
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;
IPropertyCmdletProvider support 
&lt;li&gt;
Adds support for: &lt;b&gt;Clear-ItemProperty, Copy-ItemProperty, Get-ItemProperty, Move-ItemProperty,
New-ItemProperty, Remove-ItemProperty, Rename-ItemProperty, Set-ItemProperty&lt;/b&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;0.5
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;
Dynamic Parameter support&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;0.6
&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;
Security Interfaces 
&lt;li&gt;
Adds support for: &lt;b&gt;Get-ACL, Set-ACL&lt;/b&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;a href="http://psprovider.codeplex.com/"&gt;http://psprovider.codeplex.com/&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=0b623743-f07e-4fd4-891e-35a05c656c4a" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,0b623743-f07e-4fd4-891e-35a05c656c4a.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>CodePlex</category>
      <category>Developer</category>
      <category>Modules</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>Providers</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=a106a528-3ba3-4463-8cac-555758287c5d</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,a106a528-3ba3-4463-8cac-555758287c5d.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,a106a528-3ba3-4463-8cac-555758287c5d.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=a106a528-3ba3-4463-8cac-555758287c5d</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you want to do this, you won’t really need much of an explanation as to why I’m
posting this. As to the rest of you, never mind; stick with your BigEndian Unicode
(hint: powershell console and other console applications prefer ASCII) :) 
</p>
        <p>
First up, create yourself a Windows ISE Profile script that will be loaded by default
when ISE starts (and/or when you open a new “Tab”)
</p>
        <pre class="brush:powershell">
# run this one-liner from within ISE through the interactive window (command pane):
if (-not (test-path $profile)) { md -force (split-path $profile); "" &gt; $profile; psedit $profile }
</pre>
        <p>
Now, put this one-liner (well, it could fit on one line) in your $profile:
</p>
        <pre class="brush:powershell">
# watch for changes to the Files collection of the current Tab
register-objectevent $psise.CurrentPowerShellTab.Files collectionchanged -action {
    # iterate ISEFile objects
    $event.sender | % {
         # set private field which holds default encoding to ASCII
         $_.gettype().getfield("encoding","nonpublic,instance").setvalue($_, [text.encoding]::ascii)
    }
}
</pre>
Every time the tabs "files" collection changes, it will set the default save encoding
to ASCII for all files in that tab. As the profile is loaded in each tab, all files
in all tabs will default to ASCII when saving. No more "save as" annoyances; just
hit save and ASCII will be used for encoding. "Save as" will still let you save as
unicode if you wish.
<p>
Have fun!
</p><img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=a106a528-3ba3-4463-8cac-555758287c5d" /></body>
      <title>PowerShell ISE Hacking: Change default save encoding to ASCII</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,a106a528-3ba3-4463-8cac-555758287c5d.aspx</guid>
      <link>http://www.nivot.org/2010/05/21/PowerShellISEHackingChangeDefaultSaveEncodingToASCII.aspx</link>
      <pubDate>Fri, 21 May 2010 21:58:46 GMT</pubDate>
      <description>&lt;p&gt;
If you want to do this, you won’t really need much of an explanation as to why I’m
posting this. As to the rest of you, never mind; stick with your BigEndian Unicode
(hint: powershell console and other console applications prefer ASCII) :) 
&lt;/p&gt;
&lt;p&gt;
First up, create yourself a Windows ISE Profile script that will be loaded by default
when ISE starts (and/or when you open a new “Tab”)
&lt;/p&gt;
&lt;pre class="brush:powershell"&gt;
# run this one-liner from within ISE through the interactive window (command pane):
if (-not (test-path $profile)) { md -force (split-path $profile); "" &gt; $profile; psedit $profile }
&lt;/pre&gt;
&lt;p&gt;
Now, put this one-liner (well, it could fit on one line) in your $profile:
&lt;/p&gt;
&lt;pre class="brush:powershell"&gt;
# watch for changes to the Files collection of the current Tab
register-objectevent $psise.CurrentPowerShellTab.Files collectionchanged -action {
    # iterate ISEFile objects
    $event.sender | % {
         # set private field which holds default encoding to ASCII
         $_.gettype().getfield("encoding","nonpublic,instance").setvalue($_, [text.encoding]::ascii)
    }
}
&lt;/pre&gt;
Every time the tabs "files" collection changes, it will set the default save encoding
to ASCII for all files in that tab. As the profile is loaded in each tab, all files
in all tabs will default to ASCII when saving. No more "save as" annoyances; just
hit save and ASCII will be used for encoding. "Save as" will still let you save as
unicode if you wish.&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=a106a528-3ba3-4463-8cac-555758287c5d" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,a106a528-3ba3-4463-8cac-555758287c5d.aspx</comments>
      <category>.NET</category>
      <category>Eventing</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>PowerShell ISE</category>
      <category>Reflection</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=d23c0f43-6edf-44a0-8d04-8d768af8c122</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,d23c0f43-6edf-44a0-8d04-8d768af8c122.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,d23c0f43-6edf-44a0-8d04-8d768af8c122.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=d23c0f43-6edf-44a0-8d04-8d768af8c122</wfw:commentRss>
      <title>PowerShell 2.0 – PSCX Labs: Invoke-Reflector</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,d23c0f43-6edf-44a0-8d04-8d768af8c122.aspx</guid>
      <link>http://www.nivot.org/2010/05/05/PowerShell20PSCXLabsInvokeReflector.aspx</link>
      <pubDate>Wed, 05 May 2010 21:05:16 GMT</pubDate>
      <description>&lt;p&gt;
This is a lot of fun if you spend a lot of time tinkering around with APIs in PowerShell.
This function (included in the upcoming PSCX 2.0, alias: refl) will let you open Lutz
Roeder’s &lt;a href="http://www.red-gate.com/products/reflector/" target="_blank"&gt;Reflector&lt;/a&gt; for
any Type or Cmdlet. Reflector will automatically load the correct Assembly and will
highlight the relevant Type, without you having to do diddley-squat. Examples and
help will display with -?
&lt;/p&gt;
&lt;pre class="brush:powershell"&gt;
function Invoke-Reflector {

&lt;# .synopsis quickly load Reflector, with the specified Type or Command selected.
    .DESCRIPTION
        Quickly load Reflector, with the specified Type or Command selected. The function will also
        ensure that Reflector has the Type or Command's containing Assembly loaded.
    .EXAMPLE
        # Opens System.String in Reflector. Will load its Assembly into Reflector if required.
        ps&gt;
[string] | invoke-reflector .EXAMPLE # Opens GetChildItemCommand in Reflector. Will
load its Assembly into Reflector if required. ps&gt; gcm ls | invoke-reflector .EXAMPLE
# Opens GetChildItemCommand in Reflector. Will load its Assembly into Reflector if
required. ps&gt; invoke-reflector dir .PARAMETER CommandName Accepts name of command.
Does not accept pipeline input. .PARAMETER CommandInfo Accepts output from Get-Command
(gcm). Accepts pipeline input. .PARAMETER Type Accepts a System.Type (System.RuntimeType).
Accepts pipeline input. .PARAMETER ReflectorPath Optional. Defaults to Reflector.exe's
location if it is found in your $ENV:PATH. If not found, you must specify. .INPUTS
[System.Type] [System.Management.Automation.CommandInfo] .OUTPUTS None #&gt; [cmdletbinding(defaultparametersetname="name")]
param( [parameter( parametersetname="name", position=0, mandatory=$true )] [validatenotnullorempty()]
[string]$CommandName, [parameter( parametersetname="command", position=0, valuefrompipeline=$true,
mandatory=$true )] [validatenotnull()] [management.automation.commandinfo]$CommandInfo,
[parameter( parametersetname="type", position=0, valuefrompipeline=$true, mandatory=$true
)] [validatenotnull()] [type]$Type, [parameter( position=1 )] [validatenotnullorempty()]
[string]$ReflectorPath = $((gcm reflector.exe -ea 0).definition) ) # no process block;
i only want # a single reflector instance if ($ReflectorPath -and (test-path $reflectorpath))
{ $typeName = $null $assemblyLocation = $null switch ($pscmdlet.parametersetname)
{ { "name","command" -contains $_ } { if ($CommandName) { $CommandInfo = gcm $CommandName
-ea 0 } else { $CommandName = $CommandInfo.Name } if ($CommandInfo -is [management.automation.aliasinfo])
{ # expand aliases while ($CommandInfo.CommandType -eq "Alias") { $CommandInfo = gcm
$CommandInfo.Definition } } # can only reflect cmdlets, obviously. if ($CommandInfo.CommandType
-eq "Cmdlet") { $typeName = $commandinfo.implementingtype.fullname $assemblyLocation
= $commandinfo.implementingtype.assembly.location } elseif ($CommandInfo) { write-warning
"$CommandInfo is not a Cmdlet." } else { write-warning "Cmdlet $CommandName does not
exist in current scope. Have you loaded its containing module or snap-in?" } } "type"
{ $typeName = $type.fullname $assemblyLocation = $type.assembly.location } } # end
switch if ($typeName -and $assemblyLocation) { &amp; $reflectorPath /select:$typeName
$assemblyLocation } } else { write-warning "Unable to find Reflector.exe. Please specify
full path via -ReflectorPath." } } 
&lt;/pre&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=d23c0f43-6edf-44a0-8d04-8d768af8c122" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,d23c0f43-6edf-44a0-8d04-8d768af8c122.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>Developer</category>
      <category>Functions</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>PSCX</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=dc6c6638-cb87-4f78-8715-f221bbcc53c6</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,dc6c6638-cb87-4f78-8715-f221bbcc53c6.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,dc6c6638-cb87-4f78-8715-f221bbcc53c6.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=dc6c6638-cb87-4f78-8715-f221bbcc53c6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
These days I'm incredibly busy both in my professional and private life, so I’ve not
had a lot of time to construct the usual meaty posts I like to write. Instead I figured
I could write a series of short – very short – posts centered around the little tricks
that you would need to be an efficient developer when targeting PowerShell. Here's
the first tip: how to create a Runspace and have one or more Module(s) preloaded.
The <a href="http://msdn.microsoft.com/en-us/library/system.management.automation.runspaceinvoke.aspx" target="_blank">RunspaceInvoke</a> class
is a handy wrapper that will do most of the plumbing for you if you just want to run
scripts or commands. If you want to manually construct your own <a href="http://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.pipeline.aspx" target="_blank">Pipeline</a> instances
then you must work with the <a href="http://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.runspace.aspx" target="_blank">Runspace</a> class
directly.
</p>
        <pre class="brush:csharp">
    InitialSessionState initial = InitialSessionState.CreateDefault();
    initialSession.ImportPSModule(new[] { modulePathOrModuleName1, ... });
    Runspace runspace = RunspaceFactory.CreateRunspace(initial);
    runspace.Open();
    RunspaceInvoke invoker = new RunspaceInvoke(runspace);
    Collection&lt;PSObject&gt; results = invoker.Invoke("...");
</pre>
        <p>
Have fun!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=dc6c6638-cb87-4f78-8715-f221bbcc53c6" />
      </body>
      <title>PowerShell 2.0 – Developer Essentials #1 – Initializing a Runspace with a Module</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,dc6c6638-cb87-4f78-8715-f221bbcc53c6.aspx</guid>
      <link>http://www.nivot.org/2010/05/03/PowerShell20DeveloperEssentials1InitializingARunspaceWithAModule.aspx</link>
      <pubDate>Mon, 03 May 2010 16:54:13 GMT</pubDate>
      <description>&lt;p&gt;
These days I'm incredibly busy both in my professional and private life, so I’ve not
had a lot of time to construct the usual meaty posts I like to write. Instead I figured
I could write a series of short – very short – posts centered around the little tricks
that you would need to be an efficient developer when targeting PowerShell. Here's
the first tip: how to create a Runspace and have one or more Module(s) preloaded.
The &lt;a href="http://msdn.microsoft.com/en-us/library/system.management.automation.runspaceinvoke.aspx" target="_blank"&gt;RunspaceInvoke&lt;/a&gt; class
is a handy wrapper that will do most of the plumbing for you if you just want to run
scripts or commands. If you want to manually construct your own &lt;a href="http://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.pipeline.aspx" target="_blank"&gt;Pipeline&lt;/a&gt; instances
then you must work with the &lt;a href="http://msdn.microsoft.com/en-us/library/system.management.automation.runspaces.runspace.aspx" target="_blank"&gt;Runspace&lt;/a&gt; class
directly.
&lt;/p&gt;
&lt;pre class="brush:csharp"&gt;
    InitialSessionState initial = InitialSessionState.CreateDefault();
    initialSession.ImportPSModule(new[] { modulePathOrModuleName1, ... });
    Runspace runspace = RunspaceFactory.CreateRunspace(initial);
    runspace.Open();
    RunspaceInvoke invoker = new RunspaceInvoke(runspace);
    Collection&amp;lt;PSObject&amp;gt; results = invoker.Invoke("...");
&lt;/pre&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=dc6c6638-cb87-4f78-8715-f221bbcc53c6" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,dc6c6638-cb87-4f78-8715-f221bbcc53c6.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>Developer</category>
      <category>Modules</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=10dd1c60-c001-4b4a-ac94-b4cacd10086a</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,10dd1c60-c001-4b4a-ac94-b4cacd10086a.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,10dd1c60-c001-4b4a-ac94-b4cacd10086a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=10dd1c60-c001-4b4a-ac94-b4cacd10086a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is a just a short post to remind myself (and you, frustrated googlers/bingers)
about the different ways resources are defined and accessed within SharePoint. While
some .NET applications use embedded resources or satellite assemblies, SharePoint
has a preference for raw RESX files. These resx files are dumped in one of two places:
</p>
        <p>
          <strong>12\CONFIG\RESOURCES<br /></strong>
          <br />
- application-level "global" resources<br />
- propagated at site definition instantiation<br />
- later modifications require stsadm -o copyappbincontent<br />
- they live in &lt;approot&gt;\App_GlobalAppResources 
<br />
- accessed via HttpContext.GetGlobalResourceObject / TemplateControl.GetGlobalResourceObject<br />
- <a href="http://msdn.microsoft.com/en-us/library/system.web.httpcontext.getglobalresourceobject.aspx">http://msdn.microsoft.com/en-us/library/system.web.httpcontext.getglobalresourceobject.aspx</a><br />
- declaratively accessible &lt;asp:foo runat="server" text="&lt;%$ Resources: myapp.core,
ResKeyName %&gt;" /&gt;<br />
   (where myapp.core represents myapp.core.resx)<br /><strong><br />
12\RESOURCES<br /></strong>- farm-level global resources<br />
- available to all applications 
<br />
- remain in 12\RESOURCEs, not copied anywhere<br />
- typically used programatically via SPUtility.GetLocalizedString  ( Microsoft.SharePoint.Utilities
)<br />
- <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.utilities.sputility.getlocalizedstring.aspx">http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.utilities.sputility.getlocalizedstring.aspx</a></p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=10dd1c60-c001-4b4a-ac94-b4cacd10086a" />
      </body>
      <title>SharePoint Resources &amp; Localization – What, Where and Why?</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,10dd1c60-c001-4b4a-ac94-b4cacd10086a.aspx</guid>
      <link>http://www.nivot.org/2010/04/01/SharePointResourcesLocalizationWhatWhereAndWhy.aspx</link>
      <pubDate>Thu, 01 Apr 2010 16:43:37 GMT</pubDate>
      <description>&lt;p&gt;
This is a just a short post to remind myself (and you, frustrated googlers/bingers)
about the different ways resources are defined and accessed within SharePoint. While
some .NET applications use embedded resources or satellite assemblies, SharePoint
has a preference for raw RESX files. These resx files are dumped in one of two places:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;12\CONFIG\RESOURCES&lt;br&gt;
&lt;/strong&gt;
&lt;br&gt;
- application-level "global" resources&lt;br&gt;
- propagated at site definition instantiation&lt;br&gt;
- later modifications require stsadm -o copyappbincontent&lt;br&gt;
- they live in &amp;lt;approot&amp;gt;\App_GlobalAppResources 
&lt;br&gt;
- accessed via HttpContext.GetGlobalResourceObject / TemplateControl.GetGlobalResourceObject&lt;br&gt;
- &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.httpcontext.getglobalresourceobject.aspx"&gt;http://msdn.microsoft.com/en-us/library/system.web.httpcontext.getglobalresourceobject.aspx&lt;/a&gt;
&lt;br&gt;
- declaratively accessible &amp;lt;asp:foo runat="server" text="&amp;lt;%$ Resources: myapp.core,
ResKeyName %&amp;gt;" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; (where myapp.core represents myapp.core.resx)&lt;br&gt;
&lt;strong&gt;
&lt;br&gt;
12\RESOURCES&lt;br&gt;
&lt;/strong&gt;- farm-level global resources&lt;br&gt;
- available to all applications 
&lt;br&gt;
- remain in 12\RESOURCEs, not copied anywhere&lt;br&gt;
- typically used programatically via SPUtility.GetLocalizedString&amp;nbsp; ( Microsoft.SharePoint.Utilities
)&lt;br&gt;
- &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.utilities.sputility.getlocalizedstring.aspx"&gt;http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.utilities.sputility.getlocalizedstring.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=10dd1c60-c001-4b4a-ac94-b4cacd10086a" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,10dd1c60-c001-4b4a-ac94-b4cacd10086a.aspx</comments>
      <category>.NET</category>
      <category>i18n</category>
      <category>MOSS</category>
      <category>SharePoint</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=2cb1ab35-ec6b-40bb-b917-db1630560e72</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,2cb1ab35-ec6b-40bb-b917-db1630560e72.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,2cb1ab35-ec6b-40bb-b917-db1630560e72.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=2cb1ab35-ec6b-40bb-b917-db1630560e72</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
PowerShell guru and Admin-extraordinare <a href="http://www.jdhitsolutions.com/" target="_blank">Jeff
Hicks</a> asked a great question that many a Windows administrator has probably asked
themselves when working with Hashtables in PowerShell: Why do the key/values come
out in a different order than put in? This is a great question and the answer lies
in computer science theory, particularly computational complexity theory. Rather than
bore you with a <a href="http://en.wikipedia.org/wiki/Big_O_notation" target="_blank"><strong>ton
of nonsense about O(1), O(n)</strong></a> and other <a href="http://en.wikipedia.org/wiki/Hash_table" target="_blank">propeller-head
dribble</a>, I figure I could explain it in terms everyone should be able to understand.
</p>
        <h4>Hashtables, Buckets and HashCodes = Rolodex, Index Cards and Surnames<a href="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerShellWhyarekeysinHashtablessortedra_E213/card-index_2.jpg"><img style="border-right-width: 0px; margin: 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="card-index" border="0" alt="card-index" align="right" src="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerShellWhyarekeysinHashtablessortedra_E213/card-index_thumb.jpg" width="130" height="88" /></a></h4>
        <p>
Yes, if the light hasn’t gone on yet, it will soon. Every .NET object includes a method
called GetHashCode. This method returns a number that represents the identity of the
object in a kind of fuzzy way. I say “fuzzy” because the hash code for a given instance
of an object can be different on different platforms (xp, vista, 2003 etc) or on different
bitness (64 vs 32 bit.) This method is used by hashtable to get the “surname” of an
object. Instead of Index Cards, a Hashtable uses “buckets” to separate groups of objects.
Any given Hashcode will naturally fall into a particular bucket as the function (result)
of a high-speed optimized algorithm, much like any given surname naturally falls under
a particular letter of the alphabet. Finally, it should be clear to you that using
index cards [Hashtable buckets] is way faster than flicking through an unsorted folder
[randomized list.]
</p>
        <p>
Just like a Rolodex, the order you add names to it doesn’t dictate the order they
are in as you flip through the cards sequentially, which is analogous to sending a
Hashtable to out-default.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=2cb1ab35-ec6b-40bb-b917-db1630560e72" />
      </body>
      <title>PowerShell - Why are keys in Hashtables sorted randomly?</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,2cb1ab35-ec6b-40bb-b917-db1630560e72.aspx</guid>
      <link>http://www.nivot.org/2010/02/24/PowerShellWhyAreKeysInHashtablesSortedRandomly.aspx</link>
      <pubDate>Wed, 24 Feb 2010 22:38:55 GMT</pubDate>
      <description>&lt;p&gt;
PowerShell guru and Admin-extraordinare &lt;a href="http://www.jdhitsolutions.com/" target="_blank"&gt;Jeff
Hicks&lt;/a&gt; asked a great question that many a Windows administrator has probably asked
themselves when working with Hashtables in PowerShell: Why do the key/values come
out in a different order than put in? This is a great question and the answer lies
in computer science theory, particularly computational complexity theory. Rather than
bore you with a &lt;a href="http://en.wikipedia.org/wiki/Big_O_notation" target="_blank"&gt;&lt;strong&gt;ton
of nonsense about O(1), O(n)&lt;/strong&gt;&lt;/a&gt; and other &lt;a href="http://en.wikipedia.org/wiki/Hash_table" target="_blank"&gt;propeller-head
dribble&lt;/a&gt;, I figure I could explain it in terms everyone should be able to understand.
&lt;/p&gt;
&lt;h4&gt;Hashtables, Buckets and HashCodes = Rolodex, Index Cards and Surnames&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerShellWhyarekeysinHashtablessortedra_E213/card-index_2.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="card-index" border="0" alt="card-index" align="right" src="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerShellWhyarekeysinHashtablessortedra_E213/card-index_thumb.jpg" width="130" height="88"&gt;&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;
Yes, if the light hasn’t gone on yet, it will soon. Every .NET object includes a method
called GetHashCode. This method returns a number that represents the identity of the
object in a kind of fuzzy way. I say “fuzzy” because the hash code for a given instance
of an object can be different on different platforms (xp, vista, 2003 etc) or on different
bitness (64 vs 32 bit.) This method is used by hashtable to get the “surname” of an
object. Instead of Index Cards, a Hashtable uses “buckets” to separate groups of objects.
Any given Hashcode will naturally fall into a particular bucket as the function (result)
of a high-speed optimized algorithm, much like any given surname naturally falls under
a particular letter of the alphabet. Finally, it should be clear to you that using
index cards [Hashtable buckets] is way faster than flicking through an unsorted folder
[randomized list.]
&lt;/p&gt;
&lt;p&gt;
Just like a Rolodex, the order you add names to it doesn’t dictate the order they
are in as you flip through the cards sequentially, which is analogous to sending a
Hashtable to out-default.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=2cb1ab35-ec6b-40bb-b917-db1630560e72" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,2cb1ab35-ec6b-40bb-b917-db1630560e72.aspx</comments>
      <category>.NET</category>
      <category>CTP3</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=7b7a72ad-28d7-4a61-a5a1-3729cae67bd3</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,7b7a72ad-28d7-4a61-a5a1-3729cae67bd3.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,7b7a72ad-28d7-4a61-a5a1-3729cae67bd3.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=7b7a72ad-28d7-4a61-a5a1-3729cae67bd3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>( from: </em>
          <a title="http://support.microsoft.com/default.aspx/kb/968929" href="http://support.microsoft.com/default.aspx/kb/968929">
            <em>http://support.microsoft.com/default.aspx/kb/968929</em>
          </a>
          <em> –
downloads at foot of page )</em>
        </p>
        <p>
Windows PowerShell is a command-line shell and scripting language that is designed
for system administration and Automation. Built on the Microsoft .NET Framework, Windows
PowerShell enables IT professionals and developers to control and automate the administration
of Windows and applications.
</p>
        <p>
New features that are introduced in Windows PowerShell 2.0 include the following: 
</p>
        <ul>
          <li>
            <b>Remoting</b>
            <br />
Windows PowerShell 2.0 lets you run commands on one or more remote computers from
a single computer that is running Windows PowerShell. PowerShell remoting allows for
multiple ways of connecting. These ways include interactive (1:1), fan-out (1:many),
and fan-in (many:1 by using the IIS hosting model). 
</li>
          <li>
            <b>Integrated Scripting Environment</b>
            <br />
PowerShell Integrated Scripting Environment (ISE) enables you to run interactive commands
and edit and debug scripts in a graphical environment. The main features include color-coded
syntax, selective execution, graphical debugging, Unicode support, and context-sensitive
help. 
</li>
          <li>
            <b>Modules</b>
            <br />
Modules allow for script developers and administrators to partition and organize their
Windows PowerShell code in self-contained, reusable units. Code from a module executes
in its own self-contained context and does not affect the state outside the module. 
</li>
          <li>
            <b>Advanced functions</b>
            <br />
Advanced functions are functions that have the same capabilities and behavior as cmdlets.
However, they are written completely in the Windows PowerShell language, instead of
compiled C#. 
</li>
          <li>
            <b>Background jobs</b>
            <br />
Windows PowerShell 2.0 allows for running a command or expression asynchronously and
"in the background" without interacting with the console. 
</li>
          <li>
            <b>Eventing</b>
            <br />
This feature adds support to the Windows PowerShell engine infrastructure for listening,
forwarding, and acting on management and system events. 
</li>
          <li>
            <b>Script internationalization</b>
            <br />
This new feature enables Windows PowerShell scripts to display messages in the spoken
language that is specified by the UI culture setting on the user's computer. 
</li>
          <li>
            <b>Script debugging</b>
            <br />
New debugging features were added to Windows PowerShell that let you set breakpoints
on lines, columns, variables, and commands, and that let you specify the action that
occurs when the breakpoint is hit. 
</li>
          <li>
            <b>New cmdlets</b>
            <br />
Windows PowerShell 2.0 introduces over 100 built-in cmdlets. These cmdlets, excluding
other tasks, enables you to do computer-related, event log, and performance counter
management tasks.</li>
        </ul>
        <h3>WinRM 2.0
</h3>
        <p>
WinRM is the Microsoft implementation of WS-Management Protocol, a standard Simple
Object Access Protocol (SOAP)–based, firewall-friendly protocol that allows for hardware
and operating systems from different vendors to interoperate. The WS-Management Protocol
specification provides a common way for systems to access and exchange management
information across an IT infrastructure.
</p>
        <p>
WinRM 2.0 includes the following new features: 
</p>
        <ul>
          <li>
The WinRM Client Shell API provides functionality to create and manage shells and
shell operations, commands, and data streams on remote computers. 
</li>
          <li>
The WinRM Plug-in API provides functionality that enables a user to write plug-ins
by implementing certain APIs for supported resources and operations. 
</li>
          <li>
WinRM 2.0 introduces a hosting framework. Two hosting models are supported. One is
Internet Information Services (IIS)-based and the other is WinRM service-based. 
</li>
          <li>
Association traversal lets a user retrieve instances of Association classes by using
a standard filtering mechanism. 
</li>
          <li>
WinRM 2.0 supports delegating user credentials across multiple remote computers. 
</li>
          <li>
Users of WinRM 2.0 can use Windows PowerShell cmdlets for system management. 
</li>
          <li>
WinRM has added a specific set of quotas that provide a better quality of service
and allocate server resources to concurrent users. The WinRM quota set is based on
the quota infrastructure that is implemented for the IIS service.</li>
        </ul>
        <h3>System requirements
</h3>
        <p>
          <strong>WinRM 2.0</strong> and <strong>PowerShell 2.0</strong> can be installed on
the following supported operating systems: 
</p>
        <ul>
          <li>
Windows Server 2008 with Service Pack 2 
</li>
          <li>
Windows Server 2003 with Service Pack 2 
</li>
          <li>
Windows Vista with Service Pack 2 
</li>
          <li>
Windows Vista with Service Pack 1 
</li>
          <li>
Windows XP with Service Pack 3</li>
        </ul>
Windows PowerShell 2.0 requires the Microsoft .NET Framework 2.0 with Service Pack
1. 
<p><strong>BITS 4.0</strong></p>
BITS 4.0 can be installed on the following supported operating systems: 
<ul><li>
Windows Server 2008 with Service Pack 2 
</li><li>
Windows Vista with Service Pack 2 
</li><li>
Windows Vista with Service Pack 1</li></ul><img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=7b7a72ad-28d7-4a61-a5a1-3729cae67bd3" /></body>
      <title>PowerShell 2.0 goes RTM for ALL Platforms</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,7b7a72ad-28d7-4a61-a5a1-3729cae67bd3.aspx</guid>
      <link>http://www.nivot.org/2009/10/28/PowerShell20GoesRTMForALLPlatforms.aspx</link>
      <pubDate>Wed, 28 Oct 2009 14:27:29 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;( from: &lt;/em&gt;&lt;a title="http://support.microsoft.com/default.aspx/kb/968929" href="http://support.microsoft.com/default.aspx/kb/968929"&gt;&lt;em&gt;http://support.microsoft.com/default.aspx/kb/968929&lt;/em&gt;&lt;/a&gt;&lt;em&gt; –
downloads at foot of page )&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Windows PowerShell is a command-line shell and scripting language that is designed
for system administration and Automation. Built on the Microsoft .NET Framework, Windows
PowerShell enables IT professionals and developers to control and automate the administration
of Windows and applications.
&lt;/p&gt;
&lt;p&gt;
New features that are introduced in Windows PowerShell 2.0 include the following: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;Remoting&lt;/b&gt;
&lt;br&gt;
Windows PowerShell 2.0 lets you run commands on one or more remote computers from
a single computer that is running Windows PowerShell. PowerShell remoting allows for
multiple ways of connecting. These ways include interactive (1:1), fan-out (1:many),
and fan-in (many:1 by using the IIS hosting model). 
&lt;li&gt;
&lt;b&gt;Integrated Scripting Environment&lt;/b&gt;
&lt;br&gt;
PowerShell Integrated Scripting Environment (ISE) enables you to run interactive commands
and edit and debug scripts in a graphical environment. The main features include color-coded
syntax, selective execution, graphical debugging, Unicode support, and context-sensitive
help. 
&lt;li&gt;
&lt;b&gt;Modules&lt;/b&gt;
&lt;br&gt;
Modules allow for script developers and administrators to partition and organize their
Windows PowerShell code in self-contained, reusable units. Code from a module executes
in its own self-contained context and does not affect the state outside the module. 
&lt;li&gt;
&lt;b&gt;Advanced functions&lt;/b&gt;
&lt;br&gt;
Advanced functions are functions that have the same capabilities and behavior as cmdlets.
However, they are written completely in the Windows PowerShell language, instead of
compiled C#. 
&lt;li&gt;
&lt;b&gt;Background jobs&lt;/b&gt;
&lt;br&gt;
Windows PowerShell 2.0 allows for running a command or expression asynchronously and
"in the background" without interacting with the console. 
&lt;li&gt;
&lt;b&gt;Eventing&lt;/b&gt;
&lt;br&gt;
This feature adds support to the Windows PowerShell engine infrastructure for listening,
forwarding, and acting on management and system events. 
&lt;li&gt;
&lt;b&gt;Script internationalization&lt;/b&gt;
&lt;br&gt;
This new feature enables Windows PowerShell scripts to display messages in the spoken
language that is specified by the UI culture setting on the user's computer. 
&lt;li&gt;
&lt;b&gt;Script debugging&lt;/b&gt;
&lt;br&gt;
New debugging features were added to Windows PowerShell that let you set breakpoints
on lines, columns, variables, and commands, and that let you specify the action that
occurs when the breakpoint is hit. 
&lt;li&gt;
&lt;b&gt;New cmdlets&lt;/b&gt;
&lt;br&gt;
Windows PowerShell 2.0 introduces over 100 built-in cmdlets. These cmdlets, excluding
other tasks, enables you to do computer-related, event log, and performance counter
management tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;WinRM 2.0
&lt;/h3&gt;
&lt;p&gt;
WinRM is the Microsoft implementation of WS-Management Protocol, a standard Simple
Object Access Protocol (SOAP)–based, firewall-friendly protocol that allows for hardware
and operating systems from different vendors to interoperate. The WS-Management Protocol
specification provides a common way for systems to access and exchange management
information across an IT infrastructure.
&lt;/p&gt;
&lt;p&gt;
WinRM 2.0 includes the following new features: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The WinRM Client Shell API provides functionality to create and manage shells and
shell operations, commands, and data streams on remote computers. 
&lt;li&gt;
The WinRM Plug-in API provides functionality that enables a user to write plug-ins
by implementing certain APIs for supported resources and operations. 
&lt;li&gt;
WinRM 2.0 introduces a hosting framework. Two hosting models are supported. One is
Internet Information Services (IIS)-based and the other is WinRM service-based. 
&lt;li&gt;
Association traversal lets a user retrieve instances of Association classes by using
a standard filtering mechanism. 
&lt;li&gt;
WinRM 2.0 supports delegating user credentials across multiple remote computers. 
&lt;li&gt;
Users of WinRM 2.0 can use Windows PowerShell cmdlets for system management. 
&lt;li&gt;
WinRM has added a specific set of quotas that provide a better quality of service
and allocate server resources to concurrent users. The WinRM quota set is based on
the quota infrastructure that is implemented for the IIS service.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;System requirements
&lt;/h3&gt;
&lt;p&gt;
&lt;strong&gt;WinRM 2.0&lt;/strong&gt; and &lt;strong&gt;PowerShell 2.0&lt;/strong&gt; can be installed on
the following supported operating systems: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Windows Server 2008 with Service Pack 2 
&lt;li&gt;
Windows Server 2003 with Service Pack 2 
&lt;li&gt;
Windows Vista with Service Pack 2 
&lt;li&gt;
Windows Vista with Service Pack 1 
&lt;li&gt;
Windows XP with Service Pack 3&lt;/li&gt;
&lt;/ul&gt;
Windows PowerShell 2.0 requires the Microsoft .NET Framework 2.0 with Service Pack
1. 
&lt;p&gt;
&lt;strong&gt;BITS 4.0&lt;/strong&gt;
&lt;/p&gt;
BITS 4.0 can be installed on the following supported operating systems: 
&lt;ul&gt;
&lt;li&gt;
Windows Server 2008 with Service Pack 2 
&lt;li&gt;
Windows Vista with Service Pack 2 
&lt;li&gt;
Windows Vista with Service Pack 1&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=7b7a72ad-28d7-4a61-a5a1-3729cae67bd3" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,7b7a72ad-28d7-4a61-a5a1-3729cae67bd3.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>Microsoft</category>
      <category>Modules</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=cf5692fe-f0ef-4dc7-aa9b-1473df68c984</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,cf5692fe-f0ef-4dc7-aa9b-1473df68c984.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,cf5692fe-f0ef-4dc7-aa9b-1473df68c984.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=cf5692fe-f0ef-4dc7-aa9b-1473df68c984</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <b>Updated</b>: now use a temporary file to set text to avoid overflowing command-line
buffer
</p>
        <p>
The Windows Clipboard – accessible via System.Windows.Forms.Clipboard – requires an
STA thread to read/write to it. By default, the console version of PowerShell 2.0
(i.e. not ISE) starts in MTA mode. This means that read/writing via this class is
unreliable. Rather than always starting up console PowerShell in STA mode via the
–STA flag, you can use this flag in a sneakier way to get what you want:<br /><br /></p>
        <pre class="brush:powershell">
function Set-ClipboardText {
        param($text)

        # need to use temp file to avoid exceeding command-line length limit
        $temp = [io.path]::GetTempFileName()

        try {
            set-content -Path $temp -Value $text

            $command = {
                    add-type -an system.windows.forms
                    [System.Windows.Forms.Clipboard]::SetText((get-content $args))
            }
            
            powershell -sta -noprofile -command $command -args $temp

        } finally {
            if ((test-path $temp)) {
                remove-item $temp
            }
        }
}

function Get-ClipboardText {
        $command = {
                add-type -an system.windows.forms
                [System.Windows.Forms.Clipboard]::GetText()
        }
        powershell -sta -noprofile -command $command
}</pre>
        <p>
Essentially we are running PowerShell as a child process temporarily in STA mode,
skipping loading the profile and executing a scriptblock.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=cf5692fe-f0ef-4dc7-aa9b-1473df68c984" />
      </body>
      <title>PowerShell 2.0 – Getting and setting text to and from the clipboard</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,cf5692fe-f0ef-4dc7-aa9b-1473df68c984.aspx</guid>
      <link>http://www.nivot.org/2009/10/14/PowerShell20GettingAndSettingTextToAndFromTheClipboard.aspx</link>
      <pubDate>Wed, 14 Oct 2009 15:53:35 GMT</pubDate>
      <description>&lt;p&gt;
&lt;b&gt;Updated&lt;/b&gt;: now use a temporary file to set text to avoid overflowing command-line
buffer
&lt;/p&gt;
&lt;p&gt;
The Windows Clipboard – accessible via System.Windows.Forms.Clipboard – requires an
STA thread to read/write to it. By default, the console version of PowerShell 2.0
(i.e. not ISE) starts in MTA mode. This means that read/writing via this class is
unreliable. Rather than always starting up console PowerShell in STA mode via the
–STA flag, you can use this flag in a sneakier way to get what you want:&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;pre class="brush:powershell"&gt;
function Set-ClipboardText {
        param($text)

        # need to use temp file to avoid exceeding command-line length limit
        $temp = [io.path]::GetTempFileName()

        try {
            set-content -Path $temp -Value $text

            $command = {
                    add-type -an system.windows.forms
                    [System.Windows.Forms.Clipboard]::SetText((get-content $args))
            }
            
            powershell -sta -noprofile -command $command -args $temp

        } finally {
            if ((test-path $temp)) {
                remove-item $temp
            }
        }
}

function Get-ClipboardText {
        $command = {
                add-type -an system.windows.forms
                [System.Windows.Forms.Clipboard]::GetText()
        }
        powershell -sta -noprofile -command $command
}&lt;/pre&gt;
&lt;p&gt;
Essentially we are running PowerShell as a child process temporarily in STA mode,
skipping loading the profile and executing a scriptblock.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=cf5692fe-f0ef-4dc7-aa9b-1473df68c984" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,cf5692fe-f0ef-4dc7-aa9b-1473df68c984.aspx</comments>
      <category>.NET</category>
      <category>Monad</category>
      <category>MTA</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>STA</category>
      <category>Threading</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=54bece4d-9670-4ac9-ae3c-6ad3ecbfd841</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,54bece4d-9670-4ac9-ae3c-6ad3ecbfd841.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,54bece4d-9670-4ac9-ae3c-6ad3ecbfd841.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=54bece4d-9670-4ac9-ae3c-6ad3ecbfd841</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Asynchronous callback delegates are not a friend to PowerShell. They are serviced
by the .NET threadpool which means that if they point to script blocks, there will
be no Runspace available to execute them. Runspaces are thread-local resources in
the PowerShell threadpool. The .NET threadpool, operating independently, is not too
interested in coordinating callbacks with PowerShell. So what do we do? 
</p>
        <p>
There is one feature of PowerShell 2.0 that is capable of running scriptblocks in
a pseudo-asynchronous manner: Eventing. Any events bound to with Register-ObjectEvent,
EngineEvent or WmIEvent can have associated scriptblocks that will get executed when
the associated event is raised. So, if we can somehow convert an asynchronous callback
to a .NET event then we can run scriptblocks in response to Async .NET Callbacks.
I’ve written a simple function called New-ScriptBlockCallback that helps us do exactly
that:<br /></p>
        <pre class="brush:powershell">#requires -version 2.0

function New-ScriptBlockCallback {
    param(
        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [scriptblock]$Callback
    )
&lt;#
    .SYNOPSIS
        Allows running ScriptBlocks via .NET async callbacks.

    .DESCRIPTION
        Allows running ScriptBlocks via .NET async callbacks. Internally this is
        managed by converting .NET async callbacks into .NET events. This enables
        PowerShell 2.0 to run ScriptBlocks indirectly through Register-ObjectEvent.         

    .PARAMETER Callback
        Specify a ScriptBlock to be executed in response to the callback.
        Because the ScriptBlock is executed by the eventing subsystem, it only has
        access to global scope. Any additional arguments to this function will be
        passed as event MessageData.
        
    .EXAMPLE
        You wish to run a scriptblock in reponse to a callback. Here is the .NET
        method signature:
        
        void Bar(AsyncCallback handler, int blah)
        
        ps&gt; [foo]::bar((New-ScriptBlockCallback { ... }), 42)                        

    .OUTPUTS
        A System.AsyncCallback delegate.
#&gt;
    # is this type already defined?    
    if (-not ("CallbackEventBridge" -as [type])) {
        Add-Type @"
            using System;
            
            public sealed class CallbackEventBridge
            {
                public event AsyncCallback CallbackComplete = delegate { };

                private CallbackEventBridge() {}

                private void CallbackInternal(IAsyncResult result)
                {
                    CallbackComplete(result);
                }

                public AsyncCallback Callback
                {
                    get { return new AsyncCallback(CallbackInternal); }
                }

                public static CallbackEventBridge Create()
                {
                    return new CallbackEventBridge();
                }
            }
"@
    }
    $bridge = [callbackeventbridge]::create()
    Register-ObjectEvent -input $bridge -EventName callbackcomplete -action $callback -messagedata $args &gt; $null
    $bridge.callback
}
</pre>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=54bece4d-9670-4ac9-ae3c-6ad3ecbfd841" />
      </body>
      <title>PowerShell 2.0 – Asynchronous Callbacks from .NET</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,54bece4d-9670-4ac9-ae3c-6ad3ecbfd841.aspx</guid>
      <link>http://www.nivot.org/2009/10/09/PowerShell20AsynchronousCallbacksFromNET.aspx</link>
      <pubDate>Fri, 09 Oct 2009 18:09:30 GMT</pubDate>
      <description>&lt;p&gt;
Asynchronous callback delegates are not a friend to PowerShell. They are serviced
by the .NET threadpool which means that if they point to script blocks, there will
be no Runspace available to execute them. Runspaces are thread-local resources in
the PowerShell threadpool. The .NET threadpool, operating independently, is not too
interested in coordinating callbacks with PowerShell. So what do we do? 
&lt;/p&gt;
&lt;p&gt;
There is one feature of PowerShell 2.0 that is capable of running scriptblocks in
a pseudo-asynchronous manner: Eventing. Any events bound to with Register-ObjectEvent,
EngineEvent or WmIEvent can have associated scriptblocks that will get executed when
the associated event is raised. So, if we can somehow convert an asynchronous callback
to a .NET event then we can run scriptblocks in response to Async .NET Callbacks.
I’ve written a simple function called New-ScriptBlockCallback that helps us do exactly
that:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="brush:powershell"&gt;#requires -version 2.0

function New-ScriptBlockCallback {
    param(
        [parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [scriptblock]$Callback
    )
&amp;lt;#
    .SYNOPSIS
        Allows running ScriptBlocks via .NET async callbacks.

    .DESCRIPTION
        Allows running ScriptBlocks via .NET async callbacks. Internally this is
        managed by converting .NET async callbacks into .NET events. This enables
        PowerShell 2.0 to run ScriptBlocks indirectly through Register-ObjectEvent.         

    .PARAMETER Callback
        Specify a ScriptBlock to be executed in response to the callback.
        Because the ScriptBlock is executed by the eventing subsystem, it only has
        access to global scope. Any additional arguments to this function will be
        passed as event MessageData.
        
    .EXAMPLE
        You wish to run a scriptblock in reponse to a callback. Here is the .NET
        method signature:
        
        void Bar(AsyncCallback handler, int blah)
        
        ps&amp;gt; [foo]::bar((New-ScriptBlockCallback { ... }), 42)                        

    .OUTPUTS
        A System.AsyncCallback delegate.
#&amp;gt;
    # is this type already defined?    
    if (-not ("CallbackEventBridge" -as [type])) {
        Add-Type @"
            using System;
            
            public sealed class CallbackEventBridge
            {
                public event AsyncCallback CallbackComplete = delegate { };

                private CallbackEventBridge() {}

                private void CallbackInternal(IAsyncResult result)
                {
                    CallbackComplete(result);
                }

                public AsyncCallback Callback
                {
                    get { return new AsyncCallback(CallbackInternal); }
                }

                public static CallbackEventBridge Create()
                {
                    return new CallbackEventBridge();
                }
            }
"@
    }
    $bridge = [callbackeventbridge]::create()
    Register-ObjectEvent -input $bridge -EventName callbackcomplete -action $callback -messagedata $args &amp;gt; $null
    $bridge.callback
}
&lt;/pre&gt;&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=54bece4d-9670-4ac9-ae3c-6ad3ecbfd841" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,54bece4d-9670-4ac9-ae3c-6ad3ecbfd841.aspx</comments>
      <category>.NET</category>
      <category>Eventing</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=b59daeda-8b29-40f6-a624-f6e8a62fba31</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,b59daeda-8b29-40f6-a624-f6e8a62fba31.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,b59daeda-8b29-40f6-a624-f6e8a62fba31.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=b59daeda-8b29-40f6-a624-f6e8a62fba31</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
ArgumentTransformationAttributes are attached to function parameters. They intercept
the value coming in and optionally transform it before it is assigned to the target
parameter. This is how the powershell type system is enforced:
</p>
        <pre class="brush: powershell">function Foo ( [string]$str ) { ... }
(gi function:foo).parameters.str.attributes</pre>
        <pre style="font-size:10pt">TypeId
------
System.Management.Automation.ArgumentTypeConverterAttribute
System.Management.Automation.ParameterAttribute</pre>
        <p>
This type converter derives from ArgumentTransformationAttribute. It uses the public
utility type [Management.Automation.LanguagePrimitives] (which is full of cool stuff
btw) to coerce incoming types to the designated type constraint, in this case [string].
</p>
        <p>
As an aside, you can use the credential attribute on a function parameter too:
</p>
        <pre class="brush: powershell">function do-something ([system.management.automation.credential()]$cred) { $cred }
do-something # get-credential dialog pops up if $cred is not explicitly passed</pre>
        <p>
And while a little strange but definitely empowering from a future extensibility point
of view, you can decorate parameters with entirely inappropriate attributes:
</p>
        <pre class="brush: powershell">function Foo ( [obsolete($true)][string]$bar ) { ... }</pre>
        <p>
          <i>System.ObsoleteAttribute is used in C#/VB.NET to tell the compiler that usage of
the decorated item should raise a warning (false) or error (true)</i>
        </p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=b59daeda-8b29-40f6-a624-f6e8a62fba31" />
      </body>
      <title>PowerShell – Function Parameters &amp; .NET Attributes</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,b59daeda-8b29-40f6-a624-f6e8a62fba31.aspx</guid>
      <link>http://www.nivot.org/2009/10/03/PowerShellFunctionParametersNETAttributes.aspx</link>
      <pubDate>Sat, 03 Oct 2009 00:46:51 GMT</pubDate>
      <description>&lt;p&gt;
ArgumentTransformationAttributes are attached to function parameters. They intercept
the value coming in and optionally transform it before it is assigned to the target
parameter. This is how the powershell type system is enforced:
&lt;/p&gt;
&lt;pre class="brush: powershell"&gt;function Foo ( [string]$str ) { ... }
(gi function:foo).parameters.str.attributes&lt;/pre&gt;
&lt;pre style="font-size:10pt"&gt;TypeId
------
System.Management.Automation.ArgumentTypeConverterAttribute
System.Management.Automation.ParameterAttribute&lt;/pre&gt;
&lt;p&gt;
This type converter derives from ArgumentTransformationAttribute. It uses the public
utility type [Management.Automation.LanguagePrimitives] (which is full of cool stuff
btw) to coerce incoming types to the designated type constraint, in this case [string].
&lt;/p&gt;
&lt;p&gt;
As an aside, you can use the credential attribute on a function parameter too:
&lt;/p&gt;
&lt;pre class="brush: powershell"&gt;function do-something ([system.management.automation.credential()]$cred) { $cred }
do-something # get-credential dialog pops up if $cred is not explicitly passed&lt;/pre&gt;
&lt;p&gt;
And while a little strange but definitely empowering from a future extensibility point
of view, you can decorate parameters with entirely inappropriate attributes:
&lt;/p&gt;
&lt;pre class="brush: powershell"&gt;function Foo ( [obsolete($true)][string]$bar ) { ... }&lt;/pre&gt;
&lt;p&gt;
&lt;i&gt;System.ObsoleteAttribute is used in C#/VB.NET to tell the compiler that usage of
the decorated item should raise a warning (false) or error (true)&lt;/i&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=b59daeda-8b29-40f6-a624-f6e8a62fba31" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,b59daeda-8b29-40f6-a624-f6e8a62fba31.aspx</comments>
      <category>.NET</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=21136a8a-636d-4665-8637-e93a24bbd61d</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,21136a8a-636d-4665-8637-e93a24bbd61d.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,21136a8a-636d-4665-8637-e93a24bbd61d.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=21136a8a-636d-4665-8637-e93a24bbd61d</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One thing that has been lamented frequently about <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> is
that it is very difficult to log, if not impossible, to log all of the various types
of streams it has to a single source. The legacy Windows shell CMD, and Unix shells
like Bash, Ksh etc only deal with three streams: stdin, stdout and stderr for Input,
Ouput and Error respectively. PowerShell has many more: Input, Output, Verbose, Warning,
Debug, Progress and Error. Finally, the APIs in v2.0 offer enough hooks to unify the
logging but you got to work a bit to make it come together. Well, to be honest, you
got me doing the work. The rest is easy ;)
</p>
        <pre class="brush: powershell">import-module .\scriptlogger.psm1 -force

$logger = New-ScriptLogger

# override error handler
$logger.ErrorHandler = {
    param($record)
    
    $record.tostring() &gt;&gt; scriptlog.txt
}

# override verbose handler
$logger.VerboseHandler = {
    param($record)
    
    $record.message &gt;&gt; scriptlog.txt
}

# run scriptblock with logging
$logger.Invoke(
    {
        $verbosepreference='continue';
        $erroractionpreference = 'continue';
        $debugpreference = 'continue';
        write-verbose "verbose";
        write-error "an error";
        write-warning "a warning"
        Write-debug "debug string"
        "this is output"
        1,2,3
    })
</pre>And
here is the module; save it as ScriptLogger.psm1. By default, all logging goes to
an attached debugger, like sysinternals DbgView. You can override any of the handlers
like above and do what you want. Each handler receives one argument: a ErrorRecord,
WarningRecord, VerboseRecord, DebugRecord or ProgressRecord. All of these Types are
native powershell types and are documented on MSDN.<pre class="brush: powershell">&lt;#
    Name     : Universal Script Logging Module (ScriptLogger.psm1)
    Version  : 0.1
    Author   : Oisin Grehan (MVP)
    Site     : http://www.nivot.org/
#&gt;
function New-ScriptLogger {
    New-Module -AsCustomObject -ScriptBlock {
        
        $script:ps              = [powershell]::Create()
        $script:ar              = $null
        $script:module          = $ExecutionContext.SessionState.Module
        
        [scriptblock]
        $script:ErrorHandler    = {
            param(
                [Management.Automation.ErrorRecord]
                $record
            )
            [diagnostics.debug]::writeline(
                "Error: " + $record.tostring());
        }
        [scriptblock]
        $script:WarningHandler  = {
            param(
                [Management.Automation.WarningRecord]
                $record
            )        
            [diagnostics.debug]::writeline(
                "Warning: " + $record.message);
        }
        [scriptblock]
        $script:VerboseHandler  = {
            param(
                [Management.Automation.VerboseRecord]
                $record
            )
            [diagnostics.debug]::writeline(
                "Verbose: " + $record.message);
        }
        [scriptblock]
        $script:DebugHandler    = {
            param(
                [Management.Automation.DebugRecord]
                $record
            )
            [diagnostics.debug]::writeline(
                "Debug: " + $record.message);
        }
        [scriptblock]
        $script:ProgressHandler = {
            param(
                [Management.Automation.ProgressRecord]
                $record
            )        
            [diagnostics.debug]::writeline(
                "Progress: " + $record);
        }
        
        $script:Handlers   = @{
            Error = Register-ObjectEvent $ps.Streams.Error DataAdded -Action {
                &amp; $event.MessageData {&amp; $ErrorHandler @args} $event.sender[$eventargs.index]
            } -MessageData $module #-SupportEvent
            
            Warning = Register-ObjectEvent $ps.Streams.Warning DataAdded -Action {
                &amp; $event.MessageData {&amp; $WarningHandler @args} $event.sender[$eventargs.index]
            } -MessageData $module #-SupportEvent
            
            Verbose = Register-ObjectEvent $ps.Streams.Verbose DataAdded -Action {
                &amp; $event.MessageData {&amp; $VerboseHandler @args} $event.sender[$eventargs.index]
            } -MessageData $module #-SupportEvent
            
            Debug = Register-ObjectEvent $ps.Streams.Debug DataAdded -Action {
                &amp; $event.MessageData {&amp; $DebugHandler @args} $event.sender[$eventargs.index]
            } -MessageData $module #-SupportEvent
            
            Progress = Register-ObjectEvent $ps.Streams.Progress DataAdded -Action {
                &amp; $event.MessageData {&amp; $ProgressHandler @args} $event.sender[$eventargs.index]
            } -MessageData $module #-SupportEvent
        }
        
        function Invoke {
            param(
                [validatenotnullorempty()]
                [scriptblock]$script
            )
            
            try {
            
                write-host -foreground green "Running"
                
                $ps.commands.clear()
                $command = new-object management.automation.runspaces.command $script, $true            
                $ps.commands.addcommand($command) &gt; $null                
                $ps.invoke() # returns output                
            
            } catch {
            
                # oops-ee!
                write-host -foreground red "Unhandled terminating error: $_"
                $record = new-object management.automation.errorrecord $(
                    new-object exception $_.tostring()), "TerminatingError", "NotSpecified", $null
                &amp; $ErrorHandler $record
            
            } finally {
            
                write-host -foreground green "Complete"
            
            }
        }
                
        Export-ModuleMember -Function Invoke -Variable ErrorHandler, WarningHandler, VerboseHandler, DebugHandler, ProgressHandler
    }
}
</pre><p>
Have fun!
</p><img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=21136a8a-636d-4665-8637-e93a24bbd61d" /></body>
      <title>PowerShell 2.0: A Configurable and Flexible Script Logger Module</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,21136a8a-636d-4665-8637-e93a24bbd61d.aspx</guid>
      <link>http://www.nivot.org/2009/08/19/PowerShell20AConfigurableAndFlexibleScriptLoggerModule.aspx</link>
      <pubDate>Wed, 19 Aug 2009 02:58:24 GMT</pubDate>
      <description>&lt;p&gt;
One thing that has been lamented frequently about &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; is
that it is very difficult to log, if not impossible, to log all of the various types
of streams it has to a single source. The legacy Windows shell CMD, and Unix shells
like Bash, Ksh etc only deal with three streams: stdin, stdout and stderr for Input,
Ouput and Error respectively. PowerShell has many more: Input, Output, Verbose, Warning,
Debug, Progress and Error. Finally, the APIs in v2.0 offer enough hooks to unify the
logging but you got to work a bit to make it come together. Well, to be honest, you
got me doing the work. The rest is easy ;)
&lt;/p&gt;
&lt;pre class="brush: powershell"&gt;import-module .\scriptlogger.psm1 -force

$logger = New-ScriptLogger

# override error handler
$logger.ErrorHandler = {
    param($record)
    
    $record.tostring() &amp;gt;&amp;gt; scriptlog.txt
}

# override verbose handler
$logger.VerboseHandler = {
    param($record)
    
    $record.message &amp;gt;&amp;gt; scriptlog.txt
}

# run scriptblock with logging
$logger.Invoke(
    {
        $verbosepreference='continue';
        $erroractionpreference = 'continue';
        $debugpreference = 'continue';
        write-verbose "verbose";
        write-error "an error";
        write-warning "a warning"
        Write-debug "debug string"
        "this is output"
        1,2,3
    })
&lt;/pre&gt;And
here is the module; save it as ScriptLogger.psm1. By default, all logging goes to
an attached debugger, like sysinternals DbgView. You can override any of the handlers
like above and do what you want. Each handler receives one argument: a ErrorRecord,
WarningRecord, VerboseRecord, DebugRecord or ProgressRecord. All of these Types are
native powershell types and are documented on MSDN.&lt;pre class="brush: powershell"&gt;&amp;lt;#
    Name     : Universal Script Logging Module (ScriptLogger.psm1)
    Version  : 0.1
    Author   : Oisin Grehan (MVP)
    Site     : http://www.nivot.org/
#&amp;gt;
function New-ScriptLogger {
    New-Module -AsCustomObject -ScriptBlock {
        
        $script:ps              = [powershell]::Create()
        $script:ar              = $null
        $script:module          = $ExecutionContext.SessionState.Module
        
        [scriptblock]
        $script:ErrorHandler    = {
            param(
                [Management.Automation.ErrorRecord]
                $record
            )
            [diagnostics.debug]::writeline(
                "Error: " + $record.tostring());
        }
        [scriptblock]
        $script:WarningHandler  = {
            param(
                [Management.Automation.WarningRecord]
                $record
            )        
            [diagnostics.debug]::writeline(
                "Warning: " + $record.message);
        }
        [scriptblock]
        $script:VerboseHandler  = {
            param(
                [Management.Automation.VerboseRecord]
                $record
            )
            [diagnostics.debug]::writeline(
                "Verbose: " + $record.message);
        }
        [scriptblock]
        $script:DebugHandler    = {
            param(
                [Management.Automation.DebugRecord]
                $record
            )
            [diagnostics.debug]::writeline(
                "Debug: " + $record.message);
        }
        [scriptblock]
        $script:ProgressHandler = {
            param(
                [Management.Automation.ProgressRecord]
                $record
            )        
            [diagnostics.debug]::writeline(
                "Progress: " + $record);
        }
        
        $script:Handlers   = @{
            Error = Register-ObjectEvent $ps.Streams.Error DataAdded -Action {
                &amp;amp; $event.MessageData {&amp;amp; $ErrorHandler @args} $event.sender[$eventargs.index]
            } -MessageData $module #-SupportEvent
            
            Warning = Register-ObjectEvent $ps.Streams.Warning DataAdded -Action {
                &amp;amp; $event.MessageData {&amp;amp; $WarningHandler @args} $event.sender[$eventargs.index]
            } -MessageData $module #-SupportEvent
            
            Verbose = Register-ObjectEvent $ps.Streams.Verbose DataAdded -Action {
                &amp;amp; $event.MessageData {&amp;amp; $VerboseHandler @args} $event.sender[$eventargs.index]
            } -MessageData $module #-SupportEvent
            
            Debug = Register-ObjectEvent $ps.Streams.Debug DataAdded -Action {
                &amp;amp; $event.MessageData {&amp;amp; $DebugHandler @args} $event.sender[$eventargs.index]
            } -MessageData $module #-SupportEvent
            
            Progress = Register-ObjectEvent $ps.Streams.Progress DataAdded -Action {
                &amp;amp; $event.MessageData {&amp;amp; $ProgressHandler @args} $event.sender[$eventargs.index]
            } -MessageData $module #-SupportEvent
        }
        
        function Invoke {
            param(
                [validatenotnullorempty()]
                [scriptblock]$script
            )
            
            try {
            
                write-host -foreground green "Running"
                
                $ps.commands.clear()
                $command = new-object management.automation.runspaces.command $script, $true            
                $ps.commands.addcommand($command) &amp;gt; $null                
                $ps.invoke() # returns output                
            
            } catch {
            
                # oops-ee!
                write-host -foreground red "Unhandled terminating error: $_"
                $record = new-object management.automation.errorrecord $(
                    new-object exception $_.tostring()), "TerminatingError", "NotSpecified", $null
                &amp;amp; $ErrorHandler $record
            
            } finally {
            
                write-host -foreground green "Complete"
            
            }
        }
                
        Export-ModuleMember -Function Invoke -Variable ErrorHandler, WarningHandler, VerboseHandler, DebugHandler, ProgressHandler
    }
}
&lt;/pre&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=21136a8a-636d-4665-8637-e93a24bbd61d" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,21136a8a-636d-4665-8637-e93a24bbd61d.aspx</comments>
      <category>.NET</category>
      <category>Eventing</category>
      <category>Modules</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=6b25a4df-3ffd-488b-bdae-4ff2ee8a29fd</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,6b25a4df-3ffd-488b-bdae-4ff2ee8a29fd.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,6b25a4df-3ffd-488b-bdae-4ff2ee8a29fd.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=6b25a4df-3ffd-488b-bdae-4ff2ee8a29fd</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve been reliably informed (and double checked) and I’m happy to relay to you all
that <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> 2.0
is available as part of the Windows Management Framework RC. This includes the following
components:
</p>
        <ul>
          <li>
WinRM 2.0</li>
          <li>
Windows PowerShell 2.0</li>
          <li>
BITS 4.0</li>
        </ul>
        <p>
This is the culmination of nearly three years’ of work to bring Windows to the cutting
edge of automation technology. Grab it while it’s toasty from:
</p>
        <p>
          <a title="https://connect.microsoft.com/windowsmanagement/Downloads" href="https://connect.microsoft.com/windowsmanagement/Downloads">https://connect.microsoft.com/windowsmanagement/Downloads</a>
        </p>
        <p>
Spread the word!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=6b25a4df-3ffd-488b-bdae-4ff2ee8a29fd" />
      </body>
      <title>PowerShell 2.0 Now Available for Vista and Server 2008</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,6b25a4df-3ffd-488b-bdae-4ff2ee8a29fd.aspx</guid>
      <link>http://www.nivot.org/2009/08/14/PowerShell20NowAvailableForVistaAndServer2008.aspx</link>
      <pubDate>Fri, 14 Aug 2009 02:06:02 GMT</pubDate>
      <description>&lt;p&gt;
I’ve been reliably informed (and double checked) and I’m happy to relay to you all
that &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; 2.0
is available as part of the Windows Management Framework RC. This includes the following
components:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
WinRM 2.0&lt;/li&gt;
&lt;li&gt;
Windows PowerShell 2.0&lt;/li&gt;
&lt;li&gt;
BITS 4.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
This is the culmination of nearly three years’ of work to bring Windows to the cutting
edge of automation technology. Grab it while it’s toasty from:
&lt;/p&gt;
&lt;p&gt;
&lt;a title="https://connect.microsoft.com/windowsmanagement/Downloads" href="https://connect.microsoft.com/windowsmanagement/Downloads"&gt;https://connect.microsoft.com/windowsmanagement/Downloads&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Spread the word!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=6b25a4df-3ffd-488b-bdae-4ff2ee8a29fd" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,6b25a4df-3ffd-488b-bdae-4ff2ee8a29fd.aspx</comments>
      <category>.NET</category>
      <category>BITS</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>Vista</category>
      <category>Windows 7</category>
      <category>Windows Server 2008</category>
      <category>WinRM</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=cd495bea-3b22-4e22-b6cf-4a73a136e298</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,cd495bea-3b22-4e22-b6cf-4a73a136e298.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,cd495bea-3b22-4e22-b6cf-4a73a136e298.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=cd495bea-3b22-4e22-b6cf-4a73a136e298</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>updated 2009/7/20: added link to PSEventing for v1.0 event handling<br />
updated 2009/7/24: added link to Get-Delegate script for v1.0 callbacks</em>
        </p>
        <p>
There have been some nice improvements made in the latest build of <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> with
respect to interop with the "callback” pattern in .NET. What exactly are callbacks
anyway? It’s exactly what it sounds like, pretty much. In .NET there are sometimes
APIs you need to call that expect you to hand them delegates (pointers to methods)
which that API will call some time in the future, usually based on certain conditions
being fulfilled. If that sounds a bit like .NET events, you’d be right. An event is
a much gussied-up callback - it’s just a way of permitting multiple methods to be
invoked in response to some condition.
</p>
        <h4>Synchronous Callbacks in PowerShell v1.0
</h4>
        <p>
In .NET there are two types of callbacks: Asynchronous (non-blocking) and synchronous
(blocking). In PowerShell v1.0, the only callbacks that were catered for were for <a href="http://msdn.microsoft.com/en-us/library/system.eventhandler.aspx" target="_blank">EventHandler
Delegates</a>. This is the method signature that most of the Windows Forms controls
expect to call back to in response to button clicks etc. You may have seen code similar
to:
</p>
        <p>
        </p>
        <pre class="brush: powershell">$button = new-object system.windows.forms.button
$button.add_Click( { $form.Close() } )
</pre>
        <p>
        </p>
        <p>
This works because in PowerShell v1.0, there is specialized support for this kind
of callback to methods with the EventHandler signature, that is to say, methods with
parameters of (object sender, EventArgs e). PowerShell is able to run the ScriptBlock
in response to the button being clicked and will even pass the two arguments to the
scriptblock for you. When the form is shown from a PowerShell script, there is a single
thread that is running the message loop for the application. It is this same thread
that handles running the script. In the PowerShell engine, there is a pool of threads
created at startup, and each of them has its own “Runspace” for running scripts. Because
it is one of the PowerShell threads that is running the application, that same thread
is able to run the ScriptBlocks in its Runspace when called upon to do so. Although
it is in a slightly roundabout way, this is an example of a synchronous callback.
This single application thread is effectively waiting (blocked) for the callback to
occur in response to a button click (in reality, it’s doing other things while waiting,
but it’s still waiting.)
</p>
        <p>
Some rather creative folks, namely one of the primary developers of PowerShell, wrote
a delegate/scriptblock binder in pure script some years ago which you can use to pass
script to a .NET api to be called back to in a synchronous manner.  See: <a href="http://blogs.msdn.com/powershell/archive/2006/07/25/678259.aspx" target="_blank">Creating
arbitrary delegates to ScriptBlocks</a>.
</p>
        <p>
If you want to work with .NET events in version 1.0 of PowerShell, you’ll need an
add-on, like my <a href="http://www.nivot.org/2008/06/06/PSEventing11ForPowerShell10FinalRelease.aspx" target="_blank">PSEventing
Snap-In</a>.
</p>
        <h4>Synchronous Callbacks in PowerShell v2.0
</h4>
        <p>
In the latest and greatest version of PowerShell, v2.0 RC (which comes with the public
Windows 7 RC), synchronous callbacks got a whole lot easier. PowerShell is now able
to deal with pretty much ANY delegate signature, automatically. Lets test this by
using the .NET 3.5 System.Func&lt;T, TResult&gt; delegate. This is a generic delegate
which lets us pass a method to an API expecting a callback to a method which has one
parameters of type T1, and will return type T2. Because it’s generic, we get to pick
which parameters. Lets demo creating a ScriptBlock that will be passed a DateTime
and returns a String:
</p>
        <p>
        </p>
        <pre class="brush: powershell">add-type –assembly system.core # load .net 3.5
$callback = [system.func[datetime, string]] { param($date); "the date is $date" }
$callback.Invoke( [datetime]::now )
# returns
”the date is 2009/07/14 21:50:35”
</pre>
        <p>
        </p>
        <p>
We can even take advantage of PowerShell’s super-versatile parameter binder by passing
it in a string and having it get coerced to DateTime with ne’er a Parse in sight!
</p>
        <p>
        </p>
        <pre class="brush: powershell">$callback.Invoke(“1/1/2009”)
”the date is 2009/01/01 00:00:00”
</pre>
        <p>
        </p>
        <p>
So, what’s the point of all this? Why go to all that trouble? Why not just write a
function? The point is that functions cannot be called by .NET directly. So when would
you need a callback like this in a PowerShell script? 
</p>
        <h5>Calling Web Services with Invalid, Untrusted or Expired SSL Certificates
</h5>
        <p>
The title says it all – sometimes you need to do this. Usually it’s because you’re
working with self-signed, expired or otherwise invalid certificates on a QA or Development
system. The <a href="http://technet.microsoft.com/en-us/library/dd315258.aspx" target="_blank">New-WebServiceProxy</a> Cmdlet
in v2.0 is great for calling Web Services, but it doesn’t have a switch to ignore
invalid certificates. If you were writing .NET code in C# or VB.NET, the way go about
this is to pass a callback method to an API that expects a <a href="http://msdn.microsoft.com/en-ca/library/system.net.security.remotecertificatevalidationcallback.aspx" target="_blank">RemoteCertificateValidationCallback
Delegate</a>. This delegate is designed to point to a method that is passed a handful
of arguments describing the attempted connection, and is expected to return a boolean;
that is to say, true or false. True means “sure, the connection looks fine – go for
it.” A value of False being returned tells .NET to stop the connection before it happens.
</p>
        <p>
The amount of .NET code needed to do this is not a ton, but it’s still a fair handful
of lines. Check out this example here: <a title="http://blog.jameshiggs.com/2008/05/01/c-how-to-accept-an-invalid-ssl-certificate-programmatically/" href="http://blog.jameshiggs.com/2008/05/01/c-how-to-accept-an-invalid-ssl-certificate-programmatically/">http://blog.jameshiggs.com/2008/05/01/c-how-to-accept-an-invalid-ssl-certificate-programmatically/</a></p>
        <p>
Now let’s see how much PowerShell script is needed for this same task:
</p>
        <pre class="brush: powershell">[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }</pre>
        <p>
Bwahahahah! Eat that, Mr. C# coder! Again, PowerShell’s binder comes into play here
and automatically casts our ScriptBlock to a RemoteCertificateValidateCallback delegate
(it’s not really a cast – there is no conversion – it’s a sizeable chunk of code.)
From this point on, any attempts to use the New-WebServiceProxy Cmdlet with dodgy
SSL certificates will succeed without so much as a warning. In fact, pretty much any
other classes, like WebRequest will behave the same way. It’s important to note that
this only affects the current AppDomain, that is to say, the current PowerShell process.
Other processes on the system will continue to stick their nose up at dodgy SSL certs.
Quit PowerShell and restart it -- or set that ServerCertificateValidationCallback
property to $null -- and all is right in the world again. This works as long as you
use one of PowerShell’s threads to do the work of connecting; i.e. don’t use an asynchronous
request. This ensures there is a Runspace available to execute this ScriptBlock.
</p>
        <h5>Converting Synchronous Callbacks into Events
</h5>
        <p>
This is really quite straightforward. Taking the previous example, we would generate
an event inside the scriptblock using <a href="http://technet.microsoft.com/en-us/library/dd315406.aspx" target="_blank">New-Event</a>,
and then bind one or more event handlers using the <a href="http://technet.microsoft.com/en-us/library/dd315290.aspx" target="_blank">Register-EngineEvent</a> Cmdlet:
</p>
        <pre class="brush: powershell">[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {
		new-event -SourceIdentifier SslCheck -MessageData $args &gt; $null
		$true
	}
# dump out arguments to cert validate callback
Register-EngineEvent -SourceIdentifier SslCheck -Action { write-output $args }
</pre>Next
time, we'll get into some meatier stuff. Have fun! 
<p><em>In Part Two: Asynchronous Callbacks in PowerShell v1.0 and v2.0</em></p><img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=cd495bea-3b22-4e22-b6cf-4a73a136e298" /></body>
      <title>PowerShell 2.0 RC: Working with .NET Callbacks – Part 1 - Synchronous</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,cd495bea-3b22-4e22-b6cf-4a73a136e298.aspx</guid>
      <link>http://www.nivot.org/2009/07/18/PowerShell20RCWorkingWithNETCallbacksPart1Synchronous.aspx</link>
      <pubDate>Sat, 18 Jul 2009 08:22:00 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;updated 2009/7/20: added link to PSEventing for v1.0 event handling&lt;br&gt;
updated 2009/7/24: added link to Get-Delegate script for v1.0 callbacks&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
There have been some nice improvements made in the latest build of &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; with
respect to interop with the "callback” pattern in .NET. What exactly are callbacks
anyway? It’s exactly what it sounds like, pretty much. In .NET there are sometimes
APIs you need to call that expect you to hand them delegates (pointers to methods)
which that API will call some time in the future, usually based on certain conditions
being fulfilled. If that sounds a bit like .NET events, you’d be right. An event is
a much gussied-up callback - it’s just a way of permitting multiple methods to be
invoked in response to some condition.
&lt;/p&gt;
&lt;h4&gt;Synchronous Callbacks in PowerShell v1.0
&lt;/h4&gt;
&lt;p&gt;
In .NET there are two types of callbacks: Asynchronous (non-blocking) and synchronous
(blocking). In PowerShell v1.0, the only callbacks that were catered for were for &lt;a href="http://msdn.microsoft.com/en-us/library/system.eventhandler.aspx" target="_blank"&gt;EventHandler
Delegates&lt;/a&gt;. This is the method signature that most of the Windows Forms controls
expect to call back to in response to button clicks etc. You may have seen code similar
to:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class="brush: powershell"&gt;$button = new-object system.windows.forms.button
$button.add_Click( { $form.Close() } )
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
This works because in PowerShell v1.0, there is specialized support for this kind
of callback to methods with the EventHandler signature, that is to say, methods with
parameters of (object sender, EventArgs e). PowerShell is able to run the ScriptBlock
in response to the button being clicked and will even pass the two arguments to the
scriptblock for you. When the form is shown from a PowerShell script, there is a single
thread that is running the message loop for the application. It is this same thread
that handles running the script. In the PowerShell engine, there is a pool of threads
created at startup, and each of them has its own “Runspace” for running scripts. Because
it is one of the PowerShell threads that is running the application, that same thread
is able to run the ScriptBlocks in its Runspace when called upon to do so. Although
it is in a slightly roundabout way, this is an example of a synchronous callback.
This single application thread is effectively waiting (blocked) for the callback to
occur in response to a button click (in reality, it’s doing other things while waiting,
but it’s still waiting.)
&lt;/p&gt;
&lt;p&gt;
Some rather creative folks, namely one of the primary developers of PowerShell, wrote
a delegate/scriptblock binder in pure script some years ago which you can use to pass
script to a .NET api to be called back to in a synchronous manner.&amp;nbsp; See: &lt;a href="http://blogs.msdn.com/powershell/archive/2006/07/25/678259.aspx" target="_blank"&gt;Creating
arbitrary delegates to ScriptBlocks&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
If you want to work with .NET events in version 1.0 of PowerShell, you’ll need an
add-on, like my &lt;a href="http://www.nivot.org/2008/06/06/PSEventing11ForPowerShell10FinalRelease.aspx" target="_blank"&gt;PSEventing
Snap-In&lt;/a&gt;.
&lt;/p&gt;
&lt;h4&gt;Synchronous Callbacks in PowerShell v2.0
&lt;/h4&gt;
&lt;p&gt;
In the latest and greatest version of PowerShell, v2.0 RC (which comes with the public
Windows 7 RC), synchronous callbacks got a whole lot easier. PowerShell is now able
to deal with pretty much ANY delegate signature, automatically. Lets test this by
using the .NET 3.5 System.Func&amp;lt;T, TResult&amp;gt; delegate. This is a generic delegate
which lets us pass a method to an API expecting a callback to a method which has one
parameters of type T1, and will return type T2. Because it’s generic, we get to pick
which parameters. Lets demo creating a ScriptBlock that will be passed a DateTime
and returns a String:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class="brush: powershell"&gt;add-type –assembly system.core # load .net 3.5
$callback = [system.func[datetime, string]] { param($date); "the date is $date" }
$callback.Invoke( [datetime]::now )
# returns
”the date is 2009/07/14 21:50:35”
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We can even take advantage of PowerShell’s super-versatile parameter binder by passing
it in a string and having it get coerced to DateTime with ne’er a Parse in sight!
&lt;/p&gt;
&lt;p&gt;
&lt;pre class="brush: powershell"&gt;$callback.Invoke(“1/1/2009”)
”the date is 2009/01/01 00:00:00”
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
So, what’s the point of all this? Why go to all that trouble? Why not just write a
function? The point is that functions cannot be called by .NET directly. So when would
you need a callback like this in a PowerShell script? 
&lt;/p&gt;
&lt;h5&gt;Calling Web Services with Invalid, Untrusted or Expired SSL Certificates
&lt;/h5&gt;
&lt;p&gt;
The title says it all – sometimes you need to do this. Usually it’s because you’re
working with self-signed, expired or otherwise invalid certificates on a QA or Development
system. The &lt;a href="http://technet.microsoft.com/en-us/library/dd315258.aspx" target="_blank"&gt;New-WebServiceProxy&lt;/a&gt; Cmdlet
in v2.0 is great for calling Web Services, but it doesn’t have a switch to ignore
invalid certificates. If you were writing .NET code in C# or VB.NET, the way go about
this is to pass a callback method to an API that expects a &lt;a href="http://msdn.microsoft.com/en-ca/library/system.net.security.remotecertificatevalidationcallback.aspx" target="_blank"&gt;RemoteCertificateValidationCallback
Delegate&lt;/a&gt;. This delegate is designed to point to a method that is passed a handful
of arguments describing the attempted connection, and is expected to return a boolean;
that is to say, true or false. True means “sure, the connection looks fine – go for
it.” A value of False being returned tells .NET to stop the connection before it happens.
&lt;/p&gt;
&lt;p&gt;
The amount of .NET code needed to do this is not a ton, but it’s still a fair handful
of lines. Check out this example here: &lt;a title="http://blog.jameshiggs.com/2008/05/01/c-how-to-accept-an-invalid-ssl-certificate-programmatically/" href="http://blog.jameshiggs.com/2008/05/01/c-how-to-accept-an-invalid-ssl-certificate-programmatically/"&gt;http://blog.jameshiggs.com/2008/05/01/c-how-to-accept-an-invalid-ssl-certificate-programmatically/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Now let’s see how much PowerShell script is needed for this same task:
&lt;/p&gt;
&lt;pre class="brush: powershell"&gt;[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }&lt;/pre&gt;
&lt;p&gt;
Bwahahahah! Eat that, Mr. C# coder! Again, PowerShell’s binder comes into play here
and automatically casts our ScriptBlock to a RemoteCertificateValidateCallback delegate
(it’s not really a cast – there is no conversion – it’s a sizeable chunk of code.)
From this point on, any attempts to use the New-WebServiceProxy Cmdlet with dodgy
SSL certificates will succeed without so much as a warning. In fact, pretty much any
other classes, like WebRequest will behave the same way. It’s important to note that
this only affects the current AppDomain, that is to say, the current PowerShell process.
Other processes on the system will continue to stick their nose up at dodgy SSL certs.
Quit PowerShell and restart it -- or set that ServerCertificateValidationCallback
property to $null -- and all is right in the world again. This works as long as you
use one of PowerShell’s threads to do the work of connecting; i.e. don’t use an asynchronous
request. This ensures there is a Runspace available to execute this ScriptBlock.
&lt;/p&gt;
&lt;h5&gt;Converting Synchronous Callbacks into Events
&lt;/h5&gt;
&lt;p&gt;
This is really quite straightforward. Taking the previous example, we would generate
an event inside the scriptblock using &lt;a href="http://technet.microsoft.com/en-us/library/dd315406.aspx" target="_blank"&gt;New-Event&lt;/a&gt;,
and then bind one or more event handlers using the &lt;a href="http://technet.microsoft.com/en-us/library/dd315290.aspx" target="_blank"&gt;Register-EngineEvent&lt;/a&gt; Cmdlet:
&lt;/p&gt;
&lt;pre class="brush: powershell"&gt;[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {
		new-event -SourceIdentifier SslCheck -MessageData $args &amp;gt; $null
		$true
	}
# dump out arguments to cert validate callback
Register-EngineEvent -SourceIdentifier SslCheck -Action { write-output $args }
&lt;/pre&gt;Next
time, we'll get into some meatier stuff. Have fun! 
&lt;p&gt;
&lt;em&gt;In Part Two: Asynchronous Callbacks in PowerShell v1.0 and v2.0&lt;/em&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=cd495bea-3b22-4e22-b6cf-4a73a136e298" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,cd495bea-3b22-4e22-b6cf-4a73a136e298.aspx</comments>
      <category>.NET</category>
      <category>CTP3</category>
      <category>Eventing</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>PSCX</category>
      <category>RC</category>
      <category>Windows 7</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=d1ecaa42-6645-4ada-a827-6ae717b338ad</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,d1ecaa42-6645-4ada-a827-6ae717b338ad.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,d1ecaa42-6645-4ada-a827-6ae717b338ad.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=d1ecaa42-6645-4ada-a827-6ae717b338ad</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <i>
            <b>update</b>: missing backtick ` to escape the $verbosepreference variable</i>
        </p>
        <p>
A question came up on <a href=" http://www.stackoverflow.com/" target="_blank">stack
overflow</a> (you don’t know what that is? shame on you!) today from someone asking
how they could capture the Verbose stream from a pipeline they ran in a C# program.
As it turns out, the same technique is used in script, so I’ll give that example instead
since I’m sure the C# guys and gals will have no problem converting the script. 
</p>
        <p>
The key is using the new (to v2.0) System.Management.Automation.<a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> Type,
which has a built-in Type Accelerator of [powershell]. It has a static method, Create,
which is used to create an instance. This instance is pretty much ready to roll. It
has a Streams property, which is of Type PSDataStreams. This Type has properties representing
each collection of Error, Progress, Verbose, Debug and Warning.
</p>
        <pre class="brush: powershell">
$ps = [powershell]::create()
$ps.Commands.AddScript("`$verbosepreference='continue'; write-verbose 42")
$ps.invoke()
$ps.streams.verbose
</pre>
Which yields the VerboseRecord that was written out: <pre>
Message InvocationInfo                              PipelineIterationInfo
------- --------------                              ---------------------
42      System.Management.Automation.InvocationInfo {0, 0}
</pre>
What's important to note about the above example is that I had to set the $verbosepreference
to at least "continue" (the default is silentlycontinue) in order for the verbose
record to be written. Have fun! <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=d1ecaa42-6645-4ada-a827-6ae717b338ad" /></body>
      <title>PowerShell 2.0: Quick Tip – Capture Verbose, Error &amp; Warning Streams</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,d1ecaa42-6645-4ada-a827-6ae717b338ad.aspx</guid>
      <link>http://www.nivot.org/2009/07/18/PowerShell20QuickTipCaptureVerboseErrorWarningStreams.aspx</link>
      <pubDate>Sat, 18 Jul 2009 04:02:53 GMT</pubDate>
      <description>&lt;p&gt;
&lt;i&gt;&lt;b&gt;update&lt;/b&gt;: missing backtick ` to escape the $verbosepreference variable&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
A question came up on &lt;a href=" http://www.stackoverflow.com/" target="_blank"&gt;stack
overflow&lt;/a&gt; (you don’t know what that is? shame on you!) today from someone asking
how they could capture the Verbose stream from a pipeline they ran in a C# program.
As it turns out, the same technique is used in script, so I’ll give that example instead
since I’m sure the C# guys and gals will have no problem converting the script. 
&lt;/p&gt;
&lt;p&gt;
The key is using the new (to v2.0) System.Management.Automation.&lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; Type,
which has a built-in Type Accelerator of [powershell]. It has a static method, Create,
which is used to create an instance. This instance is pretty much ready to roll. It
has a Streams property, which is of Type PSDataStreams. This Type has properties representing
each collection of Error, Progress, Verbose, Debug and Warning.
&lt;/p&gt;
&lt;pre class="brush: powershell"&gt;
$ps = [powershell]::create()
$ps.Commands.AddScript("`$verbosepreference='continue'; write-verbose 42")
$ps.invoke()
$ps.streams.verbose
&lt;/pre&gt;
Which yields the VerboseRecord that was written out: &lt;pre&gt;
Message InvocationInfo                              PipelineIterationInfo
------- --------------                              ---------------------
42      System.Management.Automation.InvocationInfo {0, 0}
&lt;/pre&gt;
What's important to note about the above example is that I had to set the $verbosepreference
to at least "continue" (the default is silentlycontinue) in order for the verbose
record to be written. Have fun! &lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=d1ecaa42-6645-4ada-a827-6ae717b338ad" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,d1ecaa42-6645-4ada-a827-6ae717b338ad.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>RC</category>
      <category>Windows 7</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=f789804c-5a35-4d5c-a303-d1a2bdc6bbc0</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,f789804c-5a35-4d5c-a303-d1a2bdc6bbc0.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,f789804c-5a35-4d5c-a303-d1a2bdc6bbc0.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=f789804c-5a35-4d5c-a303-d1a2bdc6bbc0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>
            <strong>update #1 2009/5/23</strong>: noted that local jobs (start-job) no longer
require an elevated shell.</em>
        </p>
        <p>
          <em>
            <strong>update #2 2009/5/28:</strong> ISE object model and shortcut changes; update
for set-psessionconfiguration cmdlet (new screenshot); module changes (highlighted
new manifest member names, binary module can now be root module); </em>
        </p>
        <p>
I’ve been meaning to write this for a while, but it’s been a busy time. This is a
comparison of the significant differences between the standalone CTP3 or Windows 7
Beta version and the version that comes with Win7 RC (6.1.7100.0). For all intents
and purposes, the CTP3 version (6.1.6469.0) is <em>exactly</em> the same as the Windows
7 Beta (6.1.7000.0) version.
</p>
        <p>
This is not going to be an exhaustive list of differences, but I will continue to
update this post as I find more things worth documenting. It should be safe to bookmark
the permalink. One of the nicest things about this release is that it appears that,
without exception, <strong>all built-in Cmdlets have help.</strong> A lot of things
have been cleaned up and fixed in this build, from formatting of text to typos and
minor bugs/glitches. 
</p>
        <h4>Cmdlet Differences
</h4>
        <p>
This is a table listing Cmdlets that have either <span class="changed">changed</span> (navy),
been <span class="added">added</span> (green, underlined) or <span class="removed">removed</span> (red,
strike-through.) Changed Cmdlets have their parameters listed in the second column.
A changed parameter means that its Type has been changed; e.g. it accepts a different
.NET object than before. This is generally nothing to worry about since the corresponding
source of such objects is usually changed to match – typically another Cmdlet. Parameters 
and Cmdlets that have not changed, are not listed. 
</p>
        <p>
          <style type="text/css">
            <!--
        #tbl td
        {
            vertical-align: top;
            font-size: 10pt;
        }
        .added
        {
            color: green;
            text-decoration: underline;
        }
        .removed
        {
            color: red;
            text-decoration: line-through;
        }
        .changed
        {
            color: navy;
        }
        .cmdlet
        {
            font-weight: bold;
            cursor: hand;
        }
        .param
        {
            font-style: italic;
            text-align: left;
        }
        .style1
        {
            width: 19px;
        }
    -->
          </style>
          <table id="tbl" border="1" width="600">
            <thead>
              <tr>
                <th>
Cmdlet</th>
                <th>
Parameters</th>
              </tr>
            </thead>
            <tbody>
              <tr style="background-color: white">
                <td class="changed cmdlet">
Invoke-Command 
</td>
                <td>
                  <table id="pInvoke-Command" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="param removed">
NoCompression 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="param changed">
Session 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="param changed">
SessionOption 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: #f0f0f0">
                <td class="changed cmdlet">
Remove-Computer 
</td>
                <td>
                  <table id="pRemove-Computer" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
Force 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
Reboot 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
ComputerName 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: white">
                <td class="changed cmdlet">
Add-Computer 
</td>
                <td>
                  <table id="pAdd-Computer" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
ComputerName 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
Reboot 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: #f0f0f0">
                <td class="removed cmdlet">
Rename-Computer 
</td>
                <td>
                </td>
              </tr>
              <tr style="background-color: white">
                <td class="changed cmdlet">
Test-Connection 
</td>
                <td>
                  <table id="pTest-Connection" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
ComputerName 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
Quiet 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
Destination 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: #f0f0f0">
                <td class="changed cmdlet">
Export-FormatData 
</td>
                <td>
                  <table id="pExport-FormatData" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
 </td>
                        <td class="added param">
Path 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
FilePath 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: white">
                <td class="changed cmdlet">
Receive-Job 
</td>
                <td>
                  <table id="pReceive-Job" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="param changed">
Session 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: #f0f0f0">
                <td class="changed cmdlet">
Start-Job 
</td>
                <td>
                  <table id="pStart-Job" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
InitializationScript 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
RunAs32 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
ConfigurationName 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
CertificateThumbprint 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
NoCompression 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: white">
                <td class="changed cmdlet">
Get-Module 
</td>
                <td>
                  <table id="pGet-Module" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
Recurse 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: #f0f0f0">
                <td class="changed cmdlet">
New-ModuleManifest 
</td>
                <td>
                  <table id="pNew-ModuleManifest" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
ProcessorArchitecture 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
DotNetFrameworkVersion 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
PowerShellHostName 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
PowerShellHostVersion 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
FileList 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
ModuleList 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
FunctionsToExport 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
AliasesToExport 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
VariablesToExport 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
CmdletsToExport 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
OtherFiles 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
ExportedFunctions 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
ExportedAliases 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
ExportedVariables 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
ExportedCmdlets 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="param changed">
RequiredModules 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: white">
                <td class="changed cmdlet">
Set-PSBreakpoint 
</td>
                <td>
                  <table id="pSet-PSBreakpoint" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="param changed">
Script 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: #f0f0f0">
                <td class="added cmdlet">
Enable-PSRemoting 
</td>
              </tr>
              <tr style="background-color: white">
                <td class="changed cmdlet">
Remove-PSSession 
</td>
                <td>
                  <table id="pRemove-PSSession" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="param changed">
Session 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: #f0f0f0">
                <td class="changed cmdlet">
Enter-PSSession 
</td>
                <td>
                  <table id="pEnter-PSSession" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
NoCompression 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="changed param">
Session 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="changed param">
SessionOption 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: white">
                <td class="changed cmdlet">
New-PSSession 
</td>
                <td>
                  <table id="pNew-PSSession" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
NoCompression 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="changed param">
Session 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="changed param">
SessionOption 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: #f0f0f0">
                <td class="changed cmdlet">
Export-PSSession 
</td>
                <td>
                  <table id="pExport-PSSession" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
OutputModule 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
Module 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
ModuleName 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
PSSnapin 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="changed param">
Session 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: white">
                <td class="changed cmdlet">
Import-PSSession 
</td>
                <td>
                  <table id="pImport-PSSession" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
Module 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
PSSnapin 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="changed param">
Session 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: #f0f0f0">
                <td class="added cmdlet">
New-PSSessionOption 
</td>
              </tr>
              <tr style="background-color: white">
                <td class="changed cmdlet">
Get-WSManInstance 
</td>
                <td>
                  <table id="pGet-WSManInstance" class="hidden" width="100%">
                    <tbody>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
Associations 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="added param">
CertificateThumbprint 
</td>
                      </tr>
                      <tr>
                        <td class="style1">
  
</td>
                        <td class="removed param">
References 
</td>
                      </tr>
                    </tbody>
                  </table>
                </td>
              </tr>
              <tr style="background-color: #f0f0f0">
                <td class="changed cmdlet">
Set-PSSessionConfiguration</td>
                <td class="added param">
ShowSecurityDescriptorUI</td>
              </tr>
            </tbody>
          </table>
        </p>
        <h4>Alias Changes
</h4>
        <p>
Some tweaking of aliases here. Personally I find alias changes in general to get under
my skin. Aliases are the first thing I learn and the first thing to trip me up when
things change. Regardless, the changes appear to make sense and are perhaps a bit
more mnemonic than before. 
</p>
        <p>
          <strong>Removed</strong>
        </p>
        <p>
          <span class="removed">emm</span> (Export-ModuleMember), <span class="removed">which</span> (Get-Command)
and <span class="removed">grid</span> (Out-Gridview)
</p>
        <p>
          <strong>Added</strong>
        </p>
        <p>
          <span class="added">ise</span> (powershell_ise.exe), <span class="added">rmo</span> (Remove-Module)
and <span class="added">saps</span> (Start-Process)
</p>
        <p>
          <strong>Changed</strong>
        </p>
        <p>
          <span class="changed">imo –&gt; ipmo</span> (Import-Module)
</p>
        <h4>Language Enhancements
</h4>
        <p>
The major change that has come to light so far is that statements are now allowed
on the right hand of an expression without having to use subexpressions. This is a
great fix, and one that will reduce the margin for error (and confusion) by a large
amount. Previously in CTP3, in order to use a statement like “if”, you had to use
the following syntax:
</p>
        <p>
        </p>
        <pre class="brush: posh">$result = $( if ($true) { 42 } )</pre>
        <p>
        </p>
        <p>
Now, you can drop the $( and ):
</p>
        <p>
        </p>
        <pre class="brush: posh">$result = if ($true) { 42 }</pre>
        <p>
        </p>
        <p>
or
</p>
        <p>
        </p>
        <pre class="brush: posh">$sequence = foreach ($i in 0..15) { [math]::pow(2, $i) }</pre>
        <p>
        </p>
        <p>
This is truly great stuff. 
</p>
        <h4>Jobs/Remoting
</h4>
        <p>
The best news here is the abundant help now available at your fingertips. Lots of
examples and meaty information concerning PSSessions and PSSessionConfigurations.
</p>
        <p>
          <strong>Local Jobs</strong>
        </p>
        <p>
Local jobs created now with Start-Job { ... } use an IPC channel to talk to the local
WinRM service to create jobs instead of using the more heavyweight HTTP channel. Yes,
you can infer from this that local jobs are still out of process; they run in their
own isolated runspace and have no access to the interactive session. What this means
in simpler terms is that local jobs are a lot faster now to get started. The biggest
win for local jobs is that <strong>they no longer require an elevated shell!</strong> you
can submit local jobs as a regular user now – just not remote ones (unless the applicable
remote PSSessionConfiguration is set to allow this - by default the ACL is admins
only).
</p>
        <p>
          <strong>Remoting</strong>
        </p>
        <p>
A welcome addition to this build is a new, dedicated <strong>Enable-PSRemoting</strong> Cmdlet:
</p>
        <p>
        </p>
        <div style="padding-bottom: 5px; background-color: #eeeeee; margin: 20px; padding-left: 5px; padding-right: 5px; padding-top: 5px">The
Enable-PSRemoting cmdlet configures the computer to receive Windows PowerShell remote
commands that are sent by using the WS-Management technology. 
<p></p><p>
You need to run this command only once on each computer that will receive commands.
You do not need to run it on computers that only send commands. Because the configuration
activates listeners, it is prudent to run it only where it is needed.
</p><p>
The Enable-PSRemoting cmdlet performs the following operations: 
</p><ul><li>
Runs the Set-WSManQuickConfig cmdlet, which performs the following tasks: 
<ul><li>
Starts the WinRM service. 
</li><li>
Sets the startup type on the WinRM service to Automatic. 
</li><li>
Creates a listener to accept requests on any IP address. 
</li><li>
Enables a firewall exception for WS-Management communications. 
</li></ul></li><li>
Enables all registered Windows PowerShell session configurations to receive instructions
from a remote computer. 
<ul><li>
Registers the "Microsoft.PowerShell" session configuration, if it is not already registered. 
</li><li>
Registers the "Microsoft.PowerShell32" session configuration on 64-bit computers,
if it is not already registered. 
</li><li>
Removes the "Deny Everyone" setting from the security descriptor for all the registered
session configurations. 
</li><li>
Restarts the WinRM service to make the preceding changes effective. 
</li></ul></li></ul></div>
        <p>
        </p>
        <p>
To run this cmdlet on Windows Vista, Windows Server 2008, and later versions of Windows,
you must start Windows PowerShell with the "Run as administrator" option. 
</p>
        <p>
          <strong>Session Configurations</strong>
        </p>
        <p>
There are a raft of Cmdlets dedicated to managing session configurations. So what
is a session configuration? To qoute the ever-present help system:
</p>
        <div style="padding-bottom: 5px; background-color: #eeeeee; margin: 20px; padding-left: 5px; padding-right: 5px; padding-top: 5px">
          <p>
A session configuration is a group of settings on the local computer that define the
environment for the Windows PowerShell sessions that are created when remote users
connect to the local computer.
</p>
          <p>
Administrators of the computer can use session configurations to protect the computer
and to define custom environments for users who connect to the computer.
</p>
          <p>
Administrators can also use session configurations to determine the permissions that
are required to connect to the computer remotely. By default, only members of the
Administrators group have permission to use the session configuration to connect remotely,
but you can change the default settings to allow all users, or selected users, to
connect remotely to your computer.
</p>
          <p>
Session configurations are a feature of Web Services for Management (WS-Management)
based Windows PowerShell remoting. They are used only when you use the New-PSSession,
Invoke-Command, or Enter-PSSession cmdlets to connect to a remote computer.
</p>
          <p>
            <strong>Note</strong>: To manage the session configurations on a computer that is
running Windows Vista, Windows Server 2008, or a later version of Windows, start Windows
PowerShell with the "Run as administrator" option.
</p>
        </div>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerSh.0DifferencesBetweenCTP3andWin7RC_D88A/image_2.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerSh.0DifferencesBetweenCTP3andWin7RC_D88A/image_thumb.png" width="640" height="300" />
          </a>
        </p>
        <p>
That SecurityDescriptorSddl property looks like a lot of fun to modify, right? Don’t
worry, the <strong>ShowSecurityDescriptorUI</strong> comes to the rescue:
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0DifferencesBetweenCTP3Win7BetaandWi_8776/image_2.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0DifferencesBetweenCTP3Win7BetaandWi_8776/image_thumb.png" width="510" height="480" />
          </a>
        </p>
        <p>
        </p>
        <h3>Modules
</h3>
        <h5>Manifest Members
</h5>
        <p>
Modules have received some nice incremental improvements as well as some syntactic
changes. You should have noticed above that the manifest fields (exposed as parameters
on New-ModuleManifest)  have changed to reflect the two-stage process of how
a module’s members get exposed to the importer’s scope. A module passively <em>exports</em> members
with Export-ModuleMember, and the caller actively <em>imports</em> them with Import-Module;
hence “FunctionsToExport,” which subtly says that this can be imported.
</p>
        <p>
          <strong>Binary Modules</strong>
        </p>
        <p>
A binary module is now allowed to be the root module in a manifest by pointing the
ModuleToProcess key at the assembly, e.g. ModuleToProcess = “Pscx.dll.” This seems
more intuitive than before with the [seemingly] arbitrary restriction that they must
be secondary to a text based psm1.
</p>
        <h4>Built-In Modules
</h4>
        <p>
Shipping with Windows 7 for <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> comes
two new Modules along with the others you should have noticed that arrived with CTP3
(BitsTransfer/FileTransfer and PSDiagnostics.)
</p>
        <p>
          <strong>AppLocker</strong>
        </p>
        <blockquote>
          <p>
AppLocker provides simple, powerful, rule-based structures for specifying which applications
can run that are centrally managed using Group Policy. It introduces "publisher rules"
that are based on an application's digital signature, making it possible to build
strong rules that account for application updates. For example, an organization can
create a rule to "allow all versions greater than 1.0 of Microsoft Dynamics CRM to
run if signed by Microsoft." With correctly structured rules, IT professionals can
safely deploy updates to allowed applications without having to build a new rule for
each version update.
</p>
        </blockquote>
        <p>
          <a href="http://technet.microsoft.com/en-us/windows/dd320283.aspx" target="_blank">About
AppLocker on TechNet</a>
        </p>
        <p>
          <strong>TroubleshootingPack</strong>
        </p>
        <blockquote>
          <p>
Windows Troubleshooting Platform (WTP) provides ISVs, OEMs, and administrators the
ability to write troubleshooting packs that discover and resolve software and hardware
issues, such as configuration issues, failed hardware, network issues, and application
compatibility issues. In WTP, an issue is referred to as a <em>root cause</em>. Previously,
troubleshooting software and hardware issues was a manual process; however, using
WTP you can automate the process of fixing the most common issues that the user might
encounter. 
</p>
        </blockquote>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/dd323706(VS.85).aspx" target="_blank">
            <strong>About
WTP on MSDN</strong>
          </a>
        </p>
        <h4>PowerShell Integrated Scripting Environment
</h4>
        <p>
The ISE has been vastly improved in terms of usability and sharpness in this build.
Difficult to isolate any one part of it that is much better; the whole experience
is just way smoother and intuitive. 
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerSh.0DifferencesBetweenCTP3andWin7RC_D88A/image_4.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerSh.0DifferencesBetweenCTP3andWin7RC_D88A/image_thumb_1.png" width="640" height="271" />
          </a>
        </p>
        <h5>ISE Object Model
</h5>
        <p>
The object model naming has changed quite a bit to be more intuitive and friendly
to beginners. Who needs to know about Runspaces? It’s a Tab, silly!
</p>
        <table border="1" cellspacing="0" cellpadding="2" width="671">
          <tbody>
            <tr>
              <th valign="top" width="361">
CTP3</th>
              <th valign="top" width="308">
RC</th>
            </tr>
            <tr>
              <td class="removed" valign="top" width="361">
$psise.CurrentOpenedRunspace</td>
              <td class="added" valign="top" width="308">
$psise.CurrentPowerShellTab</td>
            </tr>
            <tr>
              <td class="removed" valign="top" width="361">
$psise.CurrentOpenedRunspace.ToolsMenu</td>
              <td class="added" valign="top" width="308">
$psise.CurrentPowerShellTab.AddOnsMenu</td>
            </tr>
            <tr>
              <td class="removed" valign="top" width="361">
$psise.CurrentOpenedRunspace.OpenedFiles</td>
              <td class="added" valign="top" width="308">
$psise.CurrentPowerShellTab.Files</td>
            </tr>
            <tr>
              <td class="removed" valign="top" width="361">
$psise.CurrentOpenedRunspace.OpenedFiles.RemoveUnsaved($file)</td>
              <td class="added" valign="top" width="308">
$psise.CurrentPowerShellTab.Files.Remove($file,$true)</td>
            </tr>
            <tr>
              <td class="removed" valign="top" width="361">
$psise.OpenedRunspaces</td>
              <td class="added" valign="top" width="308">
$psise.PowerShellTabs</td>
            </tr>
            <tr>
              <td class="removed" valign="top" width="361">
$psise.OpenedRunspaces[1].Execute("string")</td>
              <td style="background-color: #ffeeee" valign="top" width="308">
                <span style="float: left" class="added">$psise.PowerShellTabs[1].Invoke({scriptBlock})</span>
                <span style="float: right; color: red">*</span>
              </td>
            </tr>
            <tr>
              <td class="removed" valign="top" width="361">
$psise.CurrentOpenedFile</td>
              <td class="added" valign="top" width="308">
$psise.CurrentFile</td>
            </tr>
            <tr>
              <td class="removed" valign="top" width="361">
$psise.Options.LocalHelp 
</td>
              <td class="added" valign="top" width="308">
$psise.Options.UseLocalHelp</td>
            </tr>
          </tbody>
        </table>
        <p>
          <font color="#ff0000">*</font>
          <strong>Note: </strong>You may only invoke script on
a tab <em>other</em> than the tab you’re using to execute this command (because you
can’t run two commands at the same time on the same tab!)
</p>
        <p>
The PowerShell team posted a way to make the RC build fairly compatible with CTP3
by adding new members to the $PSISE object which will proxy attempts to use the old
API to the new API. The post is called “<a href="http://blogs.msdn.com/powershell/archive/2009/05/27/update-typedata-ise-ctp3-vs-ise-rc-and-teched2009-demos.aspx" target="_blank">Update-TypeData,
ISE CTP3 vs ISE RC, and Teched2009 Demos</a>.” 
</p>
        <h5>Shortcut Changes
</h5>
        <p>
The shortcut to jump to the Script Pane is now Ctrl+I. (use Ctrl+D to jump to the
Command pane).
</p>
        <h4>Summary
</h4>
        <p>
The RC build is all about bugfixes and incremental improvements. I’m sure there’ll
be more fixes and additions as we near RTW/RTM and I’ll be here to post as much info
about them as possible. This is still just a drop in the ocean of what PowerShell
2.0 can do, and I’ll post more technical demos of features over the next little while.
</p>
        <p>
          <strong>Tips</strong>: run “Get-Help about_*” to get a list of all the overview topics
for the various features in PowerShell v2.
</p>
        <p>
Have fun!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=f789804c-5a35-4d5c-a303-d1a2bdc6bbc0" />
      </body>
      <title>PowerShell v2.0 – Differences Between CTP3/Win7Beta and Win7RC</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,f789804c-5a35-4d5c-a303-d1a2bdc6bbc0.aspx</guid>
      <link>http://www.nivot.org/2009/05/22/PowerShellV20DifferencesBetweenCTP3Win7BetaAndWin7RC.aspx</link>
      <pubDate>Fri, 22 May 2009 21:25:49 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;&lt;strong&gt;update #1 2009/5/23&lt;/strong&gt;: noted that local jobs (start-job) no longer
require an elevated shell.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&lt;strong&gt;update #2 2009/5/28:&lt;/strong&gt; ISE object model and shortcut changes; update
for set-psessionconfiguration cmdlet (new screenshot); module changes (highlighted
new manifest member names, binary module can now be root module); &lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
I’ve been meaning to write this for a while, but it’s been a busy time. This is a
comparison of the significant differences between the standalone CTP3 or Windows 7
Beta version and the version that comes with Win7 RC (6.1.7100.0). For all intents
and purposes, the CTP3 version (6.1.6469.0) is &lt;em&gt;exactly&lt;/em&gt; the same as the Windows
7 Beta (6.1.7000.0) version.
&lt;/p&gt;
&lt;p&gt;
This is not going to be an exhaustive list of differences, but I will continue to
update this post as I find more things worth documenting. It should be safe to bookmark
the permalink. One of the nicest things about this release is that it appears that,
without exception, &lt;strong&gt;all built-in Cmdlets have help.&lt;/strong&gt; A lot of things
have been cleaned up and fixed in this build, from formatting of text to typos and
minor bugs/glitches. 
&lt;/p&gt;
&lt;h4&gt;Cmdlet Differences
&lt;/h4&gt;
&lt;p&gt;
This is a table listing Cmdlets that have either &lt;span class="changed"&gt;changed&lt;/span&gt; (navy),
been &lt;span class="added"&gt;added&lt;/span&gt; (green, underlined) or &lt;span class="removed"&gt;removed&lt;/span&gt; (red,
strike-through.) Changed Cmdlets have their parameters listed in the second column.
A changed parameter means that its Type has been changed; e.g. it accepts a different
.NET object than before. This is generally nothing to worry about since the corresponding
source of such objects is usually changed to match – typically another Cmdlet. Parameters&amp;nbsp;
and Cmdlets that have not changed, are not listed. 
&lt;/p&gt;
&lt;p&gt;
&lt;style type="text/css"&gt;&lt;!--
        #tbl td
        {
            vertical-align: top;
            font-size: 10pt;
        }
        .added
        {
            color: green;
            text-decoration: underline;
        }
        .removed
        {
            color: red;
            text-decoration: line-through;
        }
        .changed
        {
            color: navy;
        }
        .cmdlet
        {
            font-weight: bold;
            cursor: hand;
        }
        .param
        {
            font-style: italic;
            text-align: left;
        }
        .style1
        {
            width: 19px;
        }
    --&gt;&lt;/style&gt;
&lt;table id="tbl" border="1" width="600"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;
Cmdlet&lt;/th&gt;
&lt;th&gt;
Parameters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style="background-color: white"&gt;
&lt;td class="changed cmdlet"&gt;
Invoke-Command 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pInvoke-Command" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="param removed"&gt;
NoCompression 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="param changed"&gt;
Session 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="param changed"&gt;
SessionOption 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #f0f0f0"&gt;
&lt;td class="changed cmdlet"&gt;
Remove-Computer 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pRemove-Computer" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
Force 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
Reboot 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
ComputerName 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: white"&gt;
&lt;td class="changed cmdlet"&gt;
Add-Computer 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pAdd-Computer" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
ComputerName 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
Reboot 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #f0f0f0"&gt;
&lt;td class="removed cmdlet"&gt;
Rename-Computer 
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: white"&gt;
&lt;td class="changed cmdlet"&gt;
Test-Connection 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pTest-Connection" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
ComputerName 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
Quiet 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
Destination 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #f0f0f0"&gt;
&lt;td class="changed cmdlet"&gt;
Export-FormatData 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pExport-FormatData" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td class="added param"&gt;
Path 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
FilePath 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: white"&gt;
&lt;td class="changed cmdlet"&gt;
Receive-Job 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pReceive-Job" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="param changed"&gt;
Session 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #f0f0f0"&gt;
&lt;td class="changed cmdlet"&gt;
Start-Job 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pStart-Job" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
InitializationScript 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
RunAs32 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
ConfigurationName 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
CertificateThumbprint 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
NoCompression 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: white"&gt;
&lt;td class="changed cmdlet"&gt;
Get-Module 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pGet-Module" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
Recurse 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #f0f0f0"&gt;
&lt;td class="changed cmdlet"&gt;
New-ModuleManifest 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pNew-ModuleManifest" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
ProcessorArchitecture 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
DotNetFrameworkVersion 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
PowerShellHostName 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
PowerShellHostVersion 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
FileList 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
ModuleList 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
FunctionsToExport 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
AliasesToExport 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
VariablesToExport 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
CmdletsToExport 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
OtherFiles 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
ExportedFunctions 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
ExportedAliases 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
ExportedVariables 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
ExportedCmdlets 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="param changed"&gt;
RequiredModules 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: white"&gt;
&lt;td class="changed cmdlet"&gt;
Set-PSBreakpoint 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pSet-PSBreakpoint" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="param changed"&gt;
Script 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #f0f0f0"&gt;
&lt;td class="added cmdlet"&gt;
Enable-PSRemoting 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: white"&gt;
&lt;td class="changed cmdlet"&gt;
Remove-PSSession 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pRemove-PSSession" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="param changed"&gt;
Session 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #f0f0f0"&gt;
&lt;td class="changed cmdlet"&gt;
Enter-PSSession 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pEnter-PSSession" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
NoCompression 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="changed param"&gt;
Session 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="changed param"&gt;
SessionOption 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: white"&gt;
&lt;td class="changed cmdlet"&gt;
New-PSSession 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pNew-PSSession" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
NoCompression 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="changed param"&gt;
Session 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="changed param"&gt;
SessionOption 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #f0f0f0"&gt;
&lt;td class="changed cmdlet"&gt;
Export-PSSession 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pExport-PSSession" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
OutputModule 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
Module 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
ModuleName 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
PSSnapin 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="changed param"&gt;
Session 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: white"&gt;
&lt;td class="changed cmdlet"&gt;
Import-PSSession 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pImport-PSSession" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
Module 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
PSSnapin 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="changed param"&gt;
Session 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #f0f0f0"&gt;
&lt;td class="added cmdlet"&gt;
New-PSSessionOption 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: white"&gt;
&lt;td class="changed cmdlet"&gt;
Get-WSManInstance 
&lt;/td&gt;
&lt;td&gt;
&lt;table id="pGet-WSManInstance" class="hidden" width="100%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
Associations 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="added param"&gt;
CertificateThumbprint 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="style1"&gt;
&amp;nbsp; 
&lt;/td&gt;
&lt;td class="removed param"&gt;
References 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="background-color: #f0f0f0"&gt;
&lt;td class="changed cmdlet"&gt;
Set-PSSessionConfiguration&lt;/td&gt;
&lt;td class="added param"&gt;
ShowSecurityDescriptorUI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;h4&gt;Alias Changes
&lt;/h4&gt;
&lt;p&gt;
Some tweaking of aliases here. Personally I find alias changes in general to get under
my skin. Aliases are the first thing I learn and the first thing to trip me up when
things change. Regardless, the changes appear to make sense and are perhaps a bit
more mnemonic than before. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Removed&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class="removed"&gt;emm&lt;/span&gt; (Export-ModuleMember), &lt;span class="removed"&gt;which&lt;/span&gt; (Get-Command)
and &lt;span class="removed"&gt;grid&lt;/span&gt; (Out-Gridview)
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Added&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class="added"&gt;ise&lt;/span&gt; (powershell_ise.exe), &lt;span class="added"&gt;rmo&lt;/span&gt; (Remove-Module)
and &lt;span class="added"&gt;saps&lt;/span&gt; (Start-Process)
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Changed&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class="changed"&gt;imo –&amp;gt; ipmo&lt;/span&gt; (Import-Module)
&lt;/p&gt;
&lt;h4&gt;Language Enhancements
&lt;/h4&gt;
&lt;p&gt;
The major change that has come to light so far is that statements are now allowed
on the right hand of an expression without having to use subexpressions. This is a
great fix, and one that will reduce the margin for error (and confusion) by a large
amount. Previously in CTP3, in order to use a statement like “if”, you had to use
the following syntax:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class="brush: posh"&gt;$result = $( if ($true) { 42 } )&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Now, you can drop the $( and ):
&lt;/p&gt;
&lt;p&gt;
&lt;pre class="brush: posh"&gt;$result = if ($true) { 42 }&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
or
&lt;/p&gt;
&lt;p&gt;
&lt;pre class="brush: posh"&gt;$sequence = foreach ($i in 0..15) { [math]::pow(2, $i) }&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
This is truly great stuff. 
&lt;/p&gt;
&lt;h4&gt;Jobs/Remoting
&lt;/h4&gt;
&lt;p&gt;
The best news here is the abundant help now available at your fingertips. Lots of
examples and meaty information concerning PSSessions and PSSessionConfigurations.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Local Jobs&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Local jobs created now with Start-Job { ... } use an IPC channel to talk to the local
WinRM service to create jobs instead of using the more heavyweight HTTP channel. Yes,
you can infer from this that local jobs are still out of process; they run in their
own isolated runspace and have no access to the interactive session. What this means
in simpler terms is that local jobs are a lot faster now to get started. The biggest
win for local jobs is that &lt;strong&gt;they no longer require an elevated shell!&lt;/strong&gt; you
can submit local jobs as a regular user now – just not remote ones (unless the applicable
remote PSSessionConfiguration is set to allow this - by default the ACL is admins
only).
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Remoting&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
A welcome addition to this build is a new, dedicated &lt;strong&gt;Enable-PSRemoting&lt;/strong&gt; Cmdlet:
&lt;/p&gt;
&lt;p&gt;
&lt;div style="padding-bottom: 5px; background-color: #eeeeee; margin: 20px; padding-left: 5px; padding-right: 5px; padding-top: 5px"&gt;The
Enable-PSRemoting cmdlet configures the computer to receive Windows PowerShell remote
commands that are sent by using the WS-Management technology. 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
You need to run this command only once on each computer that will receive commands.
You do not need to run it on computers that only send commands. Because the configuration
activates listeners, it is prudent to run it only where it is needed.
&lt;/p&gt;
&lt;p&gt;
The Enable-PSRemoting cmdlet performs the following operations: 
&lt;ul&gt;
&lt;li&gt;
Runs the Set-WSManQuickConfig cmdlet, which performs the following tasks: 
&lt;ul&gt;
&lt;li&gt;
Starts the WinRM service. 
&lt;li&gt;
Sets the startup type on the WinRM service to Automatic. 
&lt;li&gt;
Creates a listener to accept requests on any IP address. 
&lt;li&gt;
Enables a firewall exception for WS-Management communications. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Enables all registered Windows PowerShell session configurations to receive instructions
from a remote computer. 
&lt;ul&gt;
&lt;li&gt;
Registers the "Microsoft.PowerShell" session configuration, if it is not already registered. 
&lt;li&gt;
Registers the "Microsoft.PowerShell32" session configuration on 64-bit computers,
if it is not already registered. 
&lt;li&gt;
Removes the "Deny Everyone" setting from the security descriptor for all the registered
session configurations. 
&lt;li&gt;
Restarts the WinRM service to make the preceding changes effective. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
To run this cmdlet on Windows Vista, Windows Server 2008, and later versions of Windows,
you must start Windows PowerShell with the "Run as administrator" option. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Session Configurations&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
There are a raft of Cmdlets dedicated to managing session configurations. So what
is a session configuration? To qoute the ever-present help system:
&lt;/p&gt;
&lt;div style="padding-bottom: 5px; background-color: #eeeeee; margin: 20px; padding-left: 5px; padding-right: 5px; padding-top: 5px"&gt;
&lt;p&gt;
A session configuration is a group of settings on the local computer that define the
environment for the Windows PowerShell sessions that are created when remote users
connect to the local computer.
&lt;/p&gt;
&lt;p&gt;
Administrators of the computer can use session configurations to protect the computer
and to define custom environments for users who connect to the computer.
&lt;/p&gt;
&lt;p&gt;
Administrators can also use session configurations to determine the permissions that
are required to connect to the computer remotely. By default, only members of the
Administrators group have permission to use the session configuration to connect remotely,
but you can change the default settings to allow all users, or selected users, to
connect remotely to your computer.
&lt;/p&gt;
&lt;p&gt;
Session configurations are a feature of Web Services for Management (WS-Management)
based Windows PowerShell remoting. They are used only when you use the New-PSSession,
Invoke-Command, or Enter-PSSession cmdlets to connect to a remote computer.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Note&lt;/strong&gt;: To manage the session configurations on a computer that is
running Windows Vista, Windows Server 2008, or a later version of Windows, start Windows
PowerShell with the "Run as administrator" option.
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerSh.0DifferencesBetweenCTP3andWin7RC_D88A/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerSh.0DifferencesBetweenCTP3andWin7RC_D88A/image_thumb.png" width="640" height="300"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
That SecurityDescriptorSddl property looks like a lot of fun to modify, right? Don’t
worry, the &lt;strong&gt;ShowSecurityDescriptorUI&lt;/strong&gt; comes to the rescue:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0DifferencesBetweenCTP3Win7BetaandWi_8776/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0DifferencesBetweenCTP3Win7BetaandWi_8776/image_thumb.png" width="510" height="480"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h3&gt;Modules
&lt;/h3&gt;
&lt;h5&gt;Manifest Members
&lt;/h5&gt;
&lt;p&gt;
Modules have received some nice incremental improvements as well as some syntactic
changes. You should have noticed above that the manifest fields (exposed as parameters
on New-ModuleManifest)&amp;nbsp; have changed to reflect the two-stage process of how
a module’s members get exposed to the importer’s scope. A module passively &lt;em&gt;exports&lt;/em&gt; members
with Export-ModuleMember, and the caller actively &lt;em&gt;imports&lt;/em&gt; them with Import-Module;
hence “FunctionsToExport,” which subtly says that this can be imported.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Binary Modules&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
A binary module is now allowed to be the root module in a manifest by pointing the
ModuleToProcess key at the assembly, e.g. ModuleToProcess = “Pscx.dll.” This seems
more intuitive than before with the [seemingly] arbitrary restriction that they must
be secondary to a text based psm1.
&lt;/p&gt;
&lt;h4&gt;Built-In Modules
&lt;/h4&gt;
&lt;p&gt;
Shipping with Windows 7 for &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; comes
two new Modules along with the others you should have noticed that arrived with CTP3
(BitsTransfer/FileTransfer and PSDiagnostics.)
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;AppLocker&lt;/strong&gt;
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
AppLocker provides simple, powerful, rule-based structures for specifying which applications
can run that are centrally managed using Group Policy. It introduces "publisher rules"
that are based on an application's digital signature, making it possible to build
strong rules that account for application updates. For example, an organization can
create a rule to "allow all versions greater than 1.0 of Microsoft Dynamics CRM to
run if signed by Microsoft." With correctly structured rules, IT professionals can
safely deploy updates to allowed applications without having to build a new rule for
each version update.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;a href="http://technet.microsoft.com/en-us/windows/dd320283.aspx" target="_blank"&gt;About
AppLocker on TechNet&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;TroubleshootingPack&lt;/strong&gt;
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Windows Troubleshooting Platform (WTP) provides ISVs, OEMs, and administrators the
ability to write troubleshooting packs that discover and resolve software and hardware
issues, such as configuration issues, failed hardware, network issues, and application
compatibility issues. In WTP, an issue is referred to as a &lt;em&gt;root cause&lt;/em&gt;. Previously,
troubleshooting software and hardware issues was a manual process; however, using
WTP you can automate the process of fixing the most common issues that the user might
encounter. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/dd323706(VS.85).aspx" target="_blank"&gt;&lt;strong&gt;About
WTP on MSDN&lt;/strong&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h4&gt;PowerShell Integrated Scripting Environment
&lt;/h4&gt;
&lt;p&gt;
The ISE has been vastly improved in terms of usability and sharpness in this build.
Difficult to isolate any one part of it that is much better; the whole experience
is just way smoother and intuitive. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerSh.0DifferencesBetweenCTP3andWin7RC_D88A/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/PowerSh.0DifferencesBetweenCTP3andWin7RC_D88A/image_thumb_1.png" width="640" height="271"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;h5&gt;ISE Object Model
&lt;/h5&gt;
&lt;p&gt;
The object model naming has changed quite a bit to be more intuitive and friendly
to beginners. Who needs to know about Runspaces? It’s a Tab, silly!
&lt;/p&gt;
&lt;table border="1" cellspacing="0" cellpadding="2" width="671"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th valign="top" width="361"&gt;
CTP3&lt;/th&gt;
&lt;th valign="top" width="308"&gt;
RC&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="removed" valign="top" width="361"&gt;
$psise.CurrentOpenedRunspace&lt;/td&gt;
&lt;td class="added" valign="top" width="308"&gt;
$psise.CurrentPowerShellTab&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="removed" valign="top" width="361"&gt;
$psise.CurrentOpenedRunspace.ToolsMenu&lt;/td&gt;
&lt;td class="added" valign="top" width="308"&gt;
$psise.CurrentPowerShellTab.AddOnsMenu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="removed" valign="top" width="361"&gt;
$psise.CurrentOpenedRunspace.OpenedFiles&lt;/td&gt;
&lt;td class="added" valign="top" width="308"&gt;
$psise.CurrentPowerShellTab.Files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="removed" valign="top" width="361"&gt;
$psise.CurrentOpenedRunspace.OpenedFiles.RemoveUnsaved($file)&lt;/td&gt;
&lt;td class="added" valign="top" width="308"&gt;
$psise.CurrentPowerShellTab.Files.Remove($file,$true)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="removed" valign="top" width="361"&gt;
$psise.OpenedRunspaces&lt;/td&gt;
&lt;td class="added" valign="top" width="308"&gt;
$psise.PowerShellTabs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="removed" valign="top" width="361"&gt;
$psise.OpenedRunspaces[1].Execute("string")&lt;/td&gt;
&lt;td style="background-color: #ffeeee" valign="top" width="308"&gt;
&lt;span style="float: left" class="added"&gt;$psise.PowerShellTabs[1].Invoke({scriptBlock})&lt;/span&gt;&lt;span style="float: right; color: red"&gt;*&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="removed" valign="top" width="361"&gt;
$psise.CurrentOpenedFile&lt;/td&gt;
&lt;td class="added" valign="top" width="308"&gt;
$psise.CurrentFile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="removed" valign="top" width="361"&gt;
$psise.Options.LocalHelp 
&lt;/td&gt;
&lt;td class="added" valign="top" width="308"&gt;
$psise.Options.UseLocalHelp&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
&lt;font color="#ff0000"&gt;*&lt;/font&gt; &lt;strong&gt;Note: &lt;/strong&gt;You may only invoke script on
a tab &lt;em&gt;other&lt;/em&gt; than the tab you’re using to execute this command (because you
can’t run two commands at the same time on the same tab!)
&lt;/p&gt;
&lt;p&gt;
The PowerShell team posted a way to make the RC build fairly compatible with CTP3
by adding new members to the $PSISE object which will proxy attempts to use the old
API to the new API. The post is called “&lt;a href="http://blogs.msdn.com/powershell/archive/2009/05/27/update-typedata-ise-ctp3-vs-ise-rc-and-teched2009-demos.aspx" target="_blank"&gt;Update-TypeData,
ISE CTP3 vs ISE RC, and Teched2009 Demos&lt;/a&gt;.” 
&lt;h5&gt;Shortcut Changes
&lt;/h5&gt;
&lt;p&gt;
The shortcut to jump to the Script Pane is now Ctrl+I. (use Ctrl+D to jump to the
Command pane).
&lt;/p&gt;
&lt;h4&gt;Summary
&lt;/h4&gt;
&lt;p&gt;
The RC build is all about bugfixes and incremental improvements. I’m sure there’ll
be more fixes and additions as we near RTW/RTM and I’ll be here to post as much info
about them as possible. This is still just a drop in the ocean of what PowerShell
2.0 can do, and I’ll post more technical demos of features over the next little while.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tips&lt;/strong&gt;: run “Get-Help about_*” to get a list of all the overview topics
for the various features in PowerShell v2.
&lt;/p&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=f789804c-5a35-4d5c-a303-d1a2bdc6bbc0" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,f789804c-5a35-4d5c-a303-d1a2bdc6bbc0.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>CTP3</category>
      <category>Microsoft</category>
      <category>Modules</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>RC</category>
      <category>Windows 7</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=85ac5b6d-3f7f-403f-8cb1-cda063876092</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,85ac5b6d-3f7f-403f-8cb1-cda063876092.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,85ac5b6d-3f7f-403f-8cb1-cda063876092.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=85ac5b6d-3f7f-403f-8cb1-cda063876092</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
After some hints from Ibrahim on the Microsoft PowerShell team, I realised it was
possible to rewrite the dynamic module body generation from the <a href="http://www.nivot.org/2009/03/26/PowerShell20CTP3ModulesInPracticeNETInterfaces.aspx" target="_blank">Get-Interface
function in my last post</a> without using string literals and nested here-string
tricks. I was able to increase the brevity by using a new [to PowerShell] v2 feature
called “Closures.” Ibrahim talks a bit about the technique over on the official <a href="http://blogs.msdn.com/powershell/archive/2009/03/27/get-closure-with-getnewclosure.aspx" target="_blank">PowerShell
Blog</a>. It’s a common feature in so-called Functional languages and there are plenty
of other tidbits to read about it, both academic and practical if you search online. 
</p>
        <p>
A closure in PowerShell, in short, lets you take a snapshot of a ScriptBlock by calling
its GetNewClosure() method. The snapshot is taken of its variables and will let you
pass it around so it is no longer directly tied to the particular scope chain it was
declared in. As some are fond of saying though, <a href="http://wiki.slimdevices.com/index.php/Thar_be_Dragons" target="_blank">Thar
Be Dragons</a>. Although closing around a ScriptBlock will make copies of the PSVariables
that are within, it is still subject to the whims of .NET – particularly ByRef and
ByValue semantics. If a ScriptBlock contains a PSVariable pointing to an integer,
it’s safe to say that integer will be copied and is frozen as that value as long as
you remain within the domain of the current SessionState context (more about this
later).
</p>
        <h5>.NET intervenes: ByRef and ByVal
</h5>
        <p>
Closing around a ScriptBlock that contains PSVariables that point to reference types,
however - like Arrays for example – will only duplicate the <em>reference</em>, not
the instance itself. If elements in the array are changed via the PSVariable from
the originating scope, <strong>the corresponding array element in the closure will
also change</strong>. After all – you got a copy of the <em>pointer, </em>not the
value itself. This is the very essence of ByRef and ByVal. 
</p>
        <p>
Let’s take a look at the revised Get-Interface script:
</p>
        <pre class="brush: posh">
function Get-Interface {

#.Synopsis
#   Allows PowerShell to call specific interface implementations on any .NET object. 
#.Description
#   Allows PowerShell to call specific interface implementations on any .NET object. 
#
#   As of v2.0, PowerShell cannot cast .NET instances to a particular interface. This makes it
#   impossible (shy of reflection) to call methods on explicitly implemented interfaces.   
#.Parameter Object
#   An instance of a .NET class from which you want to get a reference to a particular interface it defines.
#.Parameter InterfaceType
#   An interface type, e.g. [idisposable], implemented by the target object.
#.Example
#   // a class with explicitly implemented interface   
#   public class MyObj : IDisposable {
#      void IDisposable.Dispose()
#   }
#   
#   ps&gt; $o = new-object MyObj
#   ps&gt; $i = get-interface $o ([idisposable])
#   ps&gt; $i.Dispose()      
#.ReturnValue
#   A PSCustomObject with ScriptMethods and ScriptProperties representing methods and properties on the target interface.
#.Notes
# AUTHOR:    Oisin Grehan http://www.nivot.org/
# LASTEDIT:  2009-03-28 18:37:23
# REVISION:  0.2

    [CmdletBinding()]
    param(
        [ValidateNotNull()]
        $Object,
        
        [ValidateScript( { $_.IsInterface } )]
        [type]$InterfaceType
    )

    $script:t  = $Object.GetType()
    
    try {
        
        $script:m  = $t.GetInterfaceMap($InterfaceType)

    } catch [argumentexception] {
        
        throw "Interface $($InterfaceType.Name) not found on ${t}!"
    }

    $script:im = $m.InterfaceMethods
    $script:tm = $m.TargetMethods
    
    # TODO: use param blocks in functions instead of $args
    #       so method signatures are visible via get-member
    
    $body = {
         param($o, $i) 
         
         $script:t  = $o.GetType()
         $script:m  = $t.GetInterfaceMap($i)
         $script:im = $m.InterfaceMethods
         $script:tm = $m.TargetMethods
                  
         for ($ix = 0; $ix -lt $im.Count; $ix++) {
            
            $mb = $im[$ix]

            # for the function body, we close over $ix to capture the index
            # so even on the next iteration of this loop, the $ix value will
            # be frozen within the function's scriptblock body
            set-item -path function:script:$($mb.Name) -value {

                # call corresponding target method
                $tm[$ix].Invoke($o, $args)

            }.GetNewClosure() -verbose -force

            if (!$mb.IsSpecialName) {
                # only export the function if it is not a getter or setter.
                Export-ModuleMember $mb.Name -verbose
            }
         }
    }

    write-verbose $body.tostring()    
    
    # create dynamic module
    $module = new-module -ScriptBlock $body -Args $Object, $InterfaceType -Verbose
    
    # generate method proxies - all exported members become scriptmethods
    # however, we are careful not to export getters and setters.
    $custom = $module.AsCustomObject()
    
    # add property proxies - need to use scriptproperties here.
    # modules cannot expose true properties, only variables and 
    # we cannot intercept variables get/set.
    
    $InterfaceType.GetProperties() | % {

        $propName = $_.Name
        $getter   = $null
        $setter   = $null
       
        if ($_.CanRead) {
            
            # where is the getter methodinfo on the interface map?
            $ix = [array]::indexof($im, $_.GetGetMethod())
            
            # bind the getter scriptblock to our module's scope
            # and generate script to call target method
            #
            # NOTE: we cannot use a closure here because sessionstate
            #       is rebound to the module's, and $ix would be lost
            $getter = $module.NewBoundScriptBlock(
                [scriptblock]::create("`$tm[{0}].Invoke(`$o, @())" -f $ix))
        }
        
        if ($_.CanWrite) {
            
            # where is the setter methodinfo on the interface map?
            $ix = [array]::indexof($im, $_.GetSetMethod())
            
            # bind the setter scriptblock to our module's scope
            # and generate script to call target method
            #
            # NOTE: we cannot use a closure here because sessionstate
            #       is rebound to the module's, and $ix would be lost
            $setter = $module.NewBoundScriptBlock(
                [scriptblock]::create(
                    "param(`$value); `$tm[{0}].Invoke(`$o, `$value)" -f $ix))
        }
        
        # add our property to the pscustomobject
        $prop = new-object management.automation.psscriptproperty $propName, $getter, $setter
        $custom.psobject.properties.add($prop)
    }
    
    # insert the interface name at the head of the typename chain (for get-member info)
    $custom.psobject.TypeNames.Insert(0, $InterfaceType.FullName)
    
    # dump our pscustomobject to pipeline
    $custom
}
</pre>
        <p>
The changes are around line 56, where I now declare $body with a script syntax, no
longer using [scriptblock]::create. Where previously I used a subexpression inside
a here-string to general literal function declarations, I now use a “for” loop and
set-item to create the functions (thanks Ibrahim!). You can see that I am calling
GetNewClosure() on the function body each time I create a new function. This “captures”
the value of the $ix index variable, so that the value will not change on subsequent
loops. If I did not use closures, when the for loop ended, all of the functions would
be using the same terminating value of the loop for $ix, which would be $im.count
+ 1. Doh.
</p>
        <h5>Module SessionState Context, Wha?
</h5>
        <p>
So if I ripped out that literal string parsing stuff for the module $body, why am
I still using it for the property getter/setter generation? (lines 115 / 130) 
Well, I have no choice: Creating a new module creates an entirely new SessionState;
in simple terms, session state is essentially a giant Hashtable in which PSVariables
are stored. If I closed over those get/set ScriptBlocks containing the $ix PSVariable,
when it is bound to the module it will use the new module’s SessionState – which is
empty! The value of $ix would be undefined. The other variables in those strings are
escaped, because they will be evaluated in the module’s context later, when the getters
and setters are invoked. Those variables are seeded by the module’s initialization
done at the new-module call at line 88.
</p>
        <p>
It’s all very succinct, but rest assured, very powerful.
</p>
        <p>
Have fun!
</p>
        <p>
          <strong>NOTE: </strong>I realise that some more refactoring could probably eliminate
this script parsing, but the value is in understanding how modules may affect usage
of closures, and the problems that may occur.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=85ac5b6d-3f7f-403f-8cb1-cda063876092" />
      </body>
      <title>PowerShell 2.0 CTP3: Modules, in Practice - Closures</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,85ac5b6d-3f7f-403f-8cb1-cda063876092.aspx</guid>
      <link>http://www.nivot.org/2009/03/28/PowerShell20CTP3ModulesInPracticeClosures.aspx</link>
      <pubDate>Sat, 28 Mar 2009 23:23:11 GMT</pubDate>
      <description>&lt;p&gt;
After some hints from Ibrahim on the Microsoft PowerShell team, I realised it was
possible to rewrite the dynamic module body generation from the &lt;a href="http://www.nivot.org/2009/03/26/PowerShell20CTP3ModulesInPracticeNETInterfaces.aspx" target="_blank"&gt;Get-Interface
function in my last post&lt;/a&gt; without using string literals and nested here-string
tricks. I was able to increase the brevity by using a new [to PowerShell] v2 feature
called “Closures.” Ibrahim talks a bit about the technique over on the official &lt;a href="http://blogs.msdn.com/powershell/archive/2009/03/27/get-closure-with-getnewclosure.aspx" target="_blank"&gt;PowerShell
Blog&lt;/a&gt;. It’s a common feature in so-called Functional languages and there are plenty
of other tidbits to read about it, both academic and practical if you search online. 
&lt;/p&gt;
&lt;p&gt;
A closure in PowerShell, in short, lets you take a snapshot of a ScriptBlock by calling
its GetNewClosure() method. The snapshot is taken of its variables and will let you
pass it around so it is no longer directly tied to the particular scope chain it was
declared in. As some are fond of saying though, &lt;a href="http://wiki.slimdevices.com/index.php/Thar_be_Dragons" target="_blank"&gt;Thar
Be Dragons&lt;/a&gt;. Although closing around a ScriptBlock will make copies of the PSVariables
that are within, it is still subject to the whims of .NET – particularly ByRef and
ByValue semantics. If a ScriptBlock contains a PSVariable pointing to an integer,
it’s safe to say that integer will be copied and is frozen as that value as long as
you remain within the domain of the current SessionState context (more about this
later).
&lt;/p&gt;
&lt;h5&gt;.NET intervenes: ByRef and ByVal
&lt;/h5&gt;
&lt;p&gt;
Closing around a ScriptBlock that contains PSVariables that point to reference types,
however - like Arrays for example – will only duplicate the &lt;em&gt;reference&lt;/em&gt;, not
the instance itself. If elements in the array are changed via the PSVariable from
the originating scope, &lt;strong&gt;the corresponding array element in the closure will
also change&lt;/strong&gt;. After all – you got a copy of the &lt;em&gt;pointer, &lt;/em&gt;not the
value itself. This is the very essence of ByRef and ByVal. 
&lt;/p&gt;
&lt;p&gt;
Let’s take a look at the revised Get-Interface script:
&lt;/p&gt;
&lt;pre class="brush: posh"&gt;
function Get-Interface {

#.Synopsis
#   Allows PowerShell to call specific interface implementations on any .NET object. 
#.Description
#   Allows PowerShell to call specific interface implementations on any .NET object. 
#
#   As of v2.0, PowerShell cannot cast .NET instances to a particular interface. This makes it
#   impossible (shy of reflection) to call methods on explicitly implemented interfaces.   
#.Parameter Object
#   An instance of a .NET class from which you want to get a reference to a particular interface it defines.
#.Parameter InterfaceType
#   An interface type, e.g. [idisposable], implemented by the target object.
#.Example
#   // a class with explicitly implemented interface   
#   public class MyObj : IDisposable {
#      void IDisposable.Dispose()
#   }
#   
#   ps&amp;gt; $o = new-object MyObj
#   ps&amp;gt; $i = get-interface $o ([idisposable])
#   ps&amp;gt; $i.Dispose()      
#.ReturnValue
#   A PSCustomObject with ScriptMethods and ScriptProperties representing methods and properties on the target interface.
#.Notes
# AUTHOR:    Oisin Grehan http://www.nivot.org/
# LASTEDIT:  2009-03-28 18:37:23
# REVISION:  0.2

    [CmdletBinding()]
    param(
        [ValidateNotNull()]
        $Object,
        
        [ValidateScript( { $_.IsInterface } )]
        [type]$InterfaceType
    )

    $script:t  = $Object.GetType()
    
    try {
        
        $script:m  = $t.GetInterfaceMap($InterfaceType)

    } catch [argumentexception] {
        
        throw "Interface $($InterfaceType.Name) not found on ${t}!"
    }

    $script:im = $m.InterfaceMethods
    $script:tm = $m.TargetMethods
    
    # TODO: use param blocks in functions instead of $args
    #       so method signatures are visible via get-member
    
    $body = {
         param($o, $i) 
         
         $script:t  = $o.GetType()
         $script:m  = $t.GetInterfaceMap($i)
         $script:im = $m.InterfaceMethods
         $script:tm = $m.TargetMethods
                  
         for ($ix = 0; $ix -lt $im.Count; $ix++) {
            
            $mb = $im[$ix]

            # for the function body, we close over $ix to capture the index
            # so even on the next iteration of this loop, the $ix value will
            # be frozen within the function's scriptblock body
            set-item -path function:script:$($mb.Name) -value {

                # call corresponding target method
                $tm[$ix].Invoke($o, $args)

            }.GetNewClosure() -verbose -force

            if (!$mb.IsSpecialName) {
                # only export the function if it is not a getter or setter.
                Export-ModuleMember $mb.Name -verbose
            }
         }
    }

    write-verbose $body.tostring()    
    
    # create dynamic module
    $module = new-module -ScriptBlock $body -Args $Object, $InterfaceType -Verbose
    
    # generate method proxies - all exported members become scriptmethods
    # however, we are careful not to export getters and setters.
    $custom = $module.AsCustomObject()
    
    # add property proxies - need to use scriptproperties here.
    # modules cannot expose true properties, only variables and 
    # we cannot intercept variables get/set.
    
    $InterfaceType.GetProperties() | % {

        $propName = $_.Name
        $getter   = $null
        $setter   = $null
       
        if ($_.CanRead) {
            
            # where is the getter methodinfo on the interface map?
            $ix = [array]::indexof($im, $_.GetGetMethod())
            
            # bind the getter scriptblock to our module's scope
            # and generate script to call target method
            #
            # NOTE: we cannot use a closure here because sessionstate
            #       is rebound to the module's, and $ix would be lost
            $getter = $module.NewBoundScriptBlock(
                [scriptblock]::create("`$tm[{0}].Invoke(`$o, @())" -f $ix))
        }
        
        if ($_.CanWrite) {
            
            # where is the setter methodinfo on the interface map?
            $ix = [array]::indexof($im, $_.GetSetMethod())
            
            # bind the setter scriptblock to our module's scope
            # and generate script to call target method
            #
            # NOTE: we cannot use a closure here because sessionstate
            #       is rebound to the module's, and $ix would be lost
            $setter = $module.NewBoundScriptBlock(
                [scriptblock]::create(
                    "param(`$value); `$tm[{0}].Invoke(`$o, `$value)" -f $ix))
        }
        
        # add our property to the pscustomobject
        $prop = new-object management.automation.psscriptproperty $propName, $getter, $setter
        $custom.psobject.properties.add($prop)
    }
    
    # insert the interface name at the head of the typename chain (for get-member info)
    $custom.psobject.TypeNames.Insert(0, $InterfaceType.FullName)
    
    # dump our pscustomobject to pipeline
    $custom
}
&lt;/pre&gt;
&lt;p&gt;
The changes are around line 56, where I now declare $body with a script syntax, no
longer using [scriptblock]::create. Where previously I used a subexpression inside
a here-string to general literal function declarations, I now use a “for” loop and
set-item to create the functions (thanks Ibrahim!). You can see that I am calling
GetNewClosure() on the function body each time I create a new function. This “captures”
the value of the $ix index variable, so that the value will not change on subsequent
loops. If I did not use closures, when the for loop ended, all of the functions would
be using the same terminating value of the loop for $ix, which would be $im.count
+ 1. Doh.
&lt;/p&gt;
&lt;h5&gt;Module SessionState Context, Wha?
&lt;/h5&gt;
&lt;p&gt;
So if I ripped out that literal string parsing stuff for the module $body, why am
I still using it for the property getter/setter generation? (lines 115 / 130)&amp;nbsp;
Well, I have no choice: Creating a new module creates an entirely new SessionState;
in simple terms, session state is essentially a giant Hashtable in which PSVariables
are stored. If I closed over those get/set ScriptBlocks containing the $ix PSVariable,
when it is bound to the module it will use the new module’s SessionState – which is
empty! The value of $ix would be undefined. The other variables in those strings are
escaped, because they will be evaluated in the module’s context later, when the getters
and setters are invoked. Those variables are seeded by the module’s initialization
done at the new-module call at line 88.
&lt;/p&gt;
&lt;p&gt;
It’s all very succinct, but rest assured, very powerful.
&lt;/p&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;NOTE: &lt;/strong&gt;I realise that some more refactoring could probably eliminate
this script parsing, but the value is in understanding how modules may affect usage
of closures, and the problems that may occur.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=85ac5b6d-3f7f-403f-8cb1-cda063876092" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,85ac5b6d-3f7f-403f-8cb1-cda063876092.aspx</comments>
      <category>.NET</category>
      <category>Closures</category>
      <category>Modules</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=1c6f9d27-3486-4203-b2a2-862d4fc754ec</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,1c6f9d27-3486-4203-b2a2-862d4fc754ec.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,1c6f9d27-3486-4203-b2a2-862d4fc754ec.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=1c6f9d27-3486-4203-b2a2-862d4fc754ec</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is a bit of a hardcore example of the power that modules have brought to the
table in v2.0. First, a little background - PowerShell’s type adaptation system has
always ignored the concept of interfaces. Frankly, it never really needed to pay them
any attention. The adapted view of any instance of a .NET class is just an aggregate
of all its methods; the most derived instance is the default, and only, view. This
is the most simple and most frequently used view. However, this all goes to hell when
you bring in the notion of explicit interfaces. 
</p>
        <h5>Explicit Interface Definitions
</h5>
        <p>
Here’s an example of a C# class, Test, with two interfaces: IFace, and IFaceEx. I’ve
put this whole example in PowerShell script so you can easily test it without firing
up Visual Studio. Add-Type cmdlet to the rescue!
</p>
        <pre class="brush: posh">if (-not ("Test" -as [type])) {    
    add-type @"
        public interface IFace {
            string Hello(string name);
            string Goodbye();
        }
        
        public interface IFaceEx {
            string Hello(string name);
            string Goodbye();
            string Prop1 {
                get;
                set;
            }                
        }
        
        public class Test : IFace, IFaceEx {
            public string Hello(string name) {
                return "Hello" + name + " from IFace";
            }
            public string Goodbye() {
                return "Goodbye from IFace";
            }            
            string IFaceEx.Hello(string name) {
                return "Hello " + name + " from IFaceEx";
            }
            string IFaceEx.Goodbye() {
                return "Goodbye from IFaceEx";
            }
            
            private string _prop1 = "Foo";
            
            string IFaceEx.Prop1 {
                get { return _prop1; }
                set { _prop1 = value; }
            }
        }
"@    
}
</pre>
        <p>
If you new up an instance of Test, you’ll see that the explicit interface definitions
are hidden. Any calls to Hello(string) will invoke the IFace implementation.
</p>
        <p>
          <strong>There is no way to call IFaceEx.Hello without using reflection!</strong>
        </p>
        <p>
So, this is where the beauty of modules can help us. The following function will take
an instance of a .NET class, and the interface you want a  reference to, and
will return a PSCustomObject with ScriptMethods and ScriptProperties bound to that
interface’s contract. You don’t have to do this only with explicit interfaces, any
interfaces will work ;-)
</p>
        <h5>Introducing Get-Interface
</h5>
        <p>
A script is worth a thousand words.
</p>
        <pre class="brush: posh">function Get-Interface {

#.Synopsis
#   Allows PowerShell to call specific interface implementations on any .NET object. 
#.Description
#   Allows PowerShell to call specific interface implementations on any .NET object. 
#
#   As of v2.0, PowerShell cannot cast .NET instances to a particular interface. This makes it
#   impossible (shy of reflection) to call methods on explicitly implemented interfaces.   
#.Parameter Object
#   An instance of a .NET class from which you want to get a reference to a particular interface it defines.
#.Parameter InterfaceType
#   An interface type, e.g. [idisposable], implemented by the target object.
#.Example
#   // a class with explicitly implemented interface   
#   public class MyObj : IDisposable {
#      void IDisposable.Dispose()
#   }
#   
#   ps&gt; $o = new-object MyObj
#   ps&gt; $i = get-interface $o ([idisposable])
#   ps&gt; $i.Dispose()      
#.ReturnValue
#   A PSCustomObject with ScriptMethods and ScriptProperties representing methods and properties on the target interface.
#.Notes
#   AUTHOR:    Oisin Grehan http://www.nivot.org/
#   LASTEDIT:  2009-03-25 11:35:23

    [CmdletBinding()]
    param(
        [ValidateNotNull()]
        $Object,
        
        [ValidateScript( { $_.IsInterface } )]
        [type]$InterfaceType
    )

    $private:t  = $Object.GetType()
    
    try {
        
        $private:m  = $t.GetInterfaceMap($InterfaceType)

    } catch [argumentexception] {
        
        throw "Interface $($InterfaceType.Name) not found on ${t}!"
    }

    $private:im = $m.InterfaceMethods
    $private:tm = $m.TargetMethods
    
    # TODO: use param blocks in functions instead of $args
    #       so method signatures are visible via get-member
    
    $body = [scriptblock]::Create(@"
        param(`$o, `$i)    
        
        `$script:t  = `$o.GetType()
        `$script:m  = `$t.GetInterfaceMap(`$i)
        `$script:im = `$m.InterfaceMethods
        `$script:tm = `$m.TargetMethods
        
        # interface methods $($im.count)
        # target methods $($tm.count)
        
        $(
            for ($ix = 0; $ix -lt $im.Count; $ix++) {
                $mb = $im[$ix]
                @"
                function $($mb.Name) {
                    `$tm[$ix].Invoke(`$o, `$args)
                }

                $(if (!$mb.IsSpecialName) {
                    @"
                    Export-ModuleMember $($mb.Name)

"@
                })
"@
            }
        )
"@)
    write-verbose $body.tostring()    
    
    # create dynamic module
    $module = new-module -ScriptBlock $body -Args $Object, $InterfaceType -Verbose
        
    # generate method proxies - all exported members become scriptmethods
    # however, we are careful not to export getters and setters.
    $custom = $module.AsCustomObject()
    
    # add property proxies - need to use scriptproperties here.
    # modules cannot expose true properties, only variables and 
    # we cannot intercept variables get/set.
    
    $InterfaceType.GetProperties() | % {

        $propName = $_.Name
        $getter   = $null
        $setter   = $null
       
        if ($_.CanRead) {
            
            # where is the getter methodinfo on the interface map?
            $ix = [array]::indexof($im, $_.GetGetMethod())
            
            # bind the getter scriptblock to our module's scope
            # and generate script to call target method
            $getter = $module.NewBoundScriptBlock(
                [scriptblock]::create("`$tm[{0}].Invoke(`$o, @())" -f $ix))
        }
        
        if ($_.CanWrite) {
            
            # where is the setter methodinfo on the interface map?
            $ix = [array]::indexof($im, $_.GetSetMethod())
            
            # bind the setter scriptblock to our module's scope
            # and generate script to call target method
            $setter = $module.NewBoundScriptBlock(
                [scriptblock]::create(
                    "param(`$value); `$tm[{0}].Invoke(`$o, `$value)" -f $ix))
        }
        
        # add our property to the pscustomobject
        $prop = new-object management.automation.psscriptproperty $propName, $getter, $setter
        $custom.psobject.properties.add($prop)
    }
    
    # insert the interface name at the head of the typename chain (for get-member info)
    $custom.psobject.TypeNames.Insert(0, $InterfaceType.FullName)
    
    # dump our pscustomobject to pipeline
    $custom
}
</pre>Here's
how to use it, with our example Test class as added earlier: <pre class="brush: posh">$if = Get-Interface (new-object test) ([ifaceex]) -verbose
$if.Hello("Oisin") # returns Hello Oisin from IFaceEx

$if.Prop1 = "Test" # property setter
$if.Prop1 # propery getter
</pre><p>
Have fun!
</p><img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=1c6f9d27-3486-4203-b2a2-862d4fc754ec" /></body>
      <title>PowerShell 2.0 CTP3: Modules, in Practice – .NET Interfaces</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,1c6f9d27-3486-4203-b2a2-862d4fc754ec.aspx</guid>
      <link>http://www.nivot.org/2009/03/26/PowerShell20CTP3ModulesInPracticeNETInterfaces.aspx</link>
      <pubDate>Thu, 26 Mar 2009 14:02:44 GMT</pubDate>
      <description>&lt;p&gt;
This is a bit of a hardcore example of the power that modules have brought to the
table in v2.0. First, a little background - PowerShell’s type adaptation system has
always ignored the concept of interfaces. Frankly, it never really needed to pay them
any attention. The adapted view of any instance of a .NET class is just an aggregate
of all its methods; the most derived instance is the default, and only, view. This
is the most simple and most frequently used view. However, this all goes to hell when
you bring in the notion of explicit interfaces. 
&lt;/p&gt;
&lt;h5&gt;Explicit Interface Definitions
&lt;/h5&gt;
&lt;p&gt;
Here’s an example of a C# class, Test, with two interfaces: IFace, and IFaceEx. I’ve
put this whole example in PowerShell script so you can easily test it without firing
up Visual Studio. Add-Type cmdlet to the rescue!
&lt;/p&gt;
&lt;pre class="brush: posh"&gt;if (-not ("Test" -as [type])) {    
    add-type @"
        public interface IFace {
            string Hello(string name);
            string Goodbye();
        }
        
        public interface IFaceEx {
            string Hello(string name);
            string Goodbye();
            string Prop1 {
                get;
                set;
            }                
        }
        
        public class Test : IFace, IFaceEx {
            public string Hello(string name) {
                return "Hello" + name + " from IFace";
            }
            public string Goodbye() {
                return "Goodbye from IFace";
            }            
            string IFaceEx.Hello(string name) {
                return "Hello " + name + " from IFaceEx";
            }
            string IFaceEx.Goodbye() {
                return "Goodbye from IFaceEx";
            }
            
            private string _prop1 = "Foo";
            
            string IFaceEx.Prop1 {
                get { return _prop1; }
                set { _prop1 = value; }
            }
        }
"@    
}
&lt;/pre&gt;
&lt;p&gt;
If you new up an instance of Test, you’ll see that the explicit interface definitions
are hidden. Any calls to Hello(string) will invoke the IFace implementation.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;There is no way to call IFaceEx.Hello without using reflection!&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
So, this is where the beauty of modules can help us. The following function will take
an instance of a .NET class, and the interface you want a&amp;nbsp; reference to, and
will return a PSCustomObject with ScriptMethods and ScriptProperties bound to that
interface’s contract. You don’t have to do this only with explicit interfaces, any
interfaces will work ;-)
&lt;/p&gt;
&lt;h5&gt;Introducing Get-Interface
&lt;/h5&gt;
&lt;p&gt;
A script is worth a thousand words.
&lt;/p&gt;
&lt;pre class="brush: posh"&gt;function Get-Interface {

#.Synopsis
#   Allows PowerShell to call specific interface implementations on any .NET object. 
#.Description
#   Allows PowerShell to call specific interface implementations on any .NET object. 
#
#   As of v2.0, PowerShell cannot cast .NET instances to a particular interface. This makes it
#   impossible (shy of reflection) to call methods on explicitly implemented interfaces.   
#.Parameter Object
#   An instance of a .NET class from which you want to get a reference to a particular interface it defines.
#.Parameter InterfaceType
#   An interface type, e.g. [idisposable], implemented by the target object.
#.Example
#   // a class with explicitly implemented interface   
#   public class MyObj : IDisposable {
#      void IDisposable.Dispose()
#   }
#   
#   ps&amp;gt; $o = new-object MyObj
#   ps&amp;gt; $i = get-interface $o ([idisposable])
#   ps&amp;gt; $i.Dispose()      
#.ReturnValue
#   A PSCustomObject with ScriptMethods and ScriptProperties representing methods and properties on the target interface.
#.Notes
#   AUTHOR:    Oisin Grehan http://www.nivot.org/
#   LASTEDIT:  2009-03-25 11:35:23

    [CmdletBinding()]
    param(
        [ValidateNotNull()]
        $Object,
        
        [ValidateScript( { $_.IsInterface } )]
        [type]$InterfaceType
    )

    $private:t  = $Object.GetType()
    
    try {
        
        $private:m  = $t.GetInterfaceMap($InterfaceType)

    } catch [argumentexception] {
        
        throw "Interface $($InterfaceType.Name) not found on ${t}!"
    }

    $private:im = $m.InterfaceMethods
    $private:tm = $m.TargetMethods
    
    # TODO: use param blocks in functions instead of $args
    #       so method signatures are visible via get-member
    
    $body = [scriptblock]::Create(@"
        param(`$o, `$i)    
        
        `$script:t  = `$o.GetType()
        `$script:m  = `$t.GetInterfaceMap(`$i)
        `$script:im = `$m.InterfaceMethods
        `$script:tm = `$m.TargetMethods
        
        # interface methods $($im.count)
        # target methods $($tm.count)
        
        $(
            for ($ix = 0; $ix -lt $im.Count; $ix++) {
                $mb = $im[$ix]
                @"
                function $($mb.Name) {
                    `$tm[$ix].Invoke(`$o, `$args)
                }

                $(if (!$mb.IsSpecialName) {
                    @"
                    Export-ModuleMember $($mb.Name)

"@
                })
"@
            }
        )
"@)
    write-verbose $body.tostring()    
    
    # create dynamic module
    $module = new-module -ScriptBlock $body -Args $Object, $InterfaceType -Verbose
        
    # generate method proxies - all exported members become scriptmethods
    # however, we are careful not to export getters and setters.
    $custom = $module.AsCustomObject()
    
    # add property proxies - need to use scriptproperties here.
    # modules cannot expose true properties, only variables and 
    # we cannot intercept variables get/set.
    
    $InterfaceType.GetProperties() | % {

        $propName = $_.Name
        $getter   = $null
        $setter   = $null
       
        if ($_.CanRead) {
            
            # where is the getter methodinfo on the interface map?
            $ix = [array]::indexof($im, $_.GetGetMethod())
            
            # bind the getter scriptblock to our module's scope
            # and generate script to call target method
            $getter = $module.NewBoundScriptBlock(
                [scriptblock]::create("`$tm[{0}].Invoke(`$o, @())" -f $ix))
        }
        
        if ($_.CanWrite) {
            
            # where is the setter methodinfo on the interface map?
            $ix = [array]::indexof($im, $_.GetSetMethod())
            
            # bind the setter scriptblock to our module's scope
            # and generate script to call target method
            $setter = $module.NewBoundScriptBlock(
                [scriptblock]::create(
                    "param(`$value); `$tm[{0}].Invoke(`$o, `$value)" -f $ix))
        }
        
        # add our property to the pscustomobject
        $prop = new-object management.automation.psscriptproperty $propName, $getter, $setter
        $custom.psobject.properties.add($prop)
    }
    
    # insert the interface name at the head of the typename chain (for get-member info)
    $custom.psobject.TypeNames.Insert(0, $InterfaceType.FullName)
    
    # dump our pscustomobject to pipeline
    $custom
}
&lt;/pre&gt;Here's
how to use it, with our example Test class as added earlier: &lt;pre class="brush: posh"&gt;$if = Get-Interface (new-object test) ([ifaceex]) -verbose
$if.Hello("Oisin") # returns Hello Oisin from IFaceEx

$if.Prop1 = "Test" # property setter
$if.Prop1 # propery getter
&lt;/pre&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=1c6f9d27-3486-4203-b2a2-862d4fc754ec" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,1c6f9d27-3486-4203-b2a2-862d4fc754ec.aspx</comments>
      <category>.NET</category>
      <category>CTP3</category>
      <category>Modules</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=63bcc008-54d7-490f-82eb-23bbe1dd039a</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,63bcc008-54d7-490f-82eb-23bbe1dd039a.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,63bcc008-54d7-490f-82eb-23bbe1dd039a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=63bcc008-54d7-490f-82eb-23bbe1dd039a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It looks like the SharePoint team is slowly catching up to what the community has
had for years in various guises on CodePlex, but I’ve a good feeling that sometime
in the future, the community will finally be able to relax and get back to real work
as official support will surpass even the best of the open source offerings (optimistic?
we’ll see). Here’s the feature set for the current CTP:
</p>
        <p>
(These are features added in v1.3 which were not available in v1.2 or v1.1) 
</p>
        <p>
· <strong>Support for developing and deploying on 64 bit (x64).</strong></p>
        <ul>
          <li>
New menu commands within Visual Studio 
<ul><li>
Package - package the solution but does not deploy. 
</li><li>
Retract - retracts and deletes the active solution from SharePoint. 
</li><li>
Quick Deploy 
<ul><li>
Copy to 12 - copies template files, modules to the 12 Hive. 
</li><li>
Copy Binarie(s) - deploys only the assemblies. 
</li><li>
Copy Both 
</li><li>
Recycle Application Pool 
</li><li>
Attach to IIS Worker Processes 
</li></ul></li></ul></li>
        </ul>
        <ul>
          <li>
WSP View Improvements (Create New Feature) 
<ul><li>
Allows specify feature scope (Web, Site, Web Application, Farm) 
</li><li>
Allows creation of a feature receiver 
</li><li>
Option to automatically create elements.xml with new feature 
</li><li>
Elements can be dragged from one feature to another</li></ul></li>
          <li>
Build Commands Updates 
<ul><li>
Package command added to Visual Studio IDE and command line. 
</li><li>
Retract command added to Visual Studio IDE and command line.</li></ul></li>
        </ul>
        <p>
1) Command line operation is as follows:<br />
devenv.exe &lt;Project.csproj or Solution.sln and other usual flags&gt; /deploy Debug<br />
devenv.exe &lt;Project.csproj or Solution.sln and other usual flags&gt; /deploy Debug
/package<br />
devenv.exe &lt;Project.csproj or Solution.sln and other usual flags&gt; /deploy Debug
/retract<br />
Note that with the /package and /retract flags the /deploy flag is required.   
</p>
        <ul>
          <li>
CTRL-F5 no longer launches the debugger. Use F5 to launch the debugger. CTRL-F5 will
just launch the web browser and show the SharePoint site. 
</li>
          <li>
SharePoint Solution Generator Enhancements 
<ul><li>
Export from publishing sites. Note that round tripping of generated sites is not supported
for anything but the simplest of sites. Instead some editing may be required.</li></ul></li>
          <li>
Correct VB and C# Inconsistency Correction 
<ul><li>
VB VSeWSS projects no longer use VSeWSS as the root namespace</li></ul></li>
          <li>
New Item Templates for RootFiles 
<ul><li>
Create a &lt;RootFiles&gt; item from template.</li></ul></li>
          <li>
Web Part Item Template Improvements 
<ul><li>
Allows selection of deployment model to the global assembly cache (GAC) or to the
\BIN directory. For /BIN deployment a simple Code Access Security permissions set
is provided.</li></ul></li>
          <li>
Easier Web Part Project Item Rename 
<ul><li>
Detect web part rename and modify dependent files</li></ul></li>
          <li>
Support for deploying dependant assemblies added as a reference with CopyLocal=true. 
<ul><li>
VSeWSS now checks for any "CopyLocal=true" reference and incorporates this binary
in the manifest.  The binary is added to the manifest with a DeploymentTarget
matching the first binary found in the manifest, usually the project target binary. 
Subsequent changes to "CopyLocal", or removing a binary altogether will correctly
be cleaned up when rebuilding the manifest (either through WSP view or through a deployment
command).  Changes to the DeploymentTarget can be made by editing the manifest.</li></ul></li>
          <li>
Improved solution validation during full deployment 
</li>
          <li>
Validation Logging 
<ul><li>
Adding the element &lt;add key="IfLog" value="true" /&gt; to the &lt;appSettings&gt;
node of your web.config will turn on validation logging. Logging occurs during a full
deployment from a VSeWSS project and can be used for diagnostic purposes. Note: The
log location will be noted on the build output window."</li></ul></li>
          <li>
Conflict resolution dialog when deploying from within Visual Studio 
<ul><li>
Duplicate Features: If a feature with the same name as a feature you are trying to
deploy is already on the server a dialog will give you the choice of uninstalling
the existing feature first. If the feature was deployed via WSP the entire solution
is retracted. If the feature was manually installed it will be deactivated then uninstalled. 
</li><li>
Duplicate Site Definition Folders: Site definition folder is the same as 12/Templates/SiteTemplates
or the WebTemp folder already exists. The option to delete the deployed folder is
available. 
</li><li>
RootFiles and Templates: If there is a RootFile or Template with the same name the
option to delete the files first is given. 
</li><li>
Solutions: If a solution with the same name exists on the server (possibly unique
solution IDs) the option is given to retract and delete the existing solution.</li></ul></li>
          <li>
The List Definition from Content Type template now allows for the creation of a List
Definition Event Receiver.</li>
        </ul>
        <p>
Grab it from the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=fb9d4b85-da2a-432e-91fb-d505199c49f6&amp;displayLang=en#filelist" target="_blank">Microsoft
Download Center</a>.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=63bcc008-54d7-490f-82eb-23bbe1dd039a" />
      </body>
      <title>Visual Studio 2008 Extensions for WSS 3.0 v1.3 March CTP</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,63bcc008-54d7-490f-82eb-23bbe1dd039a.aspx</guid>
      <link>http://www.nivot.org/2009/03/18/VisualStudio2008ExtensionsForWSS30V13MarchCTP.aspx</link>
      <pubDate>Wed, 18 Mar 2009 15:48:40 GMT</pubDate>
      <description>&lt;p&gt;
It looks like the SharePoint team is slowly catching up to what the community has
had for years in various guises on CodePlex, but I’ve a good feeling that sometime
in the future, the community will finally be able to relax and get back to real work
as official support will surpass even the best of the open source offerings (optimistic?
we’ll see). Here’s the feature set for the current CTP:
&lt;/p&gt;
&lt;p&gt;
(These are features added in v1.3 which were not available in v1.2 or v1.1) 
&lt;p&gt;
· &lt;strong&gt;Support for developing and deploying on 64 bit (x64).&lt;/strong&gt; 
&lt;ul&gt;
&lt;li&gt;
New menu commands within Visual Studio 
&lt;ul&gt;
&lt;li&gt;
Package - package the solution but does not deploy. 
&lt;li&gt;
Retract - retracts and deletes the active solution from SharePoint. 
&lt;li&gt;
Quick Deploy 
&lt;ul&gt;
&lt;li&gt;
Copy to 12 - copies template files, modules to the 12 Hive. 
&lt;li&gt;
Copy Binarie(s) - deploys only the assemblies. 
&lt;li&gt;
Copy Both 
&lt;li&gt;
Recycle Application Pool 
&lt;li&gt;
Attach to IIS Worker Processes 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;
WSP View Improvements (Create New Feature) 
&lt;ul&gt;
&lt;li&gt;
Allows specify feature scope (Web, Site, Web Application, Farm) 
&lt;li&gt;
Allows creation of a feature receiver 
&lt;li&gt;
Option to automatically create elements.xml with new feature 
&lt;li&gt;
Elements can be dragged from one feature to another&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Build Commands Updates 
&lt;ul&gt;
&lt;li&gt;
Package command added to Visual Studio IDE and command line. 
&lt;li&gt;
Retract command added to Visual Studio IDE and command line.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
1) Command line operation is as follows:&lt;br&gt;
devenv.exe &amp;lt;Project.csproj or Solution.sln and other usual flags&amp;gt; /deploy Debug&lt;br&gt;
devenv.exe &amp;lt;Project.csproj or Solution.sln and other usual flags&amp;gt; /deploy Debug
/package&lt;br&gt;
devenv.exe &amp;lt;Project.csproj or Solution.sln and other usual flags&amp;gt; /deploy Debug
/retract&lt;br&gt;
Note that with the /package and /retract flags the /deploy flag is required.&amp;nbsp;&amp;nbsp; 
&lt;ul&gt;
&lt;li&gt;
CTRL-F5 no longer launches the debugger. Use F5 to launch the debugger. CTRL-F5 will
just launch the web browser and show the SharePoint site. 
&lt;li&gt;
SharePoint Solution Generator Enhancements 
&lt;ul&gt;
&lt;li&gt;
Export from publishing sites. Note that round tripping of generated sites is not supported
for anything but the simplest of sites. Instead some editing may be required.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Correct VB and C# Inconsistency Correction 
&lt;ul&gt;
&lt;li&gt;
VB VSeWSS projects no longer use VSeWSS as the root namespace&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
New Item Templates for RootFiles 
&lt;ul&gt;
&lt;li&gt;
Create a &amp;lt;RootFiles&amp;gt; item from template.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Web Part Item Template Improvements 
&lt;ul&gt;
&lt;li&gt;
Allows selection of deployment model to the global assembly cache (GAC) or to the
\BIN directory. For /BIN deployment a simple Code Access Security permissions set
is provided.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Easier Web Part Project Item Rename 
&lt;ul&gt;
&lt;li&gt;
Detect web part rename and modify dependent files&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Support for deploying dependant assemblies added as a reference with CopyLocal=true. 
&lt;ul&gt;
&lt;li&gt;
VSeWSS now checks for any "CopyLocal=true" reference and incorporates this binary
in the manifest.&amp;nbsp; The binary is added to the manifest with a DeploymentTarget
matching the first binary found in the manifest, usually the project target binary.&amp;nbsp;
Subsequent changes to "CopyLocal", or removing a binary altogether will correctly
be cleaned up when rebuilding the manifest (either through WSP view or through a deployment
command).&amp;nbsp; Changes to the DeploymentTarget can be made by editing the manifest.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Improved solution validation during full deployment 
&lt;li&gt;
Validation Logging 
&lt;ul&gt;
&lt;li&gt;
Adding the element &amp;lt;add key="IfLog" value="true" /&amp;gt; to the &amp;lt;appSettings&amp;gt;
node of your web.config will turn on validation logging. Logging occurs during a full
deployment from a VSeWSS project and can be used for diagnostic purposes. Note: The
log location will be noted on the build output window."&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Conflict resolution dialog when deploying from within Visual Studio 
&lt;ul&gt;
&lt;li&gt;
Duplicate Features: If a feature with the same name as a feature you are trying to
deploy is already on the server a dialog will give you the choice of uninstalling
the existing feature first. If the feature was deployed via WSP the entire solution
is retracted. If the feature was manually installed it will be deactivated then uninstalled. 
&lt;li&gt;
Duplicate Site Definition Folders: Site definition folder is the same as 12/Templates/SiteTemplates
or the WebTemp folder already exists. The option to delete the deployed folder is
available. 
&lt;li&gt;
RootFiles and Templates: If there is a RootFile or Template with the same name the
option to delete the files first is given. 
&lt;li&gt;
Solutions: If a solution with the same name exists on the server (possibly unique
solution IDs) the option is given to retract and delete the existing solution.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
The List Definition from Content Type template now allows for the creation of a List
Definition Event Receiver.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Grab it from the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=fb9d4b85-da2a-432e-91fb-d505199c49f6&amp;amp;displayLang=en#filelist" target="_blank"&gt;Microsoft
Download Center&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=63bcc008-54d7-490f-82eb-23bbe1dd039a" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,63bcc008-54d7-490f-82eb-23bbe1dd039a.aspx</comments>
      <category>.NET</category>
      <category>CodePlex</category>
      <category>SharePoint</category>
      <category>Visual Studio</category>
      <category>VSTO 3.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=fc4e157a-1bcb-4b35-8934-1ec0abcdf526</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,fc4e157a-1bcb-4b35-8934-1ec0abcdf526.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,fc4e157a-1bcb-4b35-8934-1ec0abcdf526.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=fc4e157a-1bcb-4b35-8934-1ec0abcdf526</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <strong>UPDATED 2009-03-11: BUGFIXES FOR CTP3! PLEASE RE-DOWNLOAD v0.2.1</strong>
        </p>
        <p>
One of the things I hear now and then is that while PowerShell the language can be
mastered with the requisite effort, the .NET namespace is considerable harder to get
a handle on. Wouldn’t it be nice if you could type things like:
</p>
        <p>
          <font size="3" face="Courier New">PS&gt; get-help -object [string]::format</font>
        </p>
        <p>
Since Functions take precedence over native Cmdlets in the command search order, the
first thing you might think is to create a function with the same name, get-help,
that can do this. The function itself would have the same parameters as the native
Cmdlet, and add one of its own: -object. If the arguments do not belong to the “object”
ParameterSet, then the function would splat (using the @ operator) the original arguments
to the native Cmdlet transparently and transfer control. The user is none the wiser
we had a quick peek at the arguments. So, before we run off duplicating a Cmdlet’s
surface through script, first stop, Command Proxies!
</p>
        <h4>Command Proxies
</h4>
        <p>
First off, required reading: <a href="http://blogs.msdn.com/powershell/archive/2009/01/04/extending-and-or-modifing-commands-with-proxies.aspx" target="_blank">Extending
and/or Modifying Commands with Proxies</a>. Ok, now that you’ve got read that entirely
and gotten it  out of the way, you understand that the [ProxyCommand]::Create(…)
method lets you automatically generate a function that delegates to a steppable pipeline
wrapping the original Cmdlet, right? What I did then is to pack all of these functions
into a psm1 module, create a nice psd1 <a href="http://www.nivot.org/2008/12/30/PowerShellCTP3AndModuleManifests.aspx" target="_blank">module
manifest</a> and away we go. 
</p>
        <h4>The ObjectHelp Get-Help Extension Module
</h4>
        <p>
So here’s a quick look at the help for my module, in friendly, easy to read Cmdlet
help style. The code for the PSM1 module file is way too large to dump here on my
blog like I would usually do, so it’s available at as an attachment at the foot of
the page. This help below is in a comment in the psm1 file itself. 
</p>
        <p>
        </p>
        <p>
    NAME<br />
    
<br />
        ObjectHelp Extensions Module 0.2 for PowerShell
2.0 CTP3<br />
     
<br />
    SYNOPSIS<br />
    
<br />
         Get-Help -Object allows you to display
usage and summary help for .NET Types and Members.<br />
         
<br />
    DETAILED DESCRIPTION<br />
    
<br />
        Get-Help -Object allows you to display
usage and summary help for .NET Types and Members.<br />
    
<br />
        If local documentation is not found and
the object vendor is Microsoft, you will be directed<br />
        to MSDN online to the correct page. If
the vendor is not Microsoft and vendor information<br />
        exists on the owning assembly, you will
be prompted to search for information using Microsoft<br />
        Live Search.<br />
     
<br />
    TODO<br />
     
<br />
         * localize strings into PSD1 file<br />
         * Implement caching in hashtables.
XMLDocuments are fat pigs.<br />
         * Support getting property/field
help<br />
         * PowerTab integration<br />
         * Test with Strict Parser<br />
             
<br />
    EXAMPLES<br /><br />
        # get help on a type<br />
        PS&gt; get-help -obj [int]<br /><br />
        # get help against live instances<br />
        PS&gt; $obj = new-object system.xml.xmldocument<br />
        PS&gt; get-help -obj $obj<br /><br />
        or even:<br />
        
<br />
        PS&gt; get-help -obj 42<br />
        
<br />
        # get help against methods<br />
        PS&gt; get-help -obj $obj.Load<br /><br />
        # explictly try msdn<br />
        PS&gt; get-help -obj [regex] -online<br /><br />
        # go to msdn for regex's members<br />
        PS&gt; get-help -obj [regex] -online -members<br /><br />
    CREDITS<br />
    
<br />
        Author: Oisin Grehan (MVP)<br />
        Blog  : http://www.nivot.org/<br />
    
<br />
        Have fun!  
<br /></p>
        <h4>Usage Examples
</h4>
        <p>
So what does it actually look like when you call help? If the help is available locally,
it is displayed inline in the console (or ISE). <strong>Help for all types in MSCorlib
and System is pre-cached</strong>. Any other help for types in assemblies belonging
to the BCL (Base Class Libraries – effectively the stock .NET assemblies) will be
loaded on-demand. This typically takes just a few seconds and will cached for the
rest of your session.
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/CTP3ProxyCommandTrick.NETTypesandMembers_115F7/image_2.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/CTP3ProxyCommandTrick.NETTypesandMembers_115F7/image_thumb.png" width="690" height="525" />
          </a>
        </p>
        <h4>TODO and BUGS
</h4>
        <p>
Right now, it cannot deal with properties. That is to say, trying:
</p>
        <p>
          <font size="3" face="Courier New">PS&gt; get-help –object $s.length </font>
        </p>
        <p>
where $s is a string, will get help on the property _type_, not the property itself.
I have some ideas to get around this, so if you can wait for 0.3, I’d be happy. Of
course you can wait. You have no choice. :D
</p>
        <h4>Download
</h4>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:F60BB8FA-6F02-4999-8F5E-9DD4E92C4DA7:193d6938-7635-445e-a24b-8c00fc96edd2" class="wlWriterEditableSmartContent">
          <div>
            <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/CTP3ProxyCommandTrick.NETTypesandMembers_C922/ObjectHelp-0.2.1.zip" target="_blank">ObjectHelp-0.2.1.zip</a>
          </div>
        </div>
        <p>
The two files come in a zip file. Unzip this file to ~\documents\windowspowershell\modules\objecthelp\
where ~ is your home directory. On vista/win7 this would be c:\users\username. On
XP, it would be c:\documents and settings\username. To load it, just execute:
</p>
        <p>
          <font size="3" face="Courier New">PS&gt; import-module objecthelp</font>
        </p>
        <p>
That’s it! Have fun!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=fc4e157a-1bcb-4b35-8934-1ec0abcdf526" />
      </body>
      <title>CTP3 ProxyCommand Tricks: Extending Get-Help to cover .NET Types and Members</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,fc4e157a-1bcb-4b35-8934-1ec0abcdf526.aspx</guid>
      <link>http://www.nivot.org/2009/03/10/CTP3ProxyCommandTricksExtendingGetHelpToCoverNETTypesAndMembers.aspx</link>
      <pubDate>Tue, 10 Mar 2009 04:08:54 GMT</pubDate>
      <description>&lt;p&gt;
&lt;strong&gt;UPDATED 2009-03-11: BUGFIXES FOR CTP3! PLEASE RE-DOWNLOAD v0.2.1&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
One of the things I hear now and then is that while PowerShell the language can be
mastered with the requisite effort, the .NET namespace is considerable harder to get
a handle on. Wouldn’t it be nice if you could type things like:
&lt;/p&gt;
&lt;p&gt;
&lt;font size="3" face="Courier New"&gt;PS&amp;gt; get-help -object [string]::format&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Since Functions take precedence over native Cmdlets in the command search order, the
first thing you might think is to create a function with the same name, get-help,
that can do this. The function itself would have the same parameters as the native
Cmdlet, and add one of its own: -object. If the arguments do not belong to the “object”
ParameterSet, then the function would splat (using the @ operator) the original arguments
to the native Cmdlet transparently and transfer control. The user is none the wiser
we had a quick peek at the arguments. So, before we run off duplicating a Cmdlet’s
surface through script, first stop, Command Proxies!
&lt;/p&gt;
&lt;h4&gt;Command Proxies
&lt;/h4&gt;
&lt;p&gt;
First off, required reading: &lt;a href="http://blogs.msdn.com/powershell/archive/2009/01/04/extending-and-or-modifing-commands-with-proxies.aspx" target="_blank"&gt;Extending
and/or Modifying Commands with Proxies&lt;/a&gt;. Ok, now that you’ve got read that entirely
and gotten it&amp;nbsp; out of the way, you understand that the [ProxyCommand]::Create(…)
method lets you automatically generate a function that delegates to a steppable pipeline
wrapping the original Cmdlet, right? What I did then is to pack all of these functions
into a psm1 module, create a nice psd1 &lt;a href="http://www.nivot.org/2008/12/30/PowerShellCTP3AndModuleManifests.aspx" target="_blank"&gt;module
manifest&lt;/a&gt; and away we go. 
&lt;/p&gt;
&lt;h4&gt;The ObjectHelp Get-Help Extension Module
&lt;/h4&gt;
&lt;p&gt;
So here’s a quick look at the help for my module, in friendly, easy to read Cmdlet
help style. The code for the PSM1 module file is way too large to dump here on my
blog like I would usually do, so it’s available at as an attachment at the foot of
the page. This help below is in a comment in the psm1 file itself. 
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; NAME&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ObjectHelp Extensions Module 0.2 for PowerShell
2.0 CTP3&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; SYNOPSIS&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Get-Help -Object allows you to display
usage and summary help for .NET Types and Members.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; DETAILED DESCRIPTION&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Get-Help -Object allows you to display
usage and summary help for .NET Types and Members.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If local documentation is not found and
the object vendor is Microsoft, you will be directed&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; to MSDN online to the correct page. If
the vendor is not Microsoft and vendor information&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exists on the owning assembly, you will
be prompted to search for information using Microsoft&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Live Search.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; TODO&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * localize strings into PSD1 file&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Implement caching in hashtables.
XMLDocuments are fat pigs.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Support getting property/field
help&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * PowerTab integration&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Test with Strict Parser&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; EXAMPLES&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # get help on a type&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PS&amp;gt; get-help -obj [int]&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # get help against live instances&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PS&amp;gt; $obj = new-object system.xml.xmldocument&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PS&amp;gt; get-help -obj $obj&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; or even:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PS&amp;gt; get-help -obj 42&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # get help against methods&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PS&amp;gt; get-help -obj $obj.Load&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # explictly try msdn&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PS&amp;gt; get-help -obj [regex] -online&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # go to msdn for regex's members&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PS&amp;gt; get-help -obj [regex] -online -members&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CREDITS&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Author: Oisin Grehan (MVP)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Blog&amp;nbsp; : http://www.nivot.org/&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Have fun!&amp;nbsp; 
&lt;br&gt;
&lt;/p&gt;
&lt;h4&gt;Usage Examples
&lt;/h4&gt;
&lt;p&gt;
So what does it actually look like when you call help? If the help is available locally,
it is displayed inline in the console (or ISE). &lt;strong&gt;Help for all types in MSCorlib
and System is pre-cached&lt;/strong&gt;. Any other help for types in assemblies belonging
to the BCL (Base Class Libraries – effectively the stock .NET assemblies) will be
loaded on-demand. This typically takes just a few seconds and will cached for the
rest of your session.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/CTP3ProxyCommandTrick.NETTypesandMembers_115F7/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/CTP3ProxyCommandTrick.NETTypesandMembers_115F7/image_thumb.png" width="690" height="525"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;h4&gt;TODO and BUGS
&lt;/h4&gt;
&lt;p&gt;
Right now, it cannot deal with properties. That is to say, trying:
&lt;/p&gt;
&lt;p&gt;
&lt;font size="3" face="Courier New"&gt;PS&amp;gt; get-help –object $s.length &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
where $s is a string, will get help on the property _type_, not the property itself.
I have some ideas to get around this, so if you can wait for 0.3, I’d be happy. Of
course you can wait. You have no choice. :D
&lt;/p&gt;
&lt;h4&gt;Download
&lt;/h4&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:F60BB8FA-6F02-4999-8F5E-9DD4E92C4DA7:193d6938-7635-445e-a24b-8c00fc96edd2" class="wlWriterEditableSmartContent"&gt;
&lt;div&gt;&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/CTP3ProxyCommandTrick.NETTypesandMembers_C922/ObjectHelp-0.2.1.zip" target="_blank"&gt;ObjectHelp-0.2.1.zip&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
The two files come in a zip file. Unzip this file to ~\documents\windowspowershell\modules\objecthelp\
where ~ is your home directory. On vista/win7 this would be c:\users\username. On
XP, it would be c:\documents and settings\username. To load it, just execute:
&lt;/p&gt;
&lt;p&gt;
&lt;font size="3" face="Courier New"&gt;PS&amp;gt; import-module objecthelp&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
That’s it! Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=fc4e157a-1bcb-4b35-8934-1ec0abcdf526" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,fc4e157a-1bcb-4b35-8934-1ec0abcdf526.aspx</comments>
      <category>.NET</category>
      <category>CTP3</category>
      <category>Modules</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=d7e51c78-95bb-424d-bafa-fd1d31a6eca8</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,d7e51c78-95bb-424d-bafa-fd1d31a6eca8.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,d7e51c78-95bb-424d-bafa-fd1d31a6eca8.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=d7e51c78-95bb-424d-bafa-fd1d31a6eca8</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A couple of months ago I had a brief Q&amp;A with the cdndevs guys over on blogs.msdn.com.
It looks like it went live recently because I’ve been getting stopped in the streets
and harassed for a photo etc. No, not really. But if you want to read, take a look
over at <a title="http://blogs.msdn.com/cdndevs/archive/2009/02/12/mvp-insider-q-a-with-oisin-grehan.aspx" href="http://blogs.msdn.com/cdndevs/archive/2009/02/12/mvp-insider-q-a-with-oisin-grehan.aspx">http://blogs.msdn.com/cdndevs/archive/2009/02/12/mvp-insider-q-a-with-oisin-grehan.aspx</a> ;-)
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=d7e51c78-95bb-424d-bafa-fd1d31a6eca8" />
      </body>
      <title>Q&amp;A on Yours Truly for Microsoft Canadian Developers Connection</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,d7e51c78-95bb-424d-bafa-fd1d31a6eca8.aspx</guid>
      <link>http://www.nivot.org/2009/02/13/QAOnYoursTrulyForMicrosoftCanadianDevelopersConnection.aspx</link>
      <pubDate>Fri, 13 Feb 2009 23:55:32 GMT</pubDate>
      <description>&lt;p&gt;
A couple of months ago I had a brief Q&amp;amp;A with the cdndevs guys over on blogs.msdn.com.
It looks like it went live recently because I’ve been getting stopped in the streets
and harassed for a photo etc. No, not really. But if you want to read, take a look
over at &lt;a title="http://blogs.msdn.com/cdndevs/archive/2009/02/12/mvp-insider-q-a-with-oisin-grehan.aspx" href="http://blogs.msdn.com/cdndevs/archive/2009/02/12/mvp-insider-q-a-with-oisin-grehan.aspx"&gt;http://blogs.msdn.com/cdndevs/archive/2009/02/12/mvp-insider-q-a-with-oisin-grehan.aspx&lt;/a&gt; ;-)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=d7e51c78-95bb-424d-bafa-fd1d31a6eca8" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,d7e51c78-95bb-424d-bafa-fd1d31a6eca8.aspx</comments>
      <category>.NET</category>
      <category>Microsoft</category>
      <category>MVP</category>
      <category>PowerShell</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=c5db121f-cd3d-4a29-9516-737d8094005e</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,c5db121f-cd3d-4a29-9516-737d8094005e.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,c5db121f-cd3d-4a29-9516-737d8094005e.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=c5db121f-cd3d-4a29-9516-737d8094005e</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Some of you may have heard that CTP3 has support for transferring files from remote
servers using BITS (<a href="http://en.wikipedia.org/wiki/Background_Intelligent_Transfer_Service" target="_blank">Background
Intelligent Transfer Service</a>) and quite possibly had a little dig around for it.
It’s not easy to find as using “get-help BITS” will not return any help unless you’ve
already loaded the module. Not a great win for discoverability, but hey, sometimes
you just have to read the manual, expletive deleted. So, lets have a quick look at
how this works. 
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_2.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_thumb.png" width="527" height="365" />
          </a>
        </p>
        <p>
So, ok, we can see we’ve got a module for <strong>FileTransfer</strong> (BITS), but
where did this come from? Take a peek into $pshome\Modules to find out. This is the
location for system-wide (global) modules. It rests under $PSHome, which is the home
for PowerShell, in $env:systemroot\windowspowershell\v1.0. 
</p>
        <p style="padding-bottom: 5px; background-color: lightgray; margin: 20px; padding-left: 5px; padding-right: 5px; padding-top: 5px">
Yes, even PowerShell v2 lives there. This is one of those unfortunate things whereby
the team decided early on that they would support side-by-side versions of PowerShell,
implying that v2 might not be backwards compatible with v1. This is reflected also
in the choice of file extension: ps1. The extension ps2 would have been used for v2.
This was probably a poor show of faith in their own abilities to design such a great
version one product, because as it turns out, v1.0 was such an excellent release that
they were able to build on it for v2 without compromising, or breaking backwards compatibility
(apart from a couple of minor edge cases, mainly bugfixes). So, the end result is
that future versions of PowerShell will inherit the $pshome, pay a little inheritance
tax and hopefully avoid foreclosure :).
</p>
        <p>
The files in the FileTransfer module directory are laid out as follows: 
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_4.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_thumb_1.png" width="621" height="248" />
          </a>
        </p>
        <p>
          <em>(Hey look! another built-in module – <strong>PSDiagnostics</strong> - I’ll leave
that one for you guys to explore).</em>
        </p>
        <p>
So, there are four files there. A ps1xml Format file, which tells PowerShell how to
textually render the .NET objects returned by the Cmdlets. A psd1 <a href="http://www.nivot.org/2008/12/30/PowerShellCTP3AndModuleManifests.aspx" target="_blank">Module
Manifest</a> file, which tells PowerShell what files comprise the Module and a binary
DLL which in this case does NOT contain the Cmdlets, but instead is what’s called
an “Interop Assembly.”  (sometimes known as Primary Interop Assemblies or PIAs,
read about them here: <a title="Primary Interop Assemblies" href="http://msdn.microsoft.com/en-us/library/aax7sdch.aspx">Primary
Interop Assemblies</a> – there are subtle differences between IAs and PIAs, but not
enough to warrant discussion here). Essentially this DLL lets .NET, and by extension,
PowerShell, talk to the native COM APIs that wrap the BITS services on XP,Vista,Win7,Win
2003 and Win 2008. Lets take a peek into the Module Manifest:
</p>
        <!-- Stylesheet link -->
        <link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" />
        <!-- Code -->
        <div id="hlDiv" class="dp-highlighter">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span>@{   </span>
              </span>
            </li>
            <li>
              <span>GUID=</span>
              <span class="string">"{8FA5064B-8479-4c5c-86EA-0D311FE48875}"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>Author=</span>
              <span class="string">"Microsoft Corporation"</span>
              <span>  </span>
            </li>
            <li>
              <span>CompanyName=</span>
              <span class="string">"Microsoft Corporation"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>Copyright=</span>
              <span class="string">"c Microsoft Corporation. All rights reserved."</span>
              <span>  </span>
            </li>
            <li>
              <span>ModuleVersion=</span>
              <span class="string">"1.0.0.0"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>Description=</span>
              <span class="string">"Powershell File Transfer Module"</span>
              <span>  </span>
            </li>
            <li>
              <span>PowerShellVersion=</span>
              <span class="string">"2.0"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>CLRVersion=</span>
              <span class="string">"2.0"</span>
              <span>  </span>
            </li>
            <li>
              <span>
                <strong>NestedModules</strong>=</span>
              <span class="string">"Microsoft.BackgroundIntelligentTransfer.Management"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>FormatsToProcess=</span>
              <span class="string">"FileTransfer.Format.ps1xml"</span>
              <span>  </span>
            </li>
            <li>
              <span>
                <strong>RequiredAssemblies</strong>=</span>
              <span class="builtin">Join-Path</span>
              <span> </span>
              <span class="variable">$psScriptRoot</span>
              <span> </span>
              <span class="string">"Microsoft.BackgroundIntelligentTransfer.Management.Interop.dll"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>}  </span>
            </li>
          </ol>
        </div>
        <p>
If it looks like I just dumped a Hashtable out, you’re right. That’s all a manifest
is: a Hashtable. Of course, the key names are important and in this case, lets take
a look at two in particular, <strong>NestedModules</strong> and <strong>RequiredAssemblies</strong>.
</p>
        <p>
The RequiredAssemblies key is responsible for actively loading .NET assemblies containing
standard .NET types. It does not extract Providers and Cmdlets and add them to the
runspace; this is what the other key, NestedModules, does. Like I said already, this
DLL is the interop assembly. So where is the NestedModules loading that other module
from? I don’t see any other DLLs in the directory, and I <em>know</em> there are no
Cmdlets in that interop assembly. Lets take a peek at one of the Cmdlets itself and
find out:
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_8.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_thumb_3.png" width="575" height="526" />
          </a>
        </p>
        <p>
        </p>
        <p>
Aha, it’s reading it from the GAC. When PowerShell was installed, it must have installed
this DLL there. This is the DLL that contains our Cmdlets. I know this is true because
I used one of the Cmdlets to tell me where it lives. “GCM” is the alias for Get-Command
which will get us metadata about any given command in PowerShell (including functions
– new to v2).
</p>
        <p>
So, lets use a one-liner to get the names of all the Cmdlets in this module, and the
synopsis summary for the help:
</p>
        <div id="hlDiv" class="dp-highlighter">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span>gcm -module filetransfer | % { </span>
                <span class="variable">$_</span>
                <span> |
select name, @{Name=</span>
                <span class="string">"Help"</span>
                <span>;Expression={&amp; </span>
                <span class="variable">$_</span>
                <span> -?
| select -expand synopsis }}} | convertto-html –fragment  </span>
              </span>
            </li>
          </ol>
        </div>
        <p>
This yields the following:
</p>
        <table>
          <colgroup>
            <col />
            <col />
          </colgroup>
          <tbody>
            <tr>
              <th>
Name</th>
              <th>
Help</th>
            </tr>
            <tr>
              <td>
Add-FileTransfer</td>
              <td>
Adds one or more files to an existing Background Intelligent Transfer Service (BITS)
t ransfer job.</td>
            </tr>
            <tr>
              <td>
Clear-FileTransfer</td>
              <td>
Cancels a Background Intelligent Transfer Service (BITS) transfer job.</td>
            </tr>
            <tr>
              <td>
Complete-FileTransfer</td>
              <td>
Completes a Background Intelligent Transfer Service (BITS) transfer job.</td>
            </tr>
            <tr>
              <td>
Get-FileTransfer</td>
              <td>
Retrieves the associated BitsJob object for an existing Background Intelligent Transfe
r Service (BITS) transfer job.</td>
            </tr>
            <tr>
              <td>
New-FileTransfer</td>
              <td>
Creates a new Background Intelligent Transfer Service (BITS) transfer job.</td>
            </tr>
            <tr>
              <td>
Resume-FileTransfer</td>
              <td>
Resumes a Background Intelligent Transfer Service (BITS) transfer job.</td>
            </tr>
            <tr>
              <td>
Set-FileTransfer</td>
              <td>
Modifies the properties of an existing Business Intelligent Transfer Service (BITS)
tr ansfer job.</td>
            </tr>
            <tr>
              <td>
Suspend-FileTransfer</td>
              <td>
Suspends a Background Intelligent Transfer Service (BITS) transfer job.</td>
            </tr>
          </tbody>
        </table>
        <p>
I guess this covers it for the moment. Going into a full discussion about how BITS
actually works is worth another post in itself. Suffice it to say, there are plenty
of examples in the help itself. Just run:
</p>
        <p>
          <strong>get-help add-filetransfer –example | more</strong>
        </p>
        <p>
To see an example on how to use the Cmdlet (or any of the others). The team have done
a good job here.
</p>
        <p>
Have fun!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=c5db121f-cd3d-4a29-9516-737d8094005e" />
      </body>
      <title>Anatomy of a PowerShell Module: The FileTransfer (BITS) Module</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,c5db121f-cd3d-4a29-9516-737d8094005e.aspx</guid>
      <link>http://www.nivot.org/2009/02/10/AnatomyOfAPowerShellModuleTheFileTransferBITSModule.aspx</link>
      <pubDate>Tue, 10 Feb 2009 18:38:27 GMT</pubDate>
      <description>&lt;p&gt;
Some of you may have heard that CTP3 has support for transferring files from remote
servers using BITS (&lt;a href="http://en.wikipedia.org/wiki/Background_Intelligent_Transfer_Service" target="_blank"&gt;Background
Intelligent Transfer Service&lt;/a&gt;) and quite possibly had a little dig around for it.
It’s not easy to find as using “get-help BITS” will not return any help unless you’ve
already loaded the module. Not a great win for discoverability, but hey, sometimes
you just have to read the manual, expletive deleted. So, lets have a quick look at
how this works. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_thumb.png" width="527" height="365"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
So, ok, we can see we’ve got a module for &lt;strong&gt;FileTransfer&lt;/strong&gt; (BITS), but
where did this come from? Take a peek into $pshome\Modules to find out. This is the
location for system-wide (global) modules. It rests under $PSHome, which is the home
for PowerShell, in $env:systemroot\windowspowershell\v1.0. 
&lt;/p&gt;
&lt;p style="padding-bottom: 5px; background-color: lightgray; margin: 20px; padding-left: 5px; padding-right: 5px; padding-top: 5px"&gt;
Yes, even PowerShell v2 lives there. This is one of those unfortunate things whereby
the team decided early on that they would support side-by-side versions of PowerShell,
implying that v2 might not be backwards compatible with v1. This is reflected also
in the choice of file extension: ps1. The extension ps2 would have been used for v2.
This was probably a poor show of faith in their own abilities to design such a great
version one product, because as it turns out, v1.0 was such an excellent release that
they were able to build on it for v2 without compromising, or breaking backwards compatibility
(apart from a couple of minor edge cases, mainly bugfixes). So, the end result is
that future versions of PowerShell will inherit the $pshome, pay a little inheritance
tax and hopefully avoid foreclosure :).
&lt;/p&gt;
&lt;p&gt;
The files in the FileTransfer module directory are laid out as follows: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_thumb_1.png" width="621" height="248"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;(Hey look! another built-in module – &lt;strong&gt;PSDiagnostics&lt;/strong&gt; - I’ll leave
that one for you guys to explore).&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
So, there are four files there. A ps1xml Format file, which tells PowerShell how to
textually render the .NET objects returned by the Cmdlets. A psd1 &lt;a href="http://www.nivot.org/2008/12/30/PowerShellCTP3AndModuleManifests.aspx" target="_blank"&gt;Module
Manifest&lt;/a&gt; file, which tells PowerShell what files comprise the Module and a binary
DLL which in this case does NOT contain the Cmdlets, but instead is what’s called
an “Interop Assembly.”&amp;nbsp; (sometimes known as Primary Interop Assemblies or PIAs,
read about them here: &lt;a title="Primary Interop Assemblies" href="http://msdn.microsoft.com/en-us/library/aax7sdch.aspx"&gt;Primary
Interop Assemblies&lt;/a&gt; – there are subtle differences between IAs and PIAs, but not
enough to warrant discussion here). Essentially this DLL lets .NET, and by extension,
PowerShell, talk to the native COM APIs that wrap the BITS services on XP,Vista,Win7,Win
2003 and Win 2008. Lets take a peek into the Module Manifest:
&lt;/p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css"&gt;
&lt;!-- Code --&gt;
&lt;div id="hlDiv" class="dp-highlighter"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span&gt;@{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;GUID=&lt;/span&gt;&lt;span class="string"&gt;"{8FA5064B-8479-4c5c-86EA-0D311FE48875}"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;Author=&lt;/span&gt;&lt;span class="string"&gt;"Microsoft Corporation"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;CompanyName=&lt;/span&gt;&lt;span class="string"&gt;"Microsoft Corporation"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;Copyright=&lt;/span&gt;&lt;span class="string"&gt;"c Microsoft Corporation. All rights reserved."&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;ModuleVersion=&lt;/span&gt;&lt;span class="string"&gt;"1.0.0.0"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;Description=&lt;/span&gt;&lt;span class="string"&gt;"Powershell File Transfer Module"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;PowerShellVersion=&lt;/span&gt;&lt;span class="string"&gt;"2.0"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;CLRVersion=&lt;/span&gt;&lt;span class="string"&gt;"2.0"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&lt;strong&gt;NestedModules&lt;/strong&gt;=&lt;/span&gt;&lt;span class="string"&gt;"Microsoft.BackgroundIntelligentTransfer.Management"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;FormatsToProcess=&lt;/span&gt;&lt;span class="string"&gt;"FileTransfer.Format.ps1xml"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&lt;strong&gt;RequiredAssemblies&lt;/strong&gt;=&lt;/span&gt;&lt;span class="builtin"&gt;Join-Path&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="variable"&gt;$psScriptRoot&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"Microsoft.BackgroundIntelligentTransfer.Management.Interop.dll"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;}&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
If it looks like I just dumped a Hashtable out, you’re right. That’s all a manifest
is: a Hashtable. Of course, the key names are important and in this case, lets take
a look at two in particular, &lt;strong&gt;NestedModules&lt;/strong&gt; and &lt;strong&gt;RequiredAssemblies&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
The RequiredAssemblies key is responsible for actively loading .NET assemblies containing
standard .NET types. It does not extract Providers and Cmdlets and add them to the
runspace; this is what the other key, NestedModules, does. Like I said already, this
DLL is the interop assembly. So where is the NestedModules loading that other module
from? I don’t see any other DLLs in the directory, and I &lt;em&gt;know&lt;/em&gt; there are no
Cmdlets in that interop assembly. Lets take a peek at one of the Cmdlets itself and
find out:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_8.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Pow.0CTP3andthebuiltinFileTransferModule_ACD3/image_thumb_3.png" width="575" height="526"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Aha, it’s reading it from the GAC. When PowerShell was installed, it must have installed
this DLL there. This is the DLL that contains our Cmdlets. I know this is true because
I used one of the Cmdlets to tell me where it lives. “GCM” is the alias for Get-Command
which will get us metadata about any given command in PowerShell (including functions
– new to v2).
&lt;/p&gt;
&lt;p&gt;
So, lets use a one-liner to get the names of all the Cmdlets in this module, and the
synopsis summary for the help:
&lt;/p&gt;
&lt;div id="hlDiv" class="dp-highlighter"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span&gt;gcm -module filetransfer | % { &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt; |
select name, @{Name=&lt;/span&gt;&lt;span class="string"&gt;"Help"&lt;/span&gt;&lt;span&gt;;Expression={&amp;amp; &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt; -?
| select -expand synopsis }}} | convertto-html –fragment&amp;nbsp; &lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
This yields the following:
&lt;/p&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;
Name&lt;/th&gt;
&lt;th&gt;
Help&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Add-FileTransfer&lt;/td&gt;
&lt;td&gt;
Adds one or more files to an existing Background Intelligent Transfer Service (BITS)
t ransfer job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Clear-FileTransfer&lt;/td&gt;
&lt;td&gt;
Cancels a Background Intelligent Transfer Service (BITS) transfer job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Complete-FileTransfer&lt;/td&gt;
&lt;td&gt;
Completes a Background Intelligent Transfer Service (BITS) transfer job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-FileTransfer&lt;/td&gt;
&lt;td&gt;
Retrieves the associated BitsJob object for an existing Background Intelligent Transfe
r Service (BITS) transfer job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
New-FileTransfer&lt;/td&gt;
&lt;td&gt;
Creates a new Background Intelligent Transfer Service (BITS) transfer job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Resume-FileTransfer&lt;/td&gt;
&lt;td&gt;
Resumes a Background Intelligent Transfer Service (BITS) transfer job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Set-FileTransfer&lt;/td&gt;
&lt;td&gt;
Modifies the properties of an existing Business Intelligent Transfer Service (BITS)
tr ansfer job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Suspend-FileTransfer&lt;/td&gt;
&lt;td&gt;
Suspends a Background Intelligent Transfer Service (BITS) transfer job.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
I guess this covers it for the moment. Going into a full discussion about how BITS
actually works is worth another post in itself. Suffice it to say, there are plenty
of examples in the help itself. Just run:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;get-help add-filetransfer –example | more&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
To see an example on how to use the Cmdlet (or any of the others). The team have done
a good job here.
&lt;/p&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=c5db121f-cd3d-4a29-9516-737d8094005e" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,c5db121f-cd3d-4a29-9516-737d8094005e.aspx</comments>
      <category>.NET</category>
      <category>BITS</category>
      <category>Cmdlets</category>
      <category>CTP3</category>
      <category>Modules</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=f33b33fb-273a-4c45-9695-cdcc0c768aaf</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,f33b33fb-273a-4c45-9695-cdcc0c768aaf.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,f33b33fb-273a-4c45-9695-cdcc0c768aaf.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=f33b33fb-273a-4c45-9695-cdcc0c768aaf</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It’s been quite a few years -- November 14, 2006 to be exact -- since the final release
of <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> 1.0.
Let’s see what the <a href="http://blogs.msdn.com/powershell" target="_blank">lazy
buggers</a> have been up to since then. Only kidding, they’re far from lazy; we’ve
gained an extra one hundred and six new cmdlets, moving from 131 to 237. We’ve also
gained another provider, WSManProvider which lets you explore and manipulate the WS-Man
configuration. Finally, the number of public Types (.NET classes usable by 3rd parties
to extend PowerShell) has increased from 447 to 749. So how do I know all this? Well,
some months ago I wrote a suite of build analysis Cmdlets for examining the assemblies
that comprise PowerShell. In its current form it’s of very little use to 3rd parties,
but I’ve had some requests to open it up and allow it to analyze any binary modules
and snap-ins, which is a good idea I think. Watch this space. Anyway, I’m going to
dump out some interest information on the differences between v1.0 and v2.0 CTP3,
along with the one-liners I’m using to generate the information. 
</p>
        <p>
          <em>
            <strong>update feb 5</strong>: added breaking changes</em>
        </p>
        <h4>
          <b>Breaking Changes to Windows PowerShell 1.0</b>
          <u>
          </u>
        </h4>
        <p>
          <u>
          </u>
        </p>
        <p>
The following changes in Windows PowerShell V2.0 CTP3 might prevent features designed
for Windows PowerShell 1.0 from working correctly.<u></u></p>
        <ul>
          <ul>
            <li>
              <div align="left">The value of the <b>PowerShellVersion</b> registry entry in HKLM\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine
has been changed to <b>2.0</b>.
</div>
            </li>
            <li>
              <div align="left">New cmdlets and variables have been added. These are listed below.
These new elements might conflict with variables and functions in profiles and scripts.
</div>
            </li>
            <li>
              <div align="left">
                <b>-</b>IEQ operator does a case insensitive comparison on characters.
</div>
            </li>
            <li>
              <div align="left">Get-Command gets functions along with cmdlets by default. 
</div>
            </li>
            <li>
              <div align="left">Any native command that generates a user interface blocks if it
is pipelined to the Out-Host cmdlet.
</div>
            </li>
            <li>
              <div align="left">Added new language keywords: <b>Begin</b>, <strong>Process, </strong>and<strong> End</strong>.
Any commands called <b>begin</b>, <b>process</b> or <b>end</b> are interpreted as
language keywords and might result in parsing errors. 
</div>
            </li>
            <li>
              <div align="left">Cmdlet name resolution has changed. In Windows PowerShell 1.0, a
runtime error was generated when two Windows PowerShell snap-ins exported cmdlets
with the same name. In Windows PowerShell V2, the last cmdlet loaded is the one that
is executed if the cmdlet name is not qualified by a snap-in name.
</div>
            </li>
            <li>
              <div align="left">Terminating errors that are thrown in a pipeline do not terminate
the pipeline. Instead, they are written to the host. 
</div>
            </li>
            <li>
              <div align="left">A function called with '-?' parameter gets the help topic for the
function, if one is included in the function. 
</div>
            </li>
          </ul>
        </ul>
        <p>
There are no changes to Cmdlets other than Get-Command’s –PSSnapin parameter is now
an alias to a –Module parameter. This reflects the move away from administrator-installed
snap-ins, and towards the friendlier Module system. For all intents and purposes,
you can treat v1 snapins as modules as load them as such with the Import-Module Cmdlet.
</p>
        <h4>New Cmdlets
</h4>
        <p>
Here are the new Cmdlets, sorted by noun and alongside the textual synopsis is one
is present in the CTP3 help, or the syntax if there is no help. The command I ran
to generate this was:
</p>
        <p>
          <!-- Stylesheet link -->
        </p>
        <link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" />
        <!-- Code -->
        <div id="hlDiv" class="dp-highlighter">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span>compare-psbuildinfo (import-psbuildinfo .\rtm-6-0-6000-16386.psbuild)
(import-psbuildinfo .\win7beta1-6-1-7000-0.psbuild) | ? {</span>
                <span class="variable">$_</span>
                <span>.diff
-eq </span>
                <span class="string">"Added"</span>
                <span>} | sort noun | % { </span>
                <span class="variable">$_</span>
                <span> |
add-member -name Synopsis -member noteproperty -value (&amp; </span>
                <span class="variable">$_</span>
                <span>.name
-?</span>
                <span class="variable">|select</span>
                <span> -expand synopsis) -passthru }
| select name,synopsis | convertto-html -fragment &gt; new-cmdlets.htm  </span>
              </span>
            </li>
          </ol>
        </div>
        <p>
        </p>
        <style type="text/css">
          <!--
#cmdlets tr td { vertical-align: top; border-top: 1px solid gray; text-align: left; }
-->
        </style>
        <table id="cmdlets">
          <colgroup>
            <col />
            <col />
          </colgroup>
          <tbody>
            <tr>
              <th>
Name</th>
              <th>
Synopsis</th>
            </tr>
            <tr>
              <td>
Invoke-Command</td>
              <td>
Runs commands on local and remote computers.</td>
            </tr>
            <tr>
              <td>
Add-Computer</td>
              <td>
Adds computers to a domain or workgroup.</td>
            </tr>
            <tr>
              <td>
Remove-Computer</td>
              <td>
Removes computers from workgroups or domains.</td>
            </tr>
            <tr>
              <td>
Rename-Computer</td>
              <td>
Renames a computer.</td>
            </tr>
            <tr>
              <td>
Restore-Computer</td>
              <td>
Starts a system restore on the local computer.</td>
            </tr>
            <tr>
              <td>
Checkpoint-Computer</td>
              <td>
Creates a system restore point on the local computer.</td>
            </tr>
            <tr>
              <td>
Restart-Computer</td>
              <td>
Restarts ("reboots") the operating system on local and remote computers.</td>
            </tr>
            <tr>
              <td>
Stop-Computer</td>
              <td>
Stops (shuts down) local and remote computers.</td>
            </tr>
            <tr>
              <td>
Reset-ComputerMachinePassword</td>
              <td>
Resets the machine account password for the computer.</td>
            </tr>
            <tr>
              <td>
Disable-ComputerRestore</td>
              <td>
Disables the System Restore feature on the specified file system drive.</td>
            </tr>
            <tr>
              <td>
Enable-ComputerRestore</td>
              <td>
Enables the System Restore feature on the specified file system drive.</td>
            </tr>
            <tr>
              <td>
Get-ComputerRestorePoint</td>
              <td>
Gets the restore points on the local computer.</td>
            </tr>
            <tr>
              <td>
Test-ComputerSecureChannel</td>
              <td>
Test-ComputerSecureChannel [-Repair] [-Server &lt;String&gt;] [-Verbose] [-Debug]
[-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] [-WhatIf] [-Confirm] 
</td>
            </tr>
            <tr>
              <td>
Test-Connection</td>
              <td>
Sends ICMP echo request packets ("pings") to one or more computers.</td>
            </tr>
            <tr>
              <td>
Export-Counter</td>
              <td>
The Export-Counter cmdlet takes PerformanceCounterSampleSet objects and exports them
as counter log files.</td>
            </tr>
            <tr>
              <td>
Import-Counter</td>
              <td>
Imports performance counter log files (.blg, .csv, .tsv) and creates the objects that
represent each counter sample in the log.</td>
            </tr>
            <tr>
              <td>
Get-Counter</td>
              <td>
Gets performance counter data from local and remote computers.</td>
            </tr>
            <tr>
              <td>
ConvertFrom-Csv</td>
              <td>
Converts object properties in CSV format into CSV versions of the original objects.</td>
            </tr>
            <tr>
              <td>
ConvertTo-Csv</td>
              <td>
Converts .NET objects into a series of comma-separated, variable-length (CSV) strings.</td>
            </tr>
            <tr>
              <td>
Register-EngineEvent</td>
              <td>
Register-EngineEvent [-SourceIdentifier] &lt;String&gt; [[-Action] &lt;ScriptBlock&gt;]
[-MessageData &lt;PSObject&gt;] [-SupportEvent] [-Forward] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Unregister-Event</td>
              <td>
Unregister-Event [-SourceIdentifier] &lt;String&gt; [-Force] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] [-WhatIf] [-Confirm] Unregister-Event [-SubscriptionId] &lt;Int32&gt;
[-Force] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction
&lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;]
[-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] [-WhatIf] [-Confirm] 
</td>
            </tr>
            <tr>
              <td>
New-Event</td>
              <td>
New-Event [-SourceIdentifier] &lt;String&gt; [[-Sender] &lt;PSObject&gt;] [[-EventArguments]
&lt;PSObject[]&gt;] [[-MessageData] &lt;PSObject&gt;] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Remove-Event</td>
              <td>
Remove-Event [-SourceIdentifier] &lt;String&gt; [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] [-WhatIf] [-Confirm] Remove-Event [-EventIdentifier] &lt;Int32&gt;
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] [-WhatIf] [-Confirm] 
</td>
            </tr>
            <tr>
              <td>
Wait-Event</td>
              <td>
Wait-Event [[-SourceIdentifier] &lt;String&gt;] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Get-Event</td>
              <td>
Get-Event [[-SourceIdentifier] &lt;String&gt;] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Show-EventLog</td>
              <td>
Displays the event logs of the local or a remote computer in Event Viewer.</td>
            </tr>
            <tr>
              <td>
New-EventLog</td>
              <td>
Creates a new event log and a new event source on a local or remote computer.</td>
            </tr>
            <tr>
              <td>
Remove-EventLog</td>
              <td>
Deletes an event log or unregisters an event source.</td>
            </tr>
            <tr>
              <td>
Clear-EventLog</td>
              <td>
Deletes all entries from specified event logs on the local or remote computers.</td>
            </tr>
            <tr>
              <td>
Write-EventLog</td>
              <td>
Writes an event to an event log.</td>
            </tr>
            <tr>
              <td>
Limit-EventLog</td>
              <td>
Sets the event log properties that limit the size of the event log and the age of
its entries.</td>
            </tr>
            <tr>
              <td>
Get-EventSubscriber</td>
              <td>
Get-EventSubscriber [[-SourceIdentifier] &lt;String&gt;] [-Force] [-Verbose] [-Debug]
[-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Export-FormatData</td>
              <td>
Export-FormatData [-InputObject &lt;ExtendedTypeDefinition[]&gt;] [-FilePath &lt;String&gt;]
[-Force] [-NoClobber] [-IncludeScriptBlock] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Get-FormatData</td>
              <td>
Get-FormatData [[-TypeName] &lt;String[]&gt;] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Out-GridView</td>
              <td>
Sends output to an interactive table in a separate window.</td>
            </tr>
            <tr>
              <td>
Clear-History</td>
              <td>
Deletes entries from the command history.</td>
            </tr>
            <tr>
              <td>
Get-HotFix</td>
              <td>
Gets the QFE updates that have been applied to the local and remote computers.</td>
            </tr>
            <tr>
              <td>
Stop-Job</td>
              <td>
Stops a Windows PowerShell background job.</td>
            </tr>
            <tr>
              <td>
Wait-Job</td>
              <td>
Suppresses the command prompt until one or all of the Windows PowerShell background
jobs running in the session are complete.</td>
            </tr>
            <tr>
              <td>
Remove-Job</td>
              <td>
Deletes a Windows PowerShell background job.</td>
            </tr>
            <tr>
              <td>
Start-Job</td>
              <td>
Starts a Windows PowerShell background job.</td>
            </tr>
            <tr>
              <td>
Get-Job</td>
              <td>
Gets Windows PowerShell background jobs that are running in the current session.</td>
            </tr>
            <tr>
              <td>
Receive-Job</td>
              <td>
Gets the results of the Windows PowerShell background jobs in the current session.
You can use this cmdlet to retrieve the output and errors of background jobs.</td>
            </tr>
            <tr>
              <td>
Update-List</td>
              <td>
Adds and removes items from a property value that contains a collection of objects.</td>
            </tr>
            <tr>
              <td>
Import-LocalizedData</td>
              <td>
Imports language-specific data into scripts and functions based on the UI culture
that is selected for the operating system.</td>
            </tr>
            <tr>
              <td>
Send-MailMessage</td>
              <td>
Sends an e-mail message.</td>
            </tr>
            <tr>
              <td>
Get-Module</td>
              <td>
Get-Module [[-Name] &lt;String[]&gt;] [-All] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] Get-Module
[[-Name] &lt;String[]&gt;] [-ListAvailable] [-Recurse] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Remove-Module</td>
              <td>
Remove-Module [-Name] &lt;String[]&gt; [-Force] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] [-WhatIf] [-Confirm] Remove-Module [-ModuleInfo] &lt;PSModuleInfo[]&gt;
[-Force] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction
&lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;]
[-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] [-WhatIf] [-Confirm] 
</td>
            </tr>
            <tr>
              <td>
New-Module</td>
              <td>
New-Module [-ScriptBlock] &lt;ScriptBlock&gt; [-Function &lt;String[]&gt;] [-Cmdlet
&lt;String[]&gt;] [-ReturnResult] [-AsCustomObject] [-ArgumentList &lt;Object[]&gt;]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] New-Module [-Name] &lt;String&gt; [-ScriptBlock] &lt;ScriptBlock&gt;
[-Function &lt;String[]&gt;] [-Cmdlet &lt;String[]&gt;] [-ReturnResult] [-AsCustomObject]
[-ArgumentList &lt;Object[]&gt;] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Import-Module</td>
              <td>
Import-Module [-Name] &lt;String[]&gt; [-Prefix &lt;String&gt;] [-Function &lt;String[]&gt;]
[-Cmdlet &lt;String[]&gt;] [-Variable &lt;String[]&gt;] [-Alias &lt;String[]&gt;]
[-Force] [-PassThru] [-AsCustomObject] [-Version &lt;Version&gt;] [-ArgumentList &lt;Object[]&gt;]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] Import-Module [-Assembly] &lt;Assembly[]&gt; [-Prefix &lt;String&gt;]
[-Function &lt;String[]&gt;] [-Cmdlet &lt;String[]&gt;] [-Variable &lt;String[]&gt;]
[-Alias &lt;String[]&gt;] [-Force] [-PassThru] [-AsCustomObject] [-Version &lt;Version&gt;]
[-ArgumentList &lt;Object[]&gt;] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] Import-Module
[-ModuleInfo] &lt;PSModuleInfo[]&gt; [-Prefix &lt;String&gt;] [-Function &lt;String[]&gt;]
[-Cmdlet &lt;String[]&gt;] [-Variable &lt;String[]&gt;] [-Alias &lt;String[]&gt;]
[-Force] [-PassThru] [-AsCustomObject] [-Version &lt;Version&gt;] [-ArgumentList &lt;Object[]&gt;]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Test-ModuleManifest</td>
              <td>
Test-ModuleManifest [-Path] &lt;String&gt; [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
New-ModuleManifest</td>
              <td>
New-ModuleManifest [-Path] &lt;String&gt; -NestedModules &lt;String[]&gt; [-Guid &lt;Guid&gt;]
-Author &lt;String&gt; -CompanyName &lt;String&gt; -Copyright &lt;String&gt; [-ModuleToProcess
&lt;String&gt;] [-ModuleVersion &lt;Version&gt;] -Description &lt;String&gt; [-PowerShellVersion
&lt;Version&gt;] [-ClrVersion &lt;Version&gt;] [-RequiredModules &lt;IDictionary[]&gt;]
-TypesToProcess &lt;String[]&gt; -FormatsToProcess &lt;String[]&gt; [-ScriptsToProcess
&lt;String[]&gt;] -RequiredAssemblies &lt;String[]&gt; -OtherFiles &lt;String[]&gt;
[-ExportedFunctions &lt;String[]&gt;] [-ExportedAliases &lt;String[]&gt;] [-ExportedVariables
&lt;String[]&gt;] [-ExportedCmdlets &lt;String[]&gt;] [-PrivateData &lt;Object&gt;]
[-PassThru] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction
&lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;]
[-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] [-WhatIf] [-Confirm] 
</td>
            </tr>
            <tr>
              <td>
Export-ModuleMember</td>
              <td>
Export-ModuleMember [[-Function] &lt;String[]&gt;] [-Cmdlet &lt;String[]&gt;] [-Variable
&lt;String[]&gt;] [-Alias &lt;String[]&gt;] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Register-ObjectEvent</td>
              <td>
Register-ObjectEvent [-InputObject] &lt;PSObject&gt; [-EventName] &lt;String&gt; [[-SourceIdentifier]
&lt;String&gt;] [[-Action] &lt;ScriptBlock&gt;] [-MessageData &lt;PSObject&gt;] [-SupportEvent]
[-Forward] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction
&lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;]
[-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Start-Process</td>
              <td>
Starts one or more processes on the local computer.</td>
            </tr>
            <tr>
              <td>
Debug-Process</td>
              <td>
Debugs one or more processes running on the local computer.</td>
            </tr>
            <tr>
              <td>
Wait-Process</td>
              <td>
Waits for the processes to be stopped before accepting more input.</td>
            </tr>
            <tr>
              <td>
Enable-PSBreakpoint</td>
              <td>
Enables the breakpoints in the current console.</td>
            </tr>
            <tr>
              <td>
Disable-PSBreakpoint</td>
              <td>
Disables the breakpoints in the current console.</td>
            </tr>
            <tr>
              <td>
Remove-PSBreakpoint</td>
              <td>
Deletes breakpoints from the current console.</td>
            </tr>
            <tr>
              <td>
Set-PSBreakpoint</td>
              <td>
Sets a breakpoint on a line, command, or variable.</td>
            </tr>
            <tr>
              <td>
Get-PSBreakpoint</td>
              <td>
Gets the breakpoints that are set in the current console.</td>
            </tr>
            <tr>
              <td>
Get-PSCallStack</td>
              <td>
Displays the current call stack.</td>
            </tr>
            <tr>
              <td>
Remove-PSSession</td>
              <td>
Closes one or more Windows PowerShell sessions (PSSessions).</td>
            </tr>
            <tr>
              <td>
Enter-PSSession</td>
              <td>
Starts an interactive session with a remote computer.</td>
            </tr>
            <tr>
              <td>
Exit-PSSession</td>
              <td>
Ends an interactive session with a remote computer.</td>
            </tr>
            <tr>
              <td>
Get-PSSession</td>
              <td>
Gets the Windows PowerShell sessions (PSSessions) in the current session.</td>
            </tr>
            <tr>
              <td>
Export-PSSession</td>
              <td>
Saves commands from another session in a script module file.</td>
            </tr>
            <tr>
              <td>
Import-PSSession</td>
              <td>
Imports cmdlets, aliases, functions, and other command types from another session
on a local or remote computer into the current session.</td>
            </tr>
            <tr>
              <td>
New-PSSession</td>
              <td>
Creates a persistent connection to a local or remote computer.</td>
            </tr>
            <tr>
              <td>
Set-PSSessionConfiguration</td>
              <td>
Set-PSSessionConfiguration [-Name] &lt;String&gt; [-ApplicationBase &lt;String&gt;]
[-ThreadApartmentState &lt;ApartmentState&gt;] [-ThreadOptions &lt;PSThreadOptions&gt;]
[-StartupScript &lt;String&gt;] [-MaximumReceivedDataSizePerCommandMB &lt;Nullable`1&gt;]
[-MaximumReceivedObjectSizeMB &lt;Nullable`1&gt;] [-SecurityDescriptorSddl &lt;String&gt;]
[-Force] [-NoServiceRestart] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] Set-PSSessionConfiguration
[-Name] &lt;String&gt; [-AssemblyName] &lt;String&gt; [-ConfigurationTypeName] &lt;String&gt;
[-ApplicationBase &lt;String&gt;] [-ThreadApartmentState &lt;ApartmentState&gt;] [-ThreadOptions
&lt;PSThreadOptions&gt;] [-StartupScript &lt;String&gt;] [-MaximumReceivedDataSizePerCommandMB
&lt;Nullable`1&gt;] [-MaximumReceivedObjectSizeMB &lt;Nullable`1&gt;] [-SecurityDescriptorSddl
&lt;String&gt;] [-Force] [-NoServiceRestart] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Enable-PSSessionConfiguration</td>
              <td>
Enable-PSSessionConfiguration [[-Name] &lt;String[]&gt;] [-Force] [-SecurityDescriptorSddl
&lt;String&gt;] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction
&lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;]
[-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Disable-PSSessionConfiguration</td>
              <td>
Disable-PSSessionConfiguration [[-Name] &lt;String[]&gt;] [-Force] [-Verbose] [-Debug]
[-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Register-PSSessionConfiguration</td>
              <td>
Register-PSSessionConfiguration [-Name] &lt;String&gt; [-ProcessorArchitecture &lt;String&gt;]
[-ApplicationBase &lt;String&gt;] [-ThreadApartmentState &lt;ApartmentState&gt;] [-ThreadOptions
&lt;PSThreadOptions&gt;] [-StartupScript &lt;String&gt;] [-MaximumReceivedDataSizePerCommandMB
&lt;Nullable`1&gt;] [-MaximumReceivedObjectSizeMB &lt;Nullable`1&gt;] [-SecurityDescriptorSddl
&lt;String&gt;] [-Force] [-NoServiceRestart] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] Register-PSSessionConfiguration
[-Name] &lt;String&gt; [-AssemblyName] &lt;String&gt; [-ConfigurationTypeName] &lt;String&gt;
[-ProcessorArchitecture &lt;String&gt;] [-ApplicationBase &lt;String&gt;] [-ThreadApartmentState
&lt;ApartmentState&gt;] [-ThreadOptions &lt;PSThreadOptions&gt;] [-StartupScript &lt;String&gt;]
[-MaximumReceivedDataSizePerCommandMB &lt;Nullable`1&gt;] [-MaximumReceivedObjectSizeMB
&lt;Nullable`1&gt;] [-SecurityDescriptorSddl &lt;String&gt;] [-Force] [-NoServiceRestart]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Unregister-PSSessionConfiguration</td>
              <td>
Unregister-PSSessionConfiguration [-Name] &lt;String&gt; [-Force] [-NoServiceRestart]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Get-PSSessionConfiguration</td>
              <td>
Get-PSSessionConfiguration [[-Name] &lt;String[]&gt;] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Get-Random</td>
              <td>
Gets a random number or selects objects randomly from a collection.</td>
            </tr>
            <tr>
              <td>
Set-StrictMode</td>
              <td>
Establishes and enforces coding rules in expressions, scripts, and script blocks.</td>
            </tr>
            <tr>
              <td>
ConvertFrom-StringData</td>
              <td>
Converts a string containing one or more "name=value" pairs to a hash table.</td>
            </tr>
            <tr>
              <td>
Undo-Transaction</td>
              <td>
Rolls back the active transaction.</td>
            </tr>
            <tr>
              <td>
Use-Transaction</td>
              <td>
Adds the script block to the active transaction.</td>
            </tr>
            <tr>
              <td>
Complete-Transaction</td>
              <td>
Commits the active transaction.</td>
            </tr>
            <tr>
              <td>
Get-Transaction</td>
              <td>
Gets the current (active) transaction.</td>
            </tr>
            <tr>
              <td>
Start-Transaction</td>
              <td>
Starts a transaction.</td>
            </tr>
            <tr>
              <td>
Add-Type</td>
              <td>
Adds a .NET type (a class) to a Windows PowerShell session.</td>
            </tr>
            <tr>
              <td>
New-WebServiceProxy</td>
              <td>
Creates a Web service proxy object that lets you use and manage the Web service in
Windows PowerShell.</td>
            </tr>
            <tr>
              <td>
Get-WinEvent</td>
              <td>
Gets events from event logs and event tracing log files on local and remote computers.
This cmdlet runs only on Windows Vista and later versions of Windows.</td>
            </tr>
            <tr>
              <td>
Register-WmiEvent</td>
              <td>
Register-WmiEvent [-Class] &lt;String&gt; [[-SourceIdentifier] &lt;String&gt;] [[-Action]
&lt;ScriptBlock&gt;] [-Namespace &lt;String&gt;] [-Credential &lt;PSCredential&gt;]
[-ComputerName &lt;String&gt;] [-Timeout &lt;Int64&gt;] [-MessageData &lt;PSObject&gt;]
[-SupportEvent] [-Forward] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] Register-WmiEvent
[-Query] &lt;String&gt; [[-SourceIdentifier] &lt;String&gt;] [[-Action] &lt;ScriptBlock&gt;]
[-Namespace &lt;String&gt;] [-Credential &lt;PSCredential&gt;] [-ComputerName &lt;String&gt;]
[-Timeout &lt;Int64&gt;] [-MessageData &lt;PSObject&gt;] [-SupportEvent] [-Forward]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Set-WmiInstance</td>
              <td>
Creates or modifies instances of WMI classes.</td>
            </tr>
            <tr>
              <td>
Invoke-WmiMethod</td>
              <td>
Calls WMI methods.</td>
            </tr>
            <tr>
              <td>
Remove-WmiObject</td>
              <td>
Deletes WMI classes and instances.</td>
            </tr>
            <tr>
              <td>
Disconnect-WSMan</td>
              <td>
Disconnect-WSMan [[-ComputerName] &lt;String&gt;] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Connect-WSMan</td>
              <td>
Connect-WSMan [[-ComputerName] &lt;String&gt;] [-ApplicationName &lt;String&gt;] [-Authentication
&lt;AuthenticationMechanism&gt;] [-Credential &lt;PSCredential&gt;] [-OptionSet &lt;Hashtable&gt;]
[-Port &lt;Int32&gt;] [-SessionOption &lt;SessionOption&gt;] [-UseSSL] [-Verbose]
[-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] Connect-WSMan [-Authentication &lt;AuthenticationMechanism&gt;]
[-ConnectionURI &lt;Uri&gt;] [-Credential &lt;PSCredential&gt;] [-OptionSet &lt;Hashtable&gt;]
[-Port &lt;Int32&gt;] [-SessionOption &lt;SessionOption&gt;] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Test-WSMan</td>
              <td>
Test-WSMan [[-ComputerName] &lt;String&gt;] [-Authentication &lt;AuthenticationMechanism&gt;]
[-Credential &lt;PSCredential&gt;] [-Port &lt;Int32&gt;] [-UseSSL] [-ApplicationName
&lt;String&gt;] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction
&lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;]
[-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Invoke-WSManAction</td>
              <td>
Invoke-WSManAction [-ResourceURI] &lt;Uri&gt; [-Action] &lt;String&gt; [[-SelectorSet]
&lt;Hashtable&gt;] [-Authentication &lt;AuthenticationMechanism&gt;] [-ConnectionURI
&lt;Uri&gt;] [-Credential &lt;PSCredential&gt;] [-FilePath &lt;String&gt;] [-OptionSet
&lt;Hashtable&gt;] [-SessionOption &lt;SessionOption&gt;] [-ValueSet &lt;Hashtable&gt;]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] Invoke-WSManAction [-ResourceURI] &lt;Uri&gt; [-Action]
&lt;String&gt; [[-SelectorSet] &lt;Hashtable&gt;] [-ApplicationName &lt;String&gt;]
[-Authentication &lt;AuthenticationMechanism&gt;] [-ComputerName &lt;String&gt;] [-Credential
&lt;PSCredential&gt;] [-FilePath &lt;String&gt;] [-OptionSet &lt;Hashtable&gt;] [-Port
&lt;Int32&gt;] [-SessionOption &lt;SessionOption&gt;] [-UseSSL] [-ValueSet &lt;Hashtable&gt;]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Get-WSManCredSSP</td>
              <td>
Get-WSManCredSSP [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction
&lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;]
[-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Enable-WSManCredSSP</td>
              <td>
Enable-WSManCredSSP [-DelegateComputer] &lt;String[]&gt; [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Disable-WSManCredSSP</td>
              <td>
Disable-WSManCredSSP [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction
&lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;]
[-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Remove-WSManInstance</td>
              <td>
Remove-WSManInstance [-ResourceURI] &lt;Uri&gt; [-SelectorSet] &lt;Hashtable&gt; [-ApplicationName
&lt;String&gt;] [-Authentication &lt;AuthenticationMechanism&gt;] [-ComputerName &lt;String&gt;]
[-Credential &lt;PSCredential&gt;] [-OptionSet &lt;Hashtable&gt;] [-Port &lt;Int32&gt;]
[-SessionOption &lt;SessionOption&gt;] [-UseSSL] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] Remove-WSManInstance [-ResourceURI] &lt;Uri&gt; [-SelectorSet] &lt;Hashtable&gt;
[-Authentication &lt;AuthenticationMechanism&gt;] [-ConnectionURI &lt;Uri&gt;] [-Credential
&lt;PSCredential&gt;] [-OptionSet &lt;Hashtable&gt;] [-SessionOption &lt;SessionOption&gt;]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
New-WSManInstance</td>
              <td>
New-WSManInstance [-ResourceURI] &lt;Uri&gt; [-SelectorSet] &lt;Hashtable&gt; [-ApplicationName
&lt;String&gt;] [-Authentication &lt;AuthenticationMechanism&gt;] [-ComputerName &lt;String&gt;]
[-Credential &lt;PSCredential&gt;] [-FilePath &lt;String&gt;] [-OptionSet &lt;Hashtable&gt;]
[-Port &lt;Int32&gt;] [-SessionOption &lt;SessionOption&gt;] [-UseSSL] [-ValueSet
&lt;Hashtable&gt;] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction
&lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;]
[-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] New-WSManInstance [-ResourceURI]
&lt;Uri&gt; [-SelectorSet] &lt;Hashtable&gt; [-Authentication &lt;AuthenticationMechanism&gt;]
[-ConnectionURI &lt;Uri&gt;] [-Credential &lt;PSCredential&gt;] [-FilePath &lt;String&gt;]
[-OptionSet &lt;Hashtable&gt;] [-SessionOption &lt;SessionOption&gt;] [-ValueSet &lt;Hashtable&gt;]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Get-WSManInstance</td>
              <td>
Get-WSManInstance [-ResourceURI] &lt;Uri&gt; [-ApplicationName &lt;String&gt;] [-Authentication
&lt;AuthenticationMechanism&gt;] [-ComputerName &lt;String&gt;] [-ConnectionURI &lt;Uri&gt;]
[-Credential &lt;PSCredential&gt;] [-Dialect &lt;Uri&gt;] [-Fragment &lt;String&gt;]
[-OptionSet &lt;Hashtable&gt;] [-Port &lt;Int32&gt;] [-SelectorSet &lt;Hashtable&gt;]
[-SessionOption &lt;SessionOption&gt;] [-UseSSL] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] Get-WSManInstance [-ResourceURI] &lt;Uri&gt; [-ApplicationName &lt;String&gt;]
[-Authentication &lt;AuthenticationMechanism&gt;] [-BasePropertiesOnly] [-ComputerName
&lt;String&gt;] [-ConnectionURI &lt;Uri&gt;] [-Credential &lt;PSCredential&gt;] [-Dialect
&lt;Uri&gt;] -Enumerate [-Filter &lt;String&gt;] [-OptionSet &lt;Hashtable&gt;] [-Port
&lt;Int32&gt;] [-References] [-ReturnType &lt;String&gt;] [-SessionOption &lt;SessionOption&gt;]
[-Shallow] [-UseSSL] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction
&lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;]
[-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Set-WSManInstance</td>
              <td>
Set-WSManInstance [-ResourceURI] &lt;Uri&gt; [[-SelectorSet] &lt;Hashtable&gt;] [-ApplicationName
&lt;String&gt;] [-Authentication &lt;AuthenticationMechanism&gt;] [-ComputerName &lt;String&gt;]
[-Credential &lt;PSCredential&gt;] [-Dialect &lt;Uri&gt;] [-FilePath &lt;String&gt;]
[-Fragment &lt;String&gt;] [-OptionSet &lt;Hashtable&gt;] [-Port &lt;Int32&gt;] [-SessionOption
&lt;SessionOption&gt;] [-UseSSL] [-ValueSet &lt;Hashtable&gt;] [-Verbose] [-Debug]
[-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] Set-WSManInstance [-ResourceURI] &lt;Uri&gt; [[-SelectorSet]
&lt;Hashtable&gt;] [-Authentication &lt;AuthenticationMechanism&gt;] [-ConnectionURI
&lt;Uri&gt;] [-Credential &lt;PSCredential&gt;] [-Dialect &lt;Uri&gt;] [-FilePath
&lt;String&gt;] [-Fragment &lt;String&gt;] [-OptionSet &lt;Hashtable&gt;] [-SessionOption
&lt;SessionOption&gt;] [-ValueSet &lt;Hashtable&gt;] [-Verbose] [-Debug] [-ErrorAction
&lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable
&lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer
&lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Set-WSManQuickConfig</td>
              <td>
Set-WSManQuickConfig [-UseSSL] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
New-WSManSessionOption</td>
              <td>
New-WSManSessionOption [-ProxyAccessType &lt;ProxyAccessType&gt;] [-ProxyAuthentication
&lt;ProxyAuthentication&gt;] [-ProxyCredential &lt;PSCredential&gt;] [-SkipCACheck]
[-SkipCNCheck] [-SkipRevocationCheck] [-SPNPort &lt;Int32&gt;] [-OperationTimeout
&lt;Int32&gt;] [-NoEncryption] [-UseUTF16] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
Select-Xml</td>
              <td>
Select-Xml [-XPath] &lt;String&gt; [-Path] &lt;String[]&gt; [-Namespace &lt;Hashtable&gt;]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] Select-Xml [-XPath] &lt;String&gt; [-Xml] &lt;XmlNode[]&gt;
[-Namespace &lt;Hashtable&gt;] [-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;]
[-WarningAction &lt;ActionPreference&gt;] [-ErrorVariable &lt;String&gt;] [-WarningVariable
&lt;String&gt;] [-OutVariable &lt;String&gt;] [-OutBuffer &lt;Int32&gt;] Select-Xml
[-XPath] &lt;String&gt; [-Content] &lt;String[]&gt; [-Namespace &lt;Hashtable&gt;]
[-Verbose] [-Debug] [-ErrorAction &lt;ActionPreference&gt;] [-WarningAction &lt;ActionPreference&gt;]
[-ErrorVariable &lt;String&gt;] [-WarningVariable &lt;String&gt;] [-OutVariable &lt;String&gt;]
[-OutBuffer &lt;Int32&gt;] 
</td>
            </tr>
            <tr>
              <td>
ConvertTo-Xml</td>
              <td>
Creates an XML-based representation of an object.</td>
            </tr>
          </tbody>
        </table>
        <p>
Whew, that’s quite a few. Now, onto the API.
</p>
        <h4>.NET API Differences
</h4>
        <p>
This time, I’m just dumping out the namespaces and Types per namespace. It would be
a bit much to dump out all the Types themselves. The one-liner:
</p>
        <div id="hlDiv" class="dp-highlighter">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span class="variable">$v1</span>
                <span>.api | group namespace | select name,
count | convertto-html -fragment &gt; .\v1-types.htm  </span>
              </span>
            </li>
          </ol>
        </div>
        <strong>v1.0 RTM API </strong>
        <p>
Here are the namspaces and respective public Type count for v1.0:
</p>
        <table>
          <colgroup>
            <col />
            <col />
          </colgroup>
          <tbody>
            <tr>
              <th>
Name</th>
              <th>
Count</th>
            </tr>
            <tr>
              <td>
Microsoft.PowerShell.Commands</td>
              <td>
196</td>
            </tr>
            <tr>
              <td>
Microsoft.PowerShell</td>
              <td>
11</td>
            </tr>
            <tr>
              <td>
Microsoft.PowerShell.Commands.Internal.Format</td>
              <td>
4</td>
            </tr>
            <tr>
              <td>
System.Management.Automation</td>
              <td>
169</td>
            </tr>
            <tr>
              <td>
System.Management.Automation.Internal</td>
              <td>
6</td>
            </tr>
            <tr>
              <td>
System.Management.Automation.Host</td>
              <td>
15</td>
            </tr>
            <tr>
              <td>
System.Management.Automation.Runspaces</td>
              <td>
33</td>
            </tr>
            <tr>
              <td>
System.Management.Automation.Provider</td>
              <td>
13</td>
            </tr>
          </tbody>
        </table>
        <p>
          <strong>v2.0 CTP3 API </strong>
        </p>
        <p>
Here are the namspaces and respective public Type count for v2.0 CTP3:
</p>
        <table>
          <colgroup>
            <col />
            <col />
          </colgroup>
          <tbody>
            <tr>
              <th>
Name</th>
              <th>
Count</th>
            </tr>
            <tr>
              <td>
Microsoft.PowerShell.Commands</td>
              <td>
311</td>
            </tr>
            <tr>
              <td>
Microsoft.PowerShell.Commands.GetCounter</td>
              <td>
4</td>
            </tr>
            <tr>
              <td>
Microsoft.PowerShell</td>
              <td>
14</td>
            </tr>
            <tr>
              <td>
Microsoft.PowerShell.Commands.Internal.Format</td>
              <td>
4</td>
            </tr>
            <tr>
              <td>
Microsoft.WSMan.Management</td>
              <td>
40</td>
            </tr>
            <tr>
              <td>
System.Management.Automation</td>
              <td>
262</td>
            </tr>
            <tr>
              <td>
System.Management.Automation.Internal</td>
              <td>
7</td>
            </tr>
            <tr>
              <td>
System.Management.Automation.Runspaces</td>
              <td>
61</td>
            </tr>
            <tr>
              <td>
System.Management.Automation.Host</td>
              <td>
17</td>
            </tr>
            <tr>
              <td>
System.Management.Automation.Remoting</td>
              <td>
10</td>
            </tr>
            <tr>
              <td>
System.Management.Automation.Provider</td>
              <td>
14</td>
            </tr>
            <tr>
              <td>
Microsoft.PowerShell.Commands.Internal</td>
              <td>
4</td>
            </tr>
            <tr>
              <td>
Microsoft.PowerShell.Commands.Management</td>
              <td>
1</td>
            </tr>
          </tbody>
        </table>
        <p>
As you can see, there has been a nice expansion of namespaces and Types to work with,
mostly coming from the sterling work being done to generalize the “Jobs” infrastructure.
Also, a fair chunk is tied up with the refactoring and reorganizing of Runspaces to
allow for jobs (which also covers eventing), remoting and background pipelines. This
is something I will cover in more detail in a future post.
</p>
        <p>
Have fun!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=f33b33fb-273a-4c45-9695-cdcc0c768aaf" />
      </body>
      <title>Differences between PowerShell 1.0 RTM and Powershell 2.0 CTP3/Win7 Beta</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,f33b33fb-273a-4c45-9695-cdcc0c768aaf.aspx</guid>
      <link>http://www.nivot.org/2009/02/04/DifferencesBetweenPowerShell10RTMAndPowershell20CTP3Win7Beta.aspx</link>
      <pubDate>Wed, 04 Feb 2009 00:18:14 GMT</pubDate>
      <description>&lt;p&gt;
It’s been quite a few years -- November 14, 2006 to be exact -- since the final release
of &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; 1.0.
Let’s see what the &lt;a href="http://blogs.msdn.com/powershell" target="_blank"&gt;lazy
buggers&lt;/a&gt; have been up to since then. Only kidding, they’re far from lazy; we’ve
gained an extra one hundred and six new cmdlets, moving from 131 to 237. We’ve also
gained another provider, WSManProvider which lets you explore and manipulate the WS-Man
configuration. Finally, the number of public Types (.NET classes usable by 3rd parties
to extend PowerShell) has increased from 447 to 749. So how do I know all this? Well,
some months ago I wrote a suite of build analysis Cmdlets for examining the assemblies
that comprise PowerShell. In its current form it’s of very little use to 3rd parties,
but I’ve had some requests to open it up and allow it to analyze any binary modules
and snap-ins, which is a good idea I think. Watch this space. Anyway, I’m going to
dump out some interest information on the differences between v1.0 and v2.0 CTP3,
along with the one-liners I’m using to generate the information. 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&lt;strong&gt;update feb 5&lt;/strong&gt;: added breaking changes&lt;/em&gt;
&lt;/p&gt;
&lt;h4&gt;&lt;b&gt;Breaking Changes to Windows PowerShell 1.0&lt;/b&gt;&lt;u&gt;&lt;/u&gt;
&lt;/h4&gt;
&lt;p&gt;
&lt;u&gt;&lt;/u&gt; 
&lt;p&gt;
The following changes in Windows PowerShell V2.0 CTP3 might prevent features designed
for Windows PowerShell 1.0 from working correctly.&lt;u&gt;&lt;/u&gt; 
&lt;ul&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;The value of the &lt;b&gt;PowerShellVersion&lt;/b&gt; registry entry in HKLM\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine
has been changed to &lt;b&gt;2.0&lt;/b&gt;.
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="left"&gt;New cmdlets and variables have been added. These are listed below.
These new elements might conflict with variables and functions in profiles and scripts.
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="left"&gt;&lt;b&gt;-&lt;/b&gt;IEQ operator does a case insensitive comparison on characters.
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="left"&gt;Get-Command gets functions along with cmdlets by default. 
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="left"&gt;Any native command that generates a user interface blocks if it
is pipelined to the Out-Host cmdlet.
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="left"&gt;Added new language keywords: &lt;b&gt;Begin&lt;/b&gt;, &lt;strong&gt;Process, &lt;/strong&gt;and&lt;strong&gt; End&lt;/strong&gt;.
Any commands called &lt;b&gt;begin&lt;/b&gt;, &lt;b&gt;process&lt;/b&gt; or &lt;b&gt;end&lt;/b&gt; are interpreted as
language keywords and might result in parsing errors. 
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="left"&gt;Cmdlet name resolution has changed. In Windows PowerShell 1.0, a
runtime error was generated when two Windows PowerShell snap-ins exported cmdlets
with the same name. In Windows PowerShell V2, the last cmdlet loaded is the one that
is executed if the cmdlet name is not qualified by a snap-in name.
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="left"&gt;Terminating errors that are thrown in a pipeline do not terminate
the pipeline. Instead, they are written to the host. 
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="left"&gt;A function called with '-?' parameter gets the help topic for the
function, if one is included in the function. 
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;p&gt;
There are no changes to Cmdlets other than Get-Command’s –PSSnapin parameter is now
an alias to a –Module parameter. This reflects the move away from administrator-installed
snap-ins, and towards the friendlier Module system. For all intents and purposes,
you can treat v1 snapins as modules as load them as such with the Import-Module Cmdlet.
&lt;/p&gt;
&lt;h4&gt;New Cmdlets
&lt;/h4&gt;
&lt;p&gt;
Here are the new Cmdlets, sorted by noun and alongside the textual synopsis is one
is present in the CTP3 help, or the syntax if there is no help. The command I ran
to generate this was:
&lt;/p&gt;
&lt;p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css"&gt;
&lt;!-- Code --&gt;&gt;
&lt;div id="hlDiv" class="dp-highlighter"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span&gt;compare-psbuildinfo (import-psbuildinfo .\rtm-6-0-6000-16386.psbuild)
(import-psbuildinfo .\win7beta1-6-1-7000-0.psbuild) | ? {&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.diff
-eq &lt;/span&gt;&lt;span class="string"&gt;"Added"&lt;/span&gt;&lt;span&gt;} | sort noun | % { &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt; |
add-member -name Synopsis -member noteproperty -value (&amp;amp; &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.name
-?&lt;/span&gt;&lt;span class="variable"&gt;|select&lt;/span&gt;&lt;span&gt; -expand synopsis) -passthru }
| select name,synopsis | convertto-html -fragment &amp;gt; new-cmdlets.htm&amp;nbsp; &lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;style type="text/css"&gt;&lt;!--
#cmdlets tr td { vertical-align: top; border-top: 1px solid gray; text-align: left; }
--&gt;&lt;/style&gt;
&lt;table id="cmdlets"&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;
Name&lt;/th&gt;
&lt;th&gt;
Synopsis&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Invoke-Command&lt;/td&gt;
&lt;td&gt;
Runs commands on local and remote computers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Add-Computer&lt;/td&gt;
&lt;td&gt;
Adds computers to a domain or workgroup.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Remove-Computer&lt;/td&gt;
&lt;td&gt;
Removes computers from workgroups or domains.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Rename-Computer&lt;/td&gt;
&lt;td&gt;
Renames a computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Restore-Computer&lt;/td&gt;
&lt;td&gt;
Starts a system restore on the local computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Checkpoint-Computer&lt;/td&gt;
&lt;td&gt;
Creates a system restore point on the local computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Restart-Computer&lt;/td&gt;
&lt;td&gt;
Restarts ("reboots") the operating system on local and remote computers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Stop-Computer&lt;/td&gt;
&lt;td&gt;
Stops (shuts down) local and remote computers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Reset-ComputerMachinePassword&lt;/td&gt;
&lt;td&gt;
Resets the machine account password for the computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Disable-ComputerRestore&lt;/td&gt;
&lt;td&gt;
Disables the System Restore feature on the specified file system drive.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Enable-ComputerRestore&lt;/td&gt;
&lt;td&gt;
Enables the System Restore feature on the specified file system drive.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-ComputerRestorePoint&lt;/td&gt;
&lt;td&gt;
Gets the restore points on the local computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Test-ComputerSecureChannel&lt;/td&gt;
&lt;td&gt;
Test-ComputerSecureChannel [-Repair] [-Server &amp;lt;String&amp;gt;] [-Verbose] [-Debug]
[-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] [-WhatIf] [-Confirm] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Test-Connection&lt;/td&gt;
&lt;td&gt;
Sends ICMP echo request packets ("pings") to one or more computers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Export-Counter&lt;/td&gt;
&lt;td&gt;
The Export-Counter cmdlet takes PerformanceCounterSampleSet objects and exports them
as counter log files.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Import-Counter&lt;/td&gt;
&lt;td&gt;
Imports performance counter log files (.blg, .csv, .tsv) and creates the objects that
represent each counter sample in the log.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-Counter&lt;/td&gt;
&lt;td&gt;
Gets performance counter data from local and remote computers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
ConvertFrom-Csv&lt;/td&gt;
&lt;td&gt;
Converts object properties in CSV format into CSV versions of the original objects.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
ConvertTo-Csv&lt;/td&gt;
&lt;td&gt;
Converts .NET objects into a series of comma-separated, variable-length (CSV) strings.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Register-EngineEvent&lt;/td&gt;
&lt;td&gt;
Register-EngineEvent [-SourceIdentifier] &amp;lt;String&amp;gt; [[-Action] &amp;lt;ScriptBlock&amp;gt;]
[-MessageData &amp;lt;PSObject&amp;gt;] [-SupportEvent] [-Forward] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Unregister-Event&lt;/td&gt;
&lt;td&gt;
Unregister-Event [-SourceIdentifier] &amp;lt;String&amp;gt; [-Force] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] [-WhatIf] [-Confirm] Unregister-Event [-SubscriptionId] &amp;lt;Int32&amp;gt;
[-Force] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction
&amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;]
[-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] [-WhatIf] [-Confirm] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
New-Event&lt;/td&gt;
&lt;td&gt;
New-Event [-SourceIdentifier] &amp;lt;String&amp;gt; [[-Sender] &amp;lt;PSObject&amp;gt;] [[-EventArguments]
&amp;lt;PSObject[]&amp;gt;] [[-MessageData] &amp;lt;PSObject&amp;gt;] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Remove-Event&lt;/td&gt;
&lt;td&gt;
Remove-Event [-SourceIdentifier] &amp;lt;String&amp;gt; [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] [-WhatIf] [-Confirm] Remove-Event [-EventIdentifier] &amp;lt;Int32&amp;gt;
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] [-WhatIf] [-Confirm] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Wait-Event&lt;/td&gt;
&lt;td&gt;
Wait-Event [[-SourceIdentifier] &amp;lt;String&amp;gt;] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-Event&lt;/td&gt;
&lt;td&gt;
Get-Event [[-SourceIdentifier] &amp;lt;String&amp;gt;] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Show-EventLog&lt;/td&gt;
&lt;td&gt;
Displays the event logs of the local or a remote computer in Event Viewer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
New-EventLog&lt;/td&gt;
&lt;td&gt;
Creates a new event log and a new event source on a local or remote computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Remove-EventLog&lt;/td&gt;
&lt;td&gt;
Deletes an event log or unregisters an event source.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Clear-EventLog&lt;/td&gt;
&lt;td&gt;
Deletes all entries from specified event logs on the local or remote computers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Write-EventLog&lt;/td&gt;
&lt;td&gt;
Writes an event to an event log.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Limit-EventLog&lt;/td&gt;
&lt;td&gt;
Sets the event log properties that limit the size of the event log and the age of
its entries.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-EventSubscriber&lt;/td&gt;
&lt;td&gt;
Get-EventSubscriber [[-SourceIdentifier] &amp;lt;String&amp;gt;] [-Force] [-Verbose] [-Debug]
[-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Export-FormatData&lt;/td&gt;
&lt;td&gt;
Export-FormatData [-InputObject &amp;lt;ExtendedTypeDefinition[]&amp;gt;] [-FilePath &amp;lt;String&amp;gt;]
[-Force] [-NoClobber] [-IncludeScriptBlock] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-FormatData&lt;/td&gt;
&lt;td&gt;
Get-FormatData [[-TypeName] &amp;lt;String[]&amp;gt;] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Out-GridView&lt;/td&gt;
&lt;td&gt;
Sends output to an interactive table in a separate window.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Clear-History&lt;/td&gt;
&lt;td&gt;
Deletes entries from the command history.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-HotFix&lt;/td&gt;
&lt;td&gt;
Gets the QFE updates that have been applied to the local and remote computers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Stop-Job&lt;/td&gt;
&lt;td&gt;
Stops a Windows PowerShell background job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Wait-Job&lt;/td&gt;
&lt;td&gt;
Suppresses the command prompt until one or all of the Windows PowerShell background
jobs running in the session are complete.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Remove-Job&lt;/td&gt;
&lt;td&gt;
Deletes a Windows PowerShell background job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Start-Job&lt;/td&gt;
&lt;td&gt;
Starts a Windows PowerShell background job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-Job&lt;/td&gt;
&lt;td&gt;
Gets Windows PowerShell background jobs that are running in the current session.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Receive-Job&lt;/td&gt;
&lt;td&gt;
Gets the results of the Windows PowerShell background jobs in the current session.
You can use this cmdlet to retrieve the output and errors of background jobs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Update-List&lt;/td&gt;
&lt;td&gt;
Adds and removes items from a property value that contains a collection of objects.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Import-LocalizedData&lt;/td&gt;
&lt;td&gt;
Imports language-specific data into scripts and functions based on the UI culture
that is selected for the operating system.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Send-MailMessage&lt;/td&gt;
&lt;td&gt;
Sends an e-mail message.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-Module&lt;/td&gt;
&lt;td&gt;
Get-Module [[-Name] &amp;lt;String[]&amp;gt;] [-All] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] Get-Module
[[-Name] &amp;lt;String[]&amp;gt;] [-ListAvailable] [-Recurse] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Remove-Module&lt;/td&gt;
&lt;td&gt;
Remove-Module [-Name] &amp;lt;String[]&amp;gt; [-Force] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] [-WhatIf] [-Confirm] Remove-Module [-ModuleInfo] &amp;lt;PSModuleInfo[]&amp;gt;
[-Force] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction
&amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;]
[-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] [-WhatIf] [-Confirm] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
New-Module&lt;/td&gt;
&lt;td&gt;
New-Module [-ScriptBlock] &amp;lt;ScriptBlock&amp;gt; [-Function &amp;lt;String[]&amp;gt;] [-Cmdlet
&amp;lt;String[]&amp;gt;] [-ReturnResult] [-AsCustomObject] [-ArgumentList &amp;lt;Object[]&amp;gt;]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] New-Module [-Name] &amp;lt;String&amp;gt; [-ScriptBlock] &amp;lt;ScriptBlock&amp;gt;
[-Function &amp;lt;String[]&amp;gt;] [-Cmdlet &amp;lt;String[]&amp;gt;] [-ReturnResult] [-AsCustomObject]
[-ArgumentList &amp;lt;Object[]&amp;gt;] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Import-Module&lt;/td&gt;
&lt;td&gt;
Import-Module [-Name] &amp;lt;String[]&amp;gt; [-Prefix &amp;lt;String&amp;gt;] [-Function &amp;lt;String[]&amp;gt;]
[-Cmdlet &amp;lt;String[]&amp;gt;] [-Variable &amp;lt;String[]&amp;gt;] [-Alias &amp;lt;String[]&amp;gt;]
[-Force] [-PassThru] [-AsCustomObject] [-Version &amp;lt;Version&amp;gt;] [-ArgumentList &amp;lt;Object[]&amp;gt;]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] Import-Module [-Assembly] &amp;lt;Assembly[]&amp;gt; [-Prefix &amp;lt;String&amp;gt;]
[-Function &amp;lt;String[]&amp;gt;] [-Cmdlet &amp;lt;String[]&amp;gt;] [-Variable &amp;lt;String[]&amp;gt;]
[-Alias &amp;lt;String[]&amp;gt;] [-Force] [-PassThru] [-AsCustomObject] [-Version &amp;lt;Version&amp;gt;]
[-ArgumentList &amp;lt;Object[]&amp;gt;] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] Import-Module
[-ModuleInfo] &amp;lt;PSModuleInfo[]&amp;gt; [-Prefix &amp;lt;String&amp;gt;] [-Function &amp;lt;String[]&amp;gt;]
[-Cmdlet &amp;lt;String[]&amp;gt;] [-Variable &amp;lt;String[]&amp;gt;] [-Alias &amp;lt;String[]&amp;gt;]
[-Force] [-PassThru] [-AsCustomObject] [-Version &amp;lt;Version&amp;gt;] [-ArgumentList &amp;lt;Object[]&amp;gt;]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Test-ModuleManifest&lt;/td&gt;
&lt;td&gt;
Test-ModuleManifest [-Path] &amp;lt;String&amp;gt; [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
New-ModuleManifest&lt;/td&gt;
&lt;td&gt;
New-ModuleManifest [-Path] &amp;lt;String&amp;gt; -NestedModules &amp;lt;String[]&amp;gt; [-Guid &amp;lt;Guid&amp;gt;]
-Author &amp;lt;String&amp;gt; -CompanyName &amp;lt;String&amp;gt; -Copyright &amp;lt;String&amp;gt; [-ModuleToProcess
&amp;lt;String&amp;gt;] [-ModuleVersion &amp;lt;Version&amp;gt;] -Description &amp;lt;String&amp;gt; [-PowerShellVersion
&amp;lt;Version&amp;gt;] [-ClrVersion &amp;lt;Version&amp;gt;] [-RequiredModules &amp;lt;IDictionary[]&amp;gt;]
-TypesToProcess &amp;lt;String[]&amp;gt; -FormatsToProcess &amp;lt;String[]&amp;gt; [-ScriptsToProcess
&amp;lt;String[]&amp;gt;] -RequiredAssemblies &amp;lt;String[]&amp;gt; -OtherFiles &amp;lt;String[]&amp;gt;
[-ExportedFunctions &amp;lt;String[]&amp;gt;] [-ExportedAliases &amp;lt;String[]&amp;gt;] [-ExportedVariables
&amp;lt;String[]&amp;gt;] [-ExportedCmdlets &amp;lt;String[]&amp;gt;] [-PrivateData &amp;lt;Object&amp;gt;]
[-PassThru] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction
&amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;]
[-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] [-WhatIf] [-Confirm] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Export-ModuleMember&lt;/td&gt;
&lt;td&gt;
Export-ModuleMember [[-Function] &amp;lt;String[]&amp;gt;] [-Cmdlet &amp;lt;String[]&amp;gt;] [-Variable
&amp;lt;String[]&amp;gt;] [-Alias &amp;lt;String[]&amp;gt;] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Register-ObjectEvent&lt;/td&gt;
&lt;td&gt;
Register-ObjectEvent [-InputObject] &amp;lt;PSObject&amp;gt; [-EventName] &amp;lt;String&amp;gt; [[-SourceIdentifier]
&amp;lt;String&amp;gt;] [[-Action] &amp;lt;ScriptBlock&amp;gt;] [-MessageData &amp;lt;PSObject&amp;gt;] [-SupportEvent]
[-Forward] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction
&amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;]
[-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Start-Process&lt;/td&gt;
&lt;td&gt;
Starts one or more processes on the local computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Debug-Process&lt;/td&gt;
&lt;td&gt;
Debugs one or more processes running on the local computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Wait-Process&lt;/td&gt;
&lt;td&gt;
Waits for the processes to be stopped before accepting more input.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Enable-PSBreakpoint&lt;/td&gt;
&lt;td&gt;
Enables the breakpoints in the current console.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Disable-PSBreakpoint&lt;/td&gt;
&lt;td&gt;
Disables the breakpoints in the current console.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Remove-PSBreakpoint&lt;/td&gt;
&lt;td&gt;
Deletes breakpoints from the current console.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Set-PSBreakpoint&lt;/td&gt;
&lt;td&gt;
Sets a breakpoint on a line, command, or variable.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-PSBreakpoint&lt;/td&gt;
&lt;td&gt;
Gets the breakpoints that are set in the current console.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-PSCallStack&lt;/td&gt;
&lt;td&gt;
Displays the current call stack.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Remove-PSSession&lt;/td&gt;
&lt;td&gt;
Closes one or more Windows PowerShell sessions (PSSessions).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Enter-PSSession&lt;/td&gt;
&lt;td&gt;
Starts an interactive session with a remote computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Exit-PSSession&lt;/td&gt;
&lt;td&gt;
Ends an interactive session with a remote computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-PSSession&lt;/td&gt;
&lt;td&gt;
Gets the Windows PowerShell sessions (PSSessions) in the current session.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Export-PSSession&lt;/td&gt;
&lt;td&gt;
Saves commands from another session in a script module file.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Import-PSSession&lt;/td&gt;
&lt;td&gt;
Imports cmdlets, aliases, functions, and other command types from another session
on a local or remote computer into the current session.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
New-PSSession&lt;/td&gt;
&lt;td&gt;
Creates a persistent connection to a local or remote computer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Set-PSSessionConfiguration&lt;/td&gt;
&lt;td&gt;
Set-PSSessionConfiguration [-Name] &amp;lt;String&amp;gt; [-ApplicationBase &amp;lt;String&amp;gt;]
[-ThreadApartmentState &amp;lt;ApartmentState&amp;gt;] [-ThreadOptions &amp;lt;PSThreadOptions&amp;gt;]
[-StartupScript &amp;lt;String&amp;gt;] [-MaximumReceivedDataSizePerCommandMB &amp;lt;Nullable`1&amp;gt;]
[-MaximumReceivedObjectSizeMB &amp;lt;Nullable`1&amp;gt;] [-SecurityDescriptorSddl &amp;lt;String&amp;gt;]
[-Force] [-NoServiceRestart] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] Set-PSSessionConfiguration
[-Name] &amp;lt;String&amp;gt; [-AssemblyName] &amp;lt;String&amp;gt; [-ConfigurationTypeName] &amp;lt;String&amp;gt;
[-ApplicationBase &amp;lt;String&amp;gt;] [-ThreadApartmentState &amp;lt;ApartmentState&amp;gt;] [-ThreadOptions
&amp;lt;PSThreadOptions&amp;gt;] [-StartupScript &amp;lt;String&amp;gt;] [-MaximumReceivedDataSizePerCommandMB
&amp;lt;Nullable`1&amp;gt;] [-MaximumReceivedObjectSizeMB &amp;lt;Nullable`1&amp;gt;] [-SecurityDescriptorSddl
&amp;lt;String&amp;gt;] [-Force] [-NoServiceRestart] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Enable-PSSessionConfiguration&lt;/td&gt;
&lt;td&gt;
Enable-PSSessionConfiguration [[-Name] &amp;lt;String[]&amp;gt;] [-Force] [-SecurityDescriptorSddl
&amp;lt;String&amp;gt;] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction
&amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;]
[-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Disable-PSSessionConfiguration&lt;/td&gt;
&lt;td&gt;
Disable-PSSessionConfiguration [[-Name] &amp;lt;String[]&amp;gt;] [-Force] [-Verbose] [-Debug]
[-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Register-PSSessionConfiguration&lt;/td&gt;
&lt;td&gt;
Register-PSSessionConfiguration [-Name] &amp;lt;String&amp;gt; [-ProcessorArchitecture &amp;lt;String&amp;gt;]
[-ApplicationBase &amp;lt;String&amp;gt;] [-ThreadApartmentState &amp;lt;ApartmentState&amp;gt;] [-ThreadOptions
&amp;lt;PSThreadOptions&amp;gt;] [-StartupScript &amp;lt;String&amp;gt;] [-MaximumReceivedDataSizePerCommandMB
&amp;lt;Nullable`1&amp;gt;] [-MaximumReceivedObjectSizeMB &amp;lt;Nullable`1&amp;gt;] [-SecurityDescriptorSddl
&amp;lt;String&amp;gt;] [-Force] [-NoServiceRestart] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] Register-PSSessionConfiguration
[-Name] &amp;lt;String&amp;gt; [-AssemblyName] &amp;lt;String&amp;gt; [-ConfigurationTypeName] &amp;lt;String&amp;gt;
[-ProcessorArchitecture &amp;lt;String&amp;gt;] [-ApplicationBase &amp;lt;String&amp;gt;] [-ThreadApartmentState
&amp;lt;ApartmentState&amp;gt;] [-ThreadOptions &amp;lt;PSThreadOptions&amp;gt;] [-StartupScript &amp;lt;String&amp;gt;]
[-MaximumReceivedDataSizePerCommandMB &amp;lt;Nullable`1&amp;gt;] [-MaximumReceivedObjectSizeMB
&amp;lt;Nullable`1&amp;gt;] [-SecurityDescriptorSddl &amp;lt;String&amp;gt;] [-Force] [-NoServiceRestart]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Unregister-PSSessionConfiguration&lt;/td&gt;
&lt;td&gt;
Unregister-PSSessionConfiguration [-Name] &amp;lt;String&amp;gt; [-Force] [-NoServiceRestart]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-PSSessionConfiguration&lt;/td&gt;
&lt;td&gt;
Get-PSSessionConfiguration [[-Name] &amp;lt;String[]&amp;gt;] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-Random&lt;/td&gt;
&lt;td&gt;
Gets a random number or selects objects randomly from a collection.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Set-StrictMode&lt;/td&gt;
&lt;td&gt;
Establishes and enforces coding rules in expressions, scripts, and script blocks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
ConvertFrom-StringData&lt;/td&gt;
&lt;td&gt;
Converts a string containing one or more "name=value" pairs to a hash table.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Undo-Transaction&lt;/td&gt;
&lt;td&gt;
Rolls back the active transaction.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Use-Transaction&lt;/td&gt;
&lt;td&gt;
Adds the script block to the active transaction.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Complete-Transaction&lt;/td&gt;
&lt;td&gt;
Commits the active transaction.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-Transaction&lt;/td&gt;
&lt;td&gt;
Gets the current (active) transaction.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Start-Transaction&lt;/td&gt;
&lt;td&gt;
Starts a transaction.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Add-Type&lt;/td&gt;
&lt;td&gt;
Adds a .NET type (a class) to a Windows PowerShell session.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
New-WebServiceProxy&lt;/td&gt;
&lt;td&gt;
Creates a Web service proxy object that lets you use and manage the Web service in
Windows PowerShell.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-WinEvent&lt;/td&gt;
&lt;td&gt;
Gets events from event logs and event tracing log files on local and remote computers.
This cmdlet runs only on Windows Vista and later versions of Windows.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Register-WmiEvent&lt;/td&gt;
&lt;td&gt;
Register-WmiEvent [-Class] &amp;lt;String&amp;gt; [[-SourceIdentifier] &amp;lt;String&amp;gt;] [[-Action]
&amp;lt;ScriptBlock&amp;gt;] [-Namespace &amp;lt;String&amp;gt;] [-Credential &amp;lt;PSCredential&amp;gt;]
[-ComputerName &amp;lt;String&amp;gt;] [-Timeout &amp;lt;Int64&amp;gt;] [-MessageData &amp;lt;PSObject&amp;gt;]
[-SupportEvent] [-Forward] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] Register-WmiEvent
[-Query] &amp;lt;String&amp;gt; [[-SourceIdentifier] &amp;lt;String&amp;gt;] [[-Action] &amp;lt;ScriptBlock&amp;gt;]
[-Namespace &amp;lt;String&amp;gt;] [-Credential &amp;lt;PSCredential&amp;gt;] [-ComputerName &amp;lt;String&amp;gt;]
[-Timeout &amp;lt;Int64&amp;gt;] [-MessageData &amp;lt;PSObject&amp;gt;] [-SupportEvent] [-Forward]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Set-WmiInstance&lt;/td&gt;
&lt;td&gt;
Creates or modifies instances of WMI classes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Invoke-WmiMethod&lt;/td&gt;
&lt;td&gt;
Calls WMI methods.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Remove-WmiObject&lt;/td&gt;
&lt;td&gt;
Deletes WMI classes and instances.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Disconnect-WSMan&lt;/td&gt;
&lt;td&gt;
Disconnect-WSMan [[-ComputerName] &amp;lt;String&amp;gt;] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Connect-WSMan&lt;/td&gt;
&lt;td&gt;
Connect-WSMan [[-ComputerName] &amp;lt;String&amp;gt;] [-ApplicationName &amp;lt;String&amp;gt;] [-Authentication
&amp;lt;AuthenticationMechanism&amp;gt;] [-Credential &amp;lt;PSCredential&amp;gt;] [-OptionSet &amp;lt;Hashtable&amp;gt;]
[-Port &amp;lt;Int32&amp;gt;] [-SessionOption &amp;lt;SessionOption&amp;gt;] [-UseSSL] [-Verbose]
[-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] Connect-WSMan [-Authentication &amp;lt;AuthenticationMechanism&amp;gt;]
[-ConnectionURI &amp;lt;Uri&amp;gt;] [-Credential &amp;lt;PSCredential&amp;gt;] [-OptionSet &amp;lt;Hashtable&amp;gt;]
[-Port &amp;lt;Int32&amp;gt;] [-SessionOption &amp;lt;SessionOption&amp;gt;] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Test-WSMan&lt;/td&gt;
&lt;td&gt;
Test-WSMan [[-ComputerName] &amp;lt;String&amp;gt;] [-Authentication &amp;lt;AuthenticationMechanism&amp;gt;]
[-Credential &amp;lt;PSCredential&amp;gt;] [-Port &amp;lt;Int32&amp;gt;] [-UseSSL] [-ApplicationName
&amp;lt;String&amp;gt;] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction
&amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;]
[-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Invoke-WSManAction&lt;/td&gt;
&lt;td&gt;
Invoke-WSManAction [-ResourceURI] &amp;lt;Uri&amp;gt; [-Action] &amp;lt;String&amp;gt; [[-SelectorSet]
&amp;lt;Hashtable&amp;gt;] [-Authentication &amp;lt;AuthenticationMechanism&amp;gt;] [-ConnectionURI
&amp;lt;Uri&amp;gt;] [-Credential &amp;lt;PSCredential&amp;gt;] [-FilePath &amp;lt;String&amp;gt;] [-OptionSet
&amp;lt;Hashtable&amp;gt;] [-SessionOption &amp;lt;SessionOption&amp;gt;] [-ValueSet &amp;lt;Hashtable&amp;gt;]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] Invoke-WSManAction [-ResourceURI] &amp;lt;Uri&amp;gt; [-Action]
&amp;lt;String&amp;gt; [[-SelectorSet] &amp;lt;Hashtable&amp;gt;] [-ApplicationName &amp;lt;String&amp;gt;]
[-Authentication &amp;lt;AuthenticationMechanism&amp;gt;] [-ComputerName &amp;lt;String&amp;gt;] [-Credential
&amp;lt;PSCredential&amp;gt;] [-FilePath &amp;lt;String&amp;gt;] [-OptionSet &amp;lt;Hashtable&amp;gt;] [-Port
&amp;lt;Int32&amp;gt;] [-SessionOption &amp;lt;SessionOption&amp;gt;] [-UseSSL] [-ValueSet &amp;lt;Hashtable&amp;gt;]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-WSManCredSSP&lt;/td&gt;
&lt;td&gt;
Get-WSManCredSSP [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction
&amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;]
[-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Enable-WSManCredSSP&lt;/td&gt;
&lt;td&gt;
Enable-WSManCredSSP [-DelegateComputer] &amp;lt;String[]&amp;gt; [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Disable-WSManCredSSP&lt;/td&gt;
&lt;td&gt;
Disable-WSManCredSSP [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction
&amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;]
[-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Remove-WSManInstance&lt;/td&gt;
&lt;td&gt;
Remove-WSManInstance [-ResourceURI] &amp;lt;Uri&amp;gt; [-SelectorSet] &amp;lt;Hashtable&amp;gt; [-ApplicationName
&amp;lt;String&amp;gt;] [-Authentication &amp;lt;AuthenticationMechanism&amp;gt;] [-ComputerName &amp;lt;String&amp;gt;]
[-Credential &amp;lt;PSCredential&amp;gt;] [-OptionSet &amp;lt;Hashtable&amp;gt;] [-Port &amp;lt;Int32&amp;gt;]
[-SessionOption &amp;lt;SessionOption&amp;gt;] [-UseSSL] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] Remove-WSManInstance [-ResourceURI] &amp;lt;Uri&amp;gt; [-SelectorSet] &amp;lt;Hashtable&amp;gt;
[-Authentication &amp;lt;AuthenticationMechanism&amp;gt;] [-ConnectionURI &amp;lt;Uri&amp;gt;] [-Credential
&amp;lt;PSCredential&amp;gt;] [-OptionSet &amp;lt;Hashtable&amp;gt;] [-SessionOption &amp;lt;SessionOption&amp;gt;]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
New-WSManInstance&lt;/td&gt;
&lt;td&gt;
New-WSManInstance [-ResourceURI] &amp;lt;Uri&amp;gt; [-SelectorSet] &amp;lt;Hashtable&amp;gt; [-ApplicationName
&amp;lt;String&amp;gt;] [-Authentication &amp;lt;AuthenticationMechanism&amp;gt;] [-ComputerName &amp;lt;String&amp;gt;]
[-Credential &amp;lt;PSCredential&amp;gt;] [-FilePath &amp;lt;String&amp;gt;] [-OptionSet &amp;lt;Hashtable&amp;gt;]
[-Port &amp;lt;Int32&amp;gt;] [-SessionOption &amp;lt;SessionOption&amp;gt;] [-UseSSL] [-ValueSet
&amp;lt;Hashtable&amp;gt;] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction
&amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;]
[-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] New-WSManInstance [-ResourceURI]
&amp;lt;Uri&amp;gt; [-SelectorSet] &amp;lt;Hashtable&amp;gt; [-Authentication &amp;lt;AuthenticationMechanism&amp;gt;]
[-ConnectionURI &amp;lt;Uri&amp;gt;] [-Credential &amp;lt;PSCredential&amp;gt;] [-FilePath &amp;lt;String&amp;gt;]
[-OptionSet &amp;lt;Hashtable&amp;gt;] [-SessionOption &amp;lt;SessionOption&amp;gt;] [-ValueSet &amp;lt;Hashtable&amp;gt;]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Get-WSManInstance&lt;/td&gt;
&lt;td&gt;
Get-WSManInstance [-ResourceURI] &amp;lt;Uri&amp;gt; [-ApplicationName &amp;lt;String&amp;gt;] [-Authentication
&amp;lt;AuthenticationMechanism&amp;gt;] [-ComputerName &amp;lt;String&amp;gt;] [-ConnectionURI &amp;lt;Uri&amp;gt;]
[-Credential &amp;lt;PSCredential&amp;gt;] [-Dialect &amp;lt;Uri&amp;gt;] [-Fragment &amp;lt;String&amp;gt;]
[-OptionSet &amp;lt;Hashtable&amp;gt;] [-Port &amp;lt;Int32&amp;gt;] [-SelectorSet &amp;lt;Hashtable&amp;gt;]
[-SessionOption &amp;lt;SessionOption&amp;gt;] [-UseSSL] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] Get-WSManInstance [-ResourceURI] &amp;lt;Uri&amp;gt; [-ApplicationName &amp;lt;String&amp;gt;]
[-Authentication &amp;lt;AuthenticationMechanism&amp;gt;] [-BasePropertiesOnly] [-ComputerName
&amp;lt;String&amp;gt;] [-ConnectionURI &amp;lt;Uri&amp;gt;] [-Credential &amp;lt;PSCredential&amp;gt;] [-Dialect
&amp;lt;Uri&amp;gt;] -Enumerate [-Filter &amp;lt;String&amp;gt;] [-OptionSet &amp;lt;Hashtable&amp;gt;] [-Port
&amp;lt;Int32&amp;gt;] [-References] [-ReturnType &amp;lt;String&amp;gt;] [-SessionOption &amp;lt;SessionOption&amp;gt;]
[-Shallow] [-UseSSL] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction
&amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;]
[-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Set-WSManInstance&lt;/td&gt;
&lt;td&gt;
Set-WSManInstance [-ResourceURI] &amp;lt;Uri&amp;gt; [[-SelectorSet] &amp;lt;Hashtable&amp;gt;] [-ApplicationName
&amp;lt;String&amp;gt;] [-Authentication &amp;lt;AuthenticationMechanism&amp;gt;] [-ComputerName &amp;lt;String&amp;gt;]
[-Credential &amp;lt;PSCredential&amp;gt;] [-Dialect &amp;lt;Uri&amp;gt;] [-FilePath &amp;lt;String&amp;gt;]
[-Fragment &amp;lt;String&amp;gt;] [-OptionSet &amp;lt;Hashtable&amp;gt;] [-Port &amp;lt;Int32&amp;gt;] [-SessionOption
&amp;lt;SessionOption&amp;gt;] [-UseSSL] [-ValueSet &amp;lt;Hashtable&amp;gt;] [-Verbose] [-Debug]
[-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] Set-WSManInstance [-ResourceURI] &amp;lt;Uri&amp;gt; [[-SelectorSet]
&amp;lt;Hashtable&amp;gt;] [-Authentication &amp;lt;AuthenticationMechanism&amp;gt;] [-ConnectionURI
&amp;lt;Uri&amp;gt;] [-Credential &amp;lt;PSCredential&amp;gt;] [-Dialect &amp;lt;Uri&amp;gt;] [-FilePath
&amp;lt;String&amp;gt;] [-Fragment &amp;lt;String&amp;gt;] [-OptionSet &amp;lt;Hashtable&amp;gt;] [-SessionOption
&amp;lt;SessionOption&amp;gt;] [-ValueSet &amp;lt;Hashtable&amp;gt;] [-Verbose] [-Debug] [-ErrorAction
&amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable
&amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer
&amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Set-WSManQuickConfig&lt;/td&gt;
&lt;td&gt;
Set-WSManQuickConfig [-UseSSL] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
New-WSManSessionOption&lt;/td&gt;
&lt;td&gt;
New-WSManSessionOption [-ProxyAccessType &amp;lt;ProxyAccessType&amp;gt;] [-ProxyAuthentication
&amp;lt;ProxyAuthentication&amp;gt;] [-ProxyCredential &amp;lt;PSCredential&amp;gt;] [-SkipCACheck]
[-SkipCNCheck] [-SkipRevocationCheck] [-SPNPort &amp;lt;Int32&amp;gt;] [-OperationTimeout
&amp;lt;Int32&amp;gt;] [-NoEncryption] [-UseUTF16] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Select-Xml&lt;/td&gt;
&lt;td&gt;
Select-Xml [-XPath] &amp;lt;String&amp;gt; [-Path] &amp;lt;String[]&amp;gt; [-Namespace &amp;lt;Hashtable&amp;gt;]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] Select-Xml [-XPath] &amp;lt;String&amp;gt; [-Xml] &amp;lt;XmlNode[]&amp;gt;
[-Namespace &amp;lt;Hashtable&amp;gt;] [-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;]
[-WarningAction &amp;lt;ActionPreference&amp;gt;] [-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable
&amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;] [-OutBuffer &amp;lt;Int32&amp;gt;] Select-Xml
[-XPath] &amp;lt;String&amp;gt; [-Content] &amp;lt;String[]&amp;gt; [-Namespace &amp;lt;Hashtable&amp;gt;]
[-Verbose] [-Debug] [-ErrorAction &amp;lt;ActionPreference&amp;gt;] [-WarningAction &amp;lt;ActionPreference&amp;gt;]
[-ErrorVariable &amp;lt;String&amp;gt;] [-WarningVariable &amp;lt;String&amp;gt;] [-OutVariable &amp;lt;String&amp;gt;]
[-OutBuffer &amp;lt;Int32&amp;gt;] 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
ConvertTo-Xml&lt;/td&gt;
&lt;td&gt;
Creates an XML-based representation of an object.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
Whew, that’s quite a few. Now, onto the API.
&lt;/p&gt;
&lt;h4&gt;.NET API Differences
&lt;/h4&gt;
&lt;p&gt;
This time, I’m just dumping out the namespaces and Types per namespace. It would be
a bit much to dump out all the Types themselves. The one-liner:
&lt;/p&gt;
&lt;div id="hlDiv" class="dp-highlighter"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="variable"&gt;$v1&lt;/span&gt;&lt;span&gt;.api | group namespace | select name,
count | convertto-html -fragment &amp;gt; .\v1-types.htm&amp;nbsp; &lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;strong&gt;v1.0 RTM API &lt;/strong&gt; 
&lt;p&gt;
Here are the namspaces and respective public Type count for v1.0:
&lt;/p&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;
Name&lt;/th&gt;
&lt;th&gt;
Count&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Microsoft.PowerShell.Commands&lt;/td&gt;
&lt;td&gt;
196&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Microsoft.PowerShell&lt;/td&gt;
&lt;td&gt;
11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Microsoft.PowerShell.Commands.Internal.Format&lt;/td&gt;
&lt;td&gt;
4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation&lt;/td&gt;
&lt;td&gt;
169&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation.Internal&lt;/td&gt;
&lt;td&gt;
6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation.Host&lt;/td&gt;
&lt;td&gt;
15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation.Runspaces&lt;/td&gt;
&lt;td&gt;
33&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation.Provider&lt;/td&gt;
&lt;td&gt;
13&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
&lt;strong&gt;v2.0 CTP3 API &lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Here are the namspaces and respective public Type count for v2.0 CTP3:
&lt;/p&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;
Name&lt;/th&gt;
&lt;th&gt;
Count&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Microsoft.PowerShell.Commands&lt;/td&gt;
&lt;td&gt;
311&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Microsoft.PowerShell.Commands.GetCounter&lt;/td&gt;
&lt;td&gt;
4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Microsoft.PowerShell&lt;/td&gt;
&lt;td&gt;
14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Microsoft.PowerShell.Commands.Internal.Format&lt;/td&gt;
&lt;td&gt;
4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Microsoft.WSMan.Management&lt;/td&gt;
&lt;td&gt;
40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation&lt;/td&gt;
&lt;td&gt;
262&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation.Internal&lt;/td&gt;
&lt;td&gt;
7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation.Runspaces&lt;/td&gt;
&lt;td&gt;
61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation.Host&lt;/td&gt;
&lt;td&gt;
17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation.Remoting&lt;/td&gt;
&lt;td&gt;
10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
System.Management.Automation.Provider&lt;/td&gt;
&lt;td&gt;
14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Microsoft.PowerShell.Commands.Internal&lt;/td&gt;
&lt;td&gt;
4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Microsoft.PowerShell.Commands.Management&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
As you can see, there has been a nice expansion of namespaces and Types to work with,
mostly coming from the sterling work being done to generalize the “Jobs” infrastructure.
Also, a fair chunk is tied up with the refactoring and reorganizing of Runspaces to
allow for jobs (which also covers eventing), remoting and background pipelines. This
is something I will cover in more detail in a future post.
&lt;/p&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=f33b33fb-273a-4c45-9695-cdcc0c768aaf" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,f33b33fb-273a-4c45-9695-cdcc0c768aaf.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>CTP3</category>
      <category>Modules</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=846a72ce-4e85-49b5-bfb6-09e2080db40b</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,846a72ce-4e85-49b5-bfb6-09e2080db40b.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,846a72ce-4e85-49b5-bfb6-09e2080db40b.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=846a72ce-4e85-49b5-bfb6-09e2080db40b</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <!-- Stylesheet link -->
        <link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet" />
        <p>
You might have noticed these two accelerators in the list I published recently along
with the technique how to add your own type accelerators. It’s not immediately clear
that they are related, but they very much are. This is going to be a fairly developer-oriented
post, so there won’t be any hand-holding here. 
</p>
        <h4>[PowerShell]
</h4>
        <p>
The [PowerShell] accelerator is aliased to System.Management.Automation.PowerShell.
It has one static method, Create(), which returns an instance of the class itself.
In v1, if you wanted to set up asynchronous pipelines and do other fancy stuff, you
had to get your hands dirty with Runspace and Pipeline instances and know how to wire
them all together. The [PowerShell] class makes it a lot easier to do this; think
of it a “PowerShell Pipeline Runner” class. At its simplest, you can just “new up”
an instance, assign some script using the AddScript method and call Invoke(). You
can run this asynchronously using the BeginInvoke/EndInvoke pattern which should be
familiar to all .NET developers who’ve done a bit of threading work. 
</p>
        <p>
          <!-- Code -->
        </p>
        <div class="dp-highlighter" id="hlDiv">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span class="comment"># create a new pipeline </span>
                <span>  </span>
              </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$ps</span>
              <span> = [powershell]:</span>
              <span class="symbol">:create</span>
              <span>()   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># add a command (returns Command object) </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>[void] </span>
              <span class="variable">$ps</span>
              <span>.AddScript(</span>
              <span class="string">"ls"</span>
              <span>)   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># invoke synchronously, returning results of "ls." </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$results</span>
              <span> = </span>
              <span class="variable">$ps</span>
              <span>.Invoke()   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># clean up </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$ps</span>
              <span>.dispose()  </span>
            </li>
          </ol>
        </div>
        <p>
        </p>
        <h4>[RunspaceFactory]
</h4>
        <p>
This accelerator is aliased to System.Management.Automation.Runspaces.RunspaceFactory.
It has two static methods of interest, CreateRunspace and CreateRunspacePool. I’m
going to focus on the latter because it has more interesting uses which you will see.
This latter method lets you create a collection of Runspace instances that are essentially
reusable. The great thing is that you don’t have to worry about any of the details.
It just works; this leads me to the next part: queuing local pipeline jobs to be run
in the background. 
</p>
        <p>
The pool you create can be constrained in many ways by using the various overloads
of the CreateRunspacePool. You can even pass it a RunspaceConnectionInfo object so
that the queued pipelines are run on remote servers. This is done by using the New-PSSession
cmdlet to create a session to a remote machine running PowerShell 2.0 with WinRM configured
correctly.
</p>
        <h4>Queueing Pipelines to a Runspace Pool
</h4>
        <p>
This is where the magic really happens. Simply new up a PowerShell instance, assign
the pool to it and run a command. New up as many PowerShell instnaces as you like,
and as long as you assign each of them the same pool, the pool automagically looks
after processing them as fast as it can and will never go over its hard limits you
give it for the number of simultaneous runspaces. In this next script, I set up a
pool of three runspaces. I then queue up six pipelines to be run. I am using the BeginInvoke
method to start the command in the background. You’ll see when it runs that each command
will make a beep of a certain frequency when it finally starts up. You can hear the
first three jobs start up pretty much straight away, as each completes, another starts
up. Magic!
</p>
        <p>
        </p>
        <div class="dp-highlighter" id="hlDiv">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span class="comment">#require -version 2.0 </span>
                <span>  </span>
              </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># create a pool of 3 runspaces </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$pool</span>
              <span> = [runspacefactory]::CreateRunspacePool(1,
3)   </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$pool</span>
              <span>.Open()   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>write-host </span>
              <span class="string">"Available Runspaces: $($pool.GetAvailableRunspaces())"</span>
              <span>  </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$jobs</span>
              <span> = @()   </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$ps</span>
              <span> = @()   </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$wait</span>
              <span> = @()   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># run 6 background pipelines </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="keyword">for</span>
              <span> (</span>
              <span class="variable">$i</span>
              <span> =
0; </span>
              <span class="variable">$i</span>
              <span> -lt 6; </span>
              <span class="variable">$i</span>
              <span>++)
{   </span>
            </li>
            <li class="alt">
              <span>      </span>
            </li>
            <li class="">
              <span>   </span>
              <span class="comment"># create a "powershell pipeline runner" </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>   </span>
              <span class="variable">$ps</span>
              <span> += [powershell]:</span>
              <span class="symbol">:create</span>
              <span>()   </span>
            </li>
            <li class="">
              <span>      </span>
            </li>
            <li class="alt">
              <span>   </span>
              <span class="comment"># assign our pool of 3 runspaces to
use </span>
              <span>  </span>
            </li>
            <li class="">
              <span>   </span>
              <span class="variable">$ps</span>
              <span>[</span>
              <span class="variable">$i</span>
              <span>].runspacepool
= </span>
              <span class="variable">$pool</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>      </span>
            </li>
            <li class="">
              <span>   </span>
              <span class="variable">$freq</span>
              <span> = 440 + (</span>
              <span class="variable">$i</span>
              <span> *
10)   </span>
            </li>
            <li class="alt">
              <span>   </span>
              <span class="variable">$sleep</span>
              <span> = (1 * (</span>
              <span class="variable">$i</span>
              <span> +
1))   </span>
            </li>
            <li class="">
              <span>      </span>
            </li>
            <li class="alt">
              <span>   </span>
              <span class="comment"># test command: beep and wait a certain
time </span>
              <span>  </span>
            </li>
            <li class="">
              <span>   [void]</span>
              <span class="variable">$ps</span>
              <span>[</span>
              <span class="variable">$i</span>
              <span>].AddScript(   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="string">"[console]::Beep($freq,
30); sleep -seconds $sleep"</span>
              <span>)   </span>
            </li>
            <li class="">
              <span>      </span>
            </li>
            <li class="alt">
              <span>   </span>
              <span class="comment"># start job </span>
              <span>  </span>
            </li>
            <li class="">
              <span>   write-host </span>
              <span class="string">"Job $i will run for $sleep
second(s)"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>   </span>
              <span class="variable">$jobs</span>
              <span> += </span>
              <span class="variable">$ps</span>
              <span>[</span>
              <span class="variable">$i</span>
              <span>].BeginInvoke();   </span>
            </li>
            <li class="">
              <span>      </span>
            </li>
            <li class="alt">
              <span>   write-host </span>
              <span class="string">"Available runspaces: $($pool.GetAvailableRunspaces())"</span>
              <span>  </span>
            </li>
            <li class="">
              <span>      </span>
            </li>
            <li class="alt">
              <span>   </span>
              <span class="comment"># store wait handles for WaitForAll
call </span>
              <span>  </span>
            </li>
            <li class="">
              <span>   </span>
              <span class="variable">$wait</span>
              <span> += </span>
              <span class="variable">$jobs</span>
              <span>[</span>
              <span class="variable">$i</span>
              <span>].AsyncWaitHandle   </span>
            </li>
            <li class="alt">
              <span>}   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># wait 20 seconds for all jobs to complete, else
abort </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$success</span>
              <span> = [System.Threading.WaitHandle]::WaitAll(</span>
              <span class="variable">$wait</span>
              <span>,
20000)   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>write-host </span>
              <span class="string">"All completed? $success"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># end async call </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="keyword">for</span>
              <span> (</span>
              <span class="variable">$i</span>
              <span> =
0; </span>
              <span class="variable">$i</span>
              <span> -lt 6; </span>
              <span class="variable">$i</span>
              <span>++)
{   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    write-host </span>
              <span class="string">"Completing async
pipeline job $i"</span>
              <span>  </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    try {   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="comment"># complete
async job </span>
              <span>  </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="variable">$ps</span>
              <span>[</span>
              <span class="variable">$i</span>
              <span>].EndInvoke(</span>
              <span class="variable">$jobs</span>
              <span>[</span>
              <span class="variable">$i</span>
              <span>])   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    } catch {   </span>
            </li>
            <li class="alt">
              <span>       </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="comment"># oops-ee! </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>        write-warning </span>
              <span class="string">"error:
$_"</span>
              <span>  </span>
            </li>
            <li class="">
              <span>    }   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="comment"># dump info about completed
pipelines </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$info</span>
              <span> = </span>
              <span class="variable">$ps</span>
              <span>[</span>
              <span class="variable">$i</span>
              <span>].InvocationStateInfo   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    write-host </span>
              <span class="string">"State: $($info.state)
; Reason: $($info.reason)"</span>
              <span>  </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># should show 3 again. </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>write-host </span>
              <span class="string">"Available runspaces: $($pool.GetAvailableRunspaces())"</span>
              <span>  </span>
            </li>
          </ol>
        </div>
        <p>
        </p>
        <p>
Feel free to post questions or requests for clarification, but I did say it was a
bit tough and developer-oriented. I have a hint that our good friend and fellow MVP, <a href="http://karlprosser.com/coder/" target="_blank">Karl
Prosser</a> (aka Klumsy), will be wrapping up some of this stuff into some nice admin-oriented
background  command functions. 
</p>
        <p>
          <strong>IMPORTANT:</strong>
        </p>
        <p>
          <em>Due to the WaitAll call at line 40, this script will <strong>not</strong> work
in an STA thread (i.e. in PowerShell ISE). Use PowerShell.EXE to run this script.
Everything else will work in ISE fine.</em>
        </p>
        <p>
Have fun!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=846a72ce-4e85-49b5-bfb6-09e2080db40b" />
      </body>
      <title>CTP3: The [RunspaceFactory] and [PowerShell] Accelerators</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,846a72ce-4e85-49b5-bfb6-09e2080db40b.aspx</guid>
      <link>http://www.nivot.org/2009/01/22/CTP3TheRunspaceFactoryAndPowerShellAccelerators.aspx</link>
      <pubDate>Thu, 22 Jan 2009 19:38:03 GMT</pubDate>
      <description>&lt;!-- Stylesheet link --&gt;
&lt;link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet"&gt;
&lt;p&gt;
You might have noticed these two accelerators in the list I published recently along
with the technique how to add your own type accelerators. It’s not immediately clear
that they are related, but they very much are. This is going to be a fairly developer-oriented
post, so there won’t be any hand-holding here. 
&lt;/p&gt;
&lt;h4&gt;[PowerShell]
&lt;/h4&gt;
&lt;p&gt;
The [PowerShell] accelerator is aliased to System.Management.Automation.PowerShell.
It has one static method, Create(), which returns an instance of the class itself.
In v1, if you wanted to set up asynchronous pipelines and do other fancy stuff, you
had to get your hands dirty with Runspace and Pipeline instances and know how to wire
them all together. The [PowerShell] class makes it a lot easier to do this; think
of it a “PowerShell Pipeline Runner” class. At its simplest, you can just “new up”
an instance, assign some script using the AddScript method and call Invoke(). You
can run this asynchronously using the BeginInvoke/EndInvoke pattern which should be
familiar to all .NET developers who’ve done a bit of threading work. 
&lt;/p&gt;
&lt;p&gt;
&lt;!-- Code --&gt;
&lt;/p&gt;
&lt;div class="dp-highlighter" id="hlDiv"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="comment"&gt;# create a new pipeline &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt; = [powershell]:&lt;/span&gt;&lt;span class="symbol"&gt;:create&lt;/span&gt;&lt;span&gt;()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# add a command (returns Command object) &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;[void] &lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt;.AddScript(&lt;/span&gt;&lt;span class="string"&gt;"ls"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# invoke synchronously, returning results of "ls." &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$results&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt;.Invoke()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# clean up &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt;.dispose()&amp;nbsp; &lt;/span&gt;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h4&gt;[RunspaceFactory]
&lt;/h4&gt;
&lt;p&gt;
This accelerator is aliased to System.Management.Automation.Runspaces.RunspaceFactory.
It has two static methods of interest, CreateRunspace and CreateRunspacePool. I’m
going to focus on the latter because it has more interesting uses which you will see.
This latter method lets you create a collection of Runspace instances that are essentially
reusable. The great thing is that you don’t have to worry about any of the details.
It just works; this leads me to the next part: queuing local pipeline jobs to be run
in the background. 
&lt;/p&gt;
&lt;p&gt;
The pool you create can be constrained in many ways by using the various overloads
of the CreateRunspacePool. You can even pass it a RunspaceConnectionInfo object so
that the queued pipelines are run on remote servers. This is done by using the New-PSSession
cmdlet to create a session to a remote machine running PowerShell 2.0 with WinRM configured
correctly.
&lt;/p&gt;
&lt;h4&gt;Queueing Pipelines to a Runspace Pool
&lt;/h4&gt;
&lt;p&gt;
This is where the magic really happens. Simply new up a PowerShell instance, assign
the pool to it and run a command. New up as many PowerShell instnaces as you like,
and as long as you assign each of them the same pool, the pool automagically looks
after processing them as fast as it can and will never go over its hard limits you
give it for the number of simultaneous runspaces. In this next script, I set up a
pool of three runspaces. I then queue up six pipelines to be run. I am using the BeginInvoke
method to start the command in the background. You’ll see when it runs that each command
will make a beep of a certain frequency when it finally starts up. You can hear the
first three jobs start up pretty much straight away, as each completes, another starts
up. Magic!
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="dp-highlighter" id="hlDiv"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="comment"&gt;#require -version 2.0 &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# create a pool of 3 runspaces &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$pool&lt;/span&gt;&lt;span&gt; = [runspacefactory]::CreateRunspacePool(1,
3)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$pool&lt;/span&gt;&lt;span&gt;.Open()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;write-host &lt;/span&gt;&lt;span class="string"&gt;"Available Runspaces: $($pool.GetAvailableRunspaces())"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$jobs&lt;/span&gt;&lt;span&gt; = @()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt; = @()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$wait&lt;/span&gt;&lt;span&gt; = @()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# run 6 background pipelines &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt; =
0; &lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt; -lt 6; &lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt;++)
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# create a "powershell pipeline runner" &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt; += [powershell]:&lt;/span&gt;&lt;span class="symbol"&gt;:create&lt;/span&gt;&lt;span&gt;()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# assign our pool of 3 runspaces to
use &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt;].runspacepool
= &lt;/span&gt;&lt;span class="variable"&gt;$pool&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$freq&lt;/span&gt;&lt;span&gt; = 440 + (&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt; *
10)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$sleep&lt;/span&gt;&lt;span&gt; = (1 * (&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt; +
1))&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# test command: beep and wait a certain
time &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; [void]&lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt;].AddScript(&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="string"&gt;"[console]::Beep($freq,
30); sleep -seconds $sleep"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# start job &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; write-host &lt;/span&gt;&lt;span class="string"&gt;"Job $i will run for $sleep
second(s)"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$jobs&lt;/span&gt;&lt;span&gt; += &lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt;].BeginInvoke();&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; write-host &lt;/span&gt;&lt;span class="string"&gt;"Available runspaces: $($pool.GetAvailableRunspaces())"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# store wait handles for WaitForAll
call &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$wait&lt;/span&gt;&lt;span&gt; += &lt;/span&gt;&lt;span class="variable"&gt;$jobs&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt;].AsyncWaitHandle&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# wait 20 seconds for all jobs to complete, else
abort &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$success&lt;/span&gt;&lt;span&gt; = [System.Threading.WaitHandle]::WaitAll(&lt;/span&gt;&lt;span class="variable"&gt;$wait&lt;/span&gt;&lt;span&gt;,
20000)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;write-host &lt;/span&gt;&lt;span class="string"&gt;"All completed? $success"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# end async call &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt; =
0; &lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt; -lt 6; &lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt;++)
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; write-host &lt;/span&gt;&lt;span class="string"&gt;"Completing async
pipeline job $i"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# complete
async job &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt;].EndInvoke(&lt;/span&gt;&lt;span class="variable"&gt;$jobs&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt;])&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# oops-ee! &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; write-warning &lt;/span&gt;&lt;span class="string"&gt;"error:
$_"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# dump info about completed
pipelines &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$info&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$ps&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$i&lt;/span&gt;&lt;span&gt;].InvocationStateInfo&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; write-host &lt;/span&gt;&lt;span class="string"&gt;"State: $($info.state)
; Reason: $($info.reason)"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# should show 3 again. &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;write-host &lt;/span&gt;&lt;span class="string"&gt;"Available runspaces: $($pool.GetAvailableRunspaces())"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Feel free to post questions or requests for clarification, but I did say it was a
bit tough and developer-oriented. I have a hint that our good friend and fellow MVP, &lt;a href="http://karlprosser.com/coder/" target="_blank"&gt;Karl
Prosser&lt;/a&gt; (aka Klumsy), will be wrapping up some of this stuff into some nice admin-oriented
background&amp;nbsp; command functions. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;IMPORTANT:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Due to the WaitAll call at line 40, this script will &lt;strong&gt;not&lt;/strong&gt; work
in an STA thread (i.e. in PowerShell ISE). Use PowerShell.EXE to run this script.
Everything else will work in ISE fine.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=846a72ce-4e85-49b5-bfb6-09e2080db40b" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,846a72ce-4e85-49b5-bfb6-09e2080db40b.aspx</comments>
      <category>.NET</category>
      <category>CTP3</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=15c3cda2-1805-461c-ac91-6076a61180f2</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,15c3cda2-1805-461c-ac91-6076a61180f2.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,15c3cda2-1805-461c-ac91-6076a61180f2.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=15c3cda2-1805-461c-ac91-6076a61180f2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Meson tweeted a request asking if it was possible to get a list of language keywords
from <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> itself.
The answer is officially “No,” but like most things of this nature, there’s always
a sneaky way: 
</p>
        <!-- Stylesheet link -->
        <link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" />
        <!-- Code -->
        <div id="hlDiv" class="dp-highlighter">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span>[type]:</span>
                <span class="symbol">:gettype</span>
                <span>(</span>
                <span class="string">"System.Management.Automation.KeywordTokenReader"</span>
                <span>)|%{</span>
                <span class="variable">$_</span>
                <span>.InvokeMember(</span>
                <span class="string">"_keywordTokens"</span>
                <span>, </span>
                <span class="string">"NonPublic,Static,GetField"</span>
                <span>, </span>
                <span class="variable">$null</span>
                <span>, </span>
                <span class="variable">$_</span>
                <span>,@())}   </span>
              </span>
            </li>
          </ol>
        </div>
        <p>
More interestingly this list turned up a new script keyword, <strong>dynamicparam. </strong>I
haven’t seen it in action yet but it sounds like another “advanced function” feature
to bring functions and cmdlets closer to parity. I may need to add another article
to my dynamic parameter series ;-)
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=15c3cda2-1805-461c-ac91-6076a61180f2" />
      </body>
      <title>PowerShell One Liner: Listing known language keywords in CTP3</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,15c3cda2-1805-461c-ac91-6076a61180f2.aspx</guid>
      <link>http://www.nivot.org/2008/12/27/PowerShellOneLinerListingKnownLanguageKeywordsInCTP3.aspx</link>
      <pubDate>Sat, 27 Dec 2008 05:21:38 GMT</pubDate>
      <description>&lt;p&gt;
Meson tweeted a request asking if it was possible to get a list of language keywords
from &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; itself.
The answer is officially “No,” but like most things of this nature, there’s always
a sneaky way: 
&lt;/p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css"&gt;
&lt;!-- Code --&gt;
&lt;div id="hlDiv" class="dp-highlighter"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span&gt;[type]:&lt;/span&gt;&lt;span class="symbol"&gt;:gettype&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="string"&gt;"System.Management.Automation.KeywordTokenReader"&lt;/span&gt;&lt;span&gt;)|%{&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.InvokeMember(&lt;/span&gt;&lt;span class="string"&gt;"_keywordTokens"&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="string"&gt;"NonPublic,Static,GetField"&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="variable"&gt;$null&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;,@())}&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
More interestingly this list turned up a new script keyword, &lt;strong&gt;dynamicparam. &lt;/strong&gt;I
haven’t seen it in action yet but it sounds like another “advanced function” feature
to bring functions and cmdlets closer to parity. I may need to add another article
to my dynamic parameter series ;-)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=15c3cda2-1805-461c-ac91-6076a61180f2" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,15c3cda2-1805-461c-ac91-6076a61180f2.aspx</comments>
      <category>.NET</category>
      <category>CTP3</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=54e152f7-4a8d-456e-af87-65e8c6cf6cf2</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,54e152f7-4a8d-456e-af87-65e8c6cf6cf2.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,54e152f7-4a8d-456e-af87-65e8c6cf6cf2.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=54e152f7-4a8d-456e-af87-65e8c6cf6cf2</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is an interesting exercise to show the power of PowerShell’s language to explore
and manipulate object models, specifically its own. You all should be familiar with
Type Accelerators: The short name syntax for accessing commonly used .NET Types. An
example would be [wmi] – this is the same as typing [System.Management.ManagementObject].
So, how can we find all of the current existing Type Accelerators? Well, after cracking
open <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> with
our favourite decompilation tool, <a target="_blank" href="http://www.red-gate.com/products/reflector/">Reflector</a>,
the class in question is System.Management.Automation.TypeAccelerators. Here’s what
it looks like:
</p>
        <!-- Stylesheet link -->
        <link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" />
        <!-- Code -->
        <div id="hlDiv" class="dp-highlighter">
          <div class="bar">
          </div>
          <ol class="dp-c">
            <li class="alt">
              <span>
                <span class="keyword">internal</span>
                <span> </span>
                <span class="keyword">static</span>
                <span> </span>
                <span class="keyword">class</span>
                <span> TypeAccelerators   </span>
              </span>
            </li>
            <li>
              <span>{   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment">// Fields </span>
              <span>  </span>
            </li>
            <li>
              <span>    </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">static</span>
              <span> Dictionary&lt;</span>
              <span class="keyword">string</span>
              <span>,
Type&gt; allTypeAccelerators;   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">internal</span>
              <span> </span>
              <span class="keyword">static</span>
              <span> Dictionary&lt;</span>
              <span class="keyword">string</span>
              <span>,
Type&gt; builtinTypeAccelerators;   </span>
            </li>
            <li>
              <span>    </span>
              <span class="keyword">internal</span>
              <span> </span>
              <span class="keyword">static</span>
              <span> Dictionary&lt;</span>
              <span class="keyword">string</span>
              <span>,
Type&gt; userTypeAccelerators;   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li>
              <span>    </span>
              <span class="comment">// Methods </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">static</span>
              <span> TypeAccelerators();   </span>
            </li>
            <li>
              <span>    </span>
              <span class="keyword">public</span>
              <span> </span>
              <span class="keyword">static</span>
              <span> </span>
              <span class="keyword">void</span>
              <span> Add(</span>
              <span class="keyword">string</span>
              <span> typeName,
Type type);   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">internal</span>
              <span> </span>
              <span class="keyword">static</span>
              <span> </span>
              <span class="keyword">void</span>
              <span> FillCache(Dictionary&lt;</span>
              <span class="keyword">string</span>
              <span>,
Type&gt; cache);   </span>
            </li>
            <li>
              <span>    </span>
              <span class="keyword">internal</span>
              <span> </span>
              <span class="keyword">static</span>
              <span> </span>
              <span class="keyword">string</span>
              <span> FindBuiltinAccelerator(Type
type);   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">public</span>
              <span> </span>
              <span class="keyword">static</span>
              <span> </span>
              <span class="keyword">bool</span>
              <span> Remove(</span>
              <span class="keyword">string</span>
              <span> typeName);   </span>
            </li>
            <li>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment">// Properties </span>
              <span>  </span>
            </li>
            <li>
              <span>    </span>
              <span class="keyword">public</span>
              <span> </span>
              <span class="keyword">static</span>
              <span> Dictionary&lt;</span>
              <span class="keyword">string</span>
              <span>,
Type&gt; Get { </span>
              <span class="keyword">get</span>
              <span>; }   </span>
            </li>
            <li class="alt">
              <span>}   </span>
            </li>
            <li>
              <span>  </span>
            </li>
          </ol>
        </div>
        <p>
Interestingly, the methods that let you add and remove your own accelerators are marked
Public. The Type itself is internal, but the dictionary named “userTypeAccelerators”
is positively tantalizing. It looks like perhaps the team have plans to let people
add their own accelerators! Then again, this is a CTP, and this may change in the
future. Well, let’s see if we can finish off what the team half started ;-)
</p>
        <p>
First thing we need to do is get a reference to the internal class. The C# heads amongst
you will start thinking about using reflection to get your hands on the type, but
actually there’s an easier way. PowerShell’s language is incredibly flexible and through
sneakiness, you can use System.Type’s GetType method to invoke any public method without
reverting to tricky reflection calls. First of all, lets add our own user-defined
Type Accelerator which is aliased to this internal class itself:
</p>
        <div id="hlDiv" class="dp-highlighter">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span class="comment"># get a reference to the Type  </span>
                <span>  </span>
              </span>
            </li>
            <li>
              <span>
              </span>
              <span class="variable">$acceleratorsType</span>
              <span> = [type]:</span>
              <span class="symbol">:gettype</span>
              <span>(</span>
              <span class="string">"System.Management.Automation.TypeAccelerators"</span>
              <span>)   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># add an accelerator for this type ;-) </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$acceleratorsType</span>
              <span>::Add(</span>
              <span class="string">"accelerators"</span>
              <span>, </span>
              <span class="variable">$acceleratorsType</span>
              <span>)   </span>
            </li>
            <li>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># will return all built-in accelerators (property) </span>
              <span>  </span>
            </li>
            <li>
              <span>[accelerators]:</span>
              <span class="symbol">:get</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># add a user-defined accelerator </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>[accelerators]:</span>
              <span class="symbol">:add</span>
              <span>([string], [type])   </span>
            </li>
            <li>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># remove a user-defined accelerator </span>
              <span>  </span>
            </li>
            <li>
              <span>[accelerators]:</span>
              <span class="symbol">:remove</span>
              <span>([string])   </span>
            </li>
          </ol>
        </div>
        <p>
I’ve split the Type retrieval and Add methods into two lines for brevity. The parser
is actually flexible enough to understand the more pithy ([type]::gettype("System.Management.Automation.TypeAccelerators"))::Add(…).
</p>
        <p>
So what do we have in CTP3? 
</p>
        <table border="1" width="200">
          <colgroup>
            <col />
            <col />
          </colgroup>
          <tbody>
            <tr>
              <th>
Name</th>
              <th>
Type</th>
            </tr>
            <tr>
              <td>
int</td>
              <td>
System.Int32</td>
            </tr>
            <tr>
              <td>
long</td>
              <td>
System.Int64</td>
            </tr>
            <tr>
              <td>
string</td>
              <td>
System.String</td>
            </tr>
            <tr>
              <td>
char</td>
              <td>
System.Char</td>
            </tr>
            <tr>
              <td>
bool</td>
              <td>
System.Boolean</td>
            </tr>
            <tr>
              <td>
byte</td>
              <td>
System.Byte</td>
            </tr>
            <tr>
              <td>
double</td>
              <td>
System.Double</td>
            </tr>
            <tr>
              <td>
decimal</td>
              <td>
System.Decimal</td>
            </tr>
            <tr>
              <td>
float</td>
              <td>
System.Single</td>
            </tr>
            <tr>
              <td>
single</td>
              <td>
System.Single</td>
            </tr>
            <tr>
              <td>
regex</td>
              <td>
System.Text.RegularExpressions.Regex</td>
            </tr>
            <tr>
              <td>
array</td>
              <td>
System.Array</td>
            </tr>
            <tr>
              <td>
xml</td>
              <td>
System.Xml.XmlDocument</td>
            </tr>
            <tr>
              <td>
scriptblock</td>
              <td>
System.Management.Automation.ScriptBlock</td>
            </tr>
            <tr>
              <td>
switch</td>
              <td>
System.Management.Automation.SwitchParameter</td>
            </tr>
            <tr>
              <td>
hashtable</td>
              <td>
System.Collections.Hashtable</td>
            </tr>
            <tr>
              <td>
type</td>
              <td>
System.Type</td>
            </tr>
            <tr>
              <td>
ref</td>
              <td>
System.Management.Automation.PSReference</td>
            </tr>
            <tr>
              <td>
psobject</td>
              <td>
System.Management.Automation.PSObject</td>
            </tr>
            <tr>
              <td>
pscustomobject</td>
              <td>
System.Management.Automation.PSObject</td>
            </tr>
            <tr>
              <td>
psmoduleinfo</td>
              <td>
System.Management.Automation.PSModuleInfo</td>
            </tr>
            <tr>
              <td>
powershell</td>
              <td>
System.Management.Automation.PowerShell</td>
            </tr>
            <tr>
              <td>
runspacefactory</td>
              <td>
System.Management.Automation.Runspaces.RunspaceFactory</td>
            </tr>
            <tr>
              <td>
runspace</td>
              <td>
System.Management.Automation.Runspaces.Runspace</td>
            </tr>
            <tr>
              <td>
ipaddress</td>
              <td>
System.Net.IPAddress</td>
            </tr>
            <tr>
              <td>
wmi</td>
              <td>
System.Management.ManagementObject</td>
            </tr>
            <tr>
              <td>
wmisearcher</td>
              <td>
System.Management.ManagementObjectSearcher</td>
            </tr>
            <tr>
              <td>
wmiclass</td>
              <td>
System.Management.ManagementClass</td>
            </tr>
            <tr>
              <td>
adsi</td>
              <td>
System.DirectoryServices.DirectoryEntry</td>
            </tr>
            <tr>
              <td>
adsisearcher</td>
              <td>
System.DirectoryServices.DirectorySearcher</td>
            </tr>
            <tr>
              <td>
accelerators</td>
              <td>
System.Management.Automation.TypeAccelerators</td>
            </tr>
          </tbody>
        </table>
        <p>
Btw, I generated the above list with this one liner:
</p>
        <div id="hlDiv" class="dp-highlighter">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span>[accelerators]::Get.getenumerator() | `   </span>
              </span>
            </li>
            <li>
              <span>    select @{Name=</span>
              <span class="string">"Name"</span>
              <span>;
expression={</span>
              <span class="variable">$_</span>
              <span>.key}},   </span>
            </li>
            <li class="alt">
              <span>           @{name=</span>
              <span class="string">"Type"</span>
              <span>;
expression={</span>
              <span class="variable">$_</span>
              <span>.value}} | `   </span>
            </li>
            <li>
              <span>    convertto-html -fragment &gt; .\accelerators.html   </span>
            </li>
          </ol>
        </div>
        <p>
Have fun!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=54e152f7-4a8d-456e-af87-65e8c6cf6cf2" />
      </body>
      <title>List of Type Accelerators for PowerShell CTP3</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,54e152f7-4a8d-456e-af87-65e8c6cf6cf2.aspx</guid>
      <link>http://www.nivot.org/2008/12/25/ListOfTypeAcceleratorsForPowerShellCTP3.aspx</link>
      <pubDate>Thu, 25 Dec 2008 20:29:55 GMT</pubDate>
      <description>&lt;p&gt;
This is an interesting exercise to show the power of PowerShell’s language to explore
and manipulate object models, specifically its own. You all should be familiar with
Type Accelerators: The short name syntax for accessing commonly used .NET Types. An
example would be [wmi] – this is the same as typing [System.Management.ManagementObject].
So, how can we find all of the current existing Type Accelerators? Well, after cracking
open &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; with
our favourite decompilation tool, &lt;a target="_blank" href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt;,
the class in question is System.Management.Automation.TypeAccelerators. Here’s what
it looks like:
&lt;/p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css"&gt;
&lt;!-- Code --&gt;
&lt;div id="hlDiv" class="dp-highlighter"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-c"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="keyword"&gt;internal&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt; TypeAccelerators&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;{&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// Fields &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt; Dictionary&amp;lt;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;,
Type&amp;gt; allTypeAccelerators;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;internal&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt; Dictionary&amp;lt;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;,
Type&amp;gt; builtinTypeAccelerators;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;internal&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt; Dictionary&amp;lt;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;,
Type&amp;gt; userTypeAccelerators;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// Methods &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt; TypeAccelerators();&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt; Add(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; typeName,
Type type);&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;internal&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt; FillCache(Dictionary&amp;lt;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;,
Type&amp;gt; cache);&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;internal&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; FindBuiltinAccelerator(Type
type);&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;bool&lt;/span&gt;&lt;span&gt; Remove(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; typeName);&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// Properties &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt; Dictionary&amp;lt;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;,
Type&amp;gt; Get { &lt;/span&gt;&lt;span class="keyword"&gt;get&lt;/span&gt;&lt;span&gt;; }&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
Interestingly, the methods that let you add and remove your own accelerators are marked
Public. The Type itself is internal, but the dictionary named “userTypeAccelerators”
is positively tantalizing. It looks like perhaps the team have plans to let people
add their own accelerators! Then again, this is a CTP, and this may change in the
future. Well, let’s see if we can finish off what the team half started ;-)
&lt;/p&gt;
&lt;p&gt;
First thing we need to do is get a reference to the internal class. The C# heads amongst
you will start thinking about using reflection to get your hands on the type, but
actually there’s an easier way. PowerShell’s language is incredibly flexible and through
sneakiness, you can use System.Type’s GetType method to invoke any public method without
reverting to tricky reflection calls. First of all, lets add our own user-defined
Type Accelerator which is aliased to this internal class itself:
&lt;/p&gt;
&lt;div id="hlDiv" class="dp-highlighter"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="comment"&gt;# get a reference to the Type&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$acceleratorsType&lt;/span&gt;&lt;span&gt; = [type]:&lt;/span&gt;&lt;span class="symbol"&gt;:gettype&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="string"&gt;"System.Management.Automation.TypeAccelerators"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# add an accelerator for this type ;-) &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$acceleratorsType&lt;/span&gt;&lt;span&gt;::Add(&lt;/span&gt;&lt;span class="string"&gt;"accelerators"&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="variable"&gt;$acceleratorsType&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# will return all built-in accelerators (property) &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;[accelerators]:&lt;/span&gt;&lt;span class="symbol"&gt;:get&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# add a user-defined accelerator &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;[accelerators]:&lt;/span&gt;&lt;span class="symbol"&gt;:add&lt;/span&gt;&lt;span&gt;([string], [type])&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# remove a user-defined accelerator &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;[accelerators]:&lt;/span&gt;&lt;span class="symbol"&gt;:remove&lt;/span&gt;&lt;span&gt;([string])&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
I’ve split the Type retrieval and Add methods into two lines for brevity. The parser
is actually flexible enough to understand the more pithy ([type]::gettype("System.Management.Automation.TypeAccelerators"))::Add(…).
&lt;/p&gt;
&lt;p&gt;
So what do we have in CTP3? 
&lt;/p&gt;
&lt;table border="1" width="200"&gt;
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;
Name&lt;/th&gt;
&lt;th&gt;
Type&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
int&lt;/td&gt;
&lt;td&gt;
System.Int32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
long&lt;/td&gt;
&lt;td&gt;
System.Int64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
string&lt;/td&gt;
&lt;td&gt;
System.String&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
char&lt;/td&gt;
&lt;td&gt;
System.Char&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
bool&lt;/td&gt;
&lt;td&gt;
System.Boolean&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
byte&lt;/td&gt;
&lt;td&gt;
System.Byte&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
double&lt;/td&gt;
&lt;td&gt;
System.Double&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
decimal&lt;/td&gt;
&lt;td&gt;
System.Decimal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
float&lt;/td&gt;
&lt;td&gt;
System.Single&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
single&lt;/td&gt;
&lt;td&gt;
System.Single&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
regex&lt;/td&gt;
&lt;td&gt;
System.Text.RegularExpressions.Regex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
array&lt;/td&gt;
&lt;td&gt;
System.Array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
xml&lt;/td&gt;
&lt;td&gt;
System.Xml.XmlDocument&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
scriptblock&lt;/td&gt;
&lt;td&gt;
System.Management.Automation.ScriptBlock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
switch&lt;/td&gt;
&lt;td&gt;
System.Management.Automation.SwitchParameter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
hashtable&lt;/td&gt;
&lt;td&gt;
System.Collections.Hashtable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
type&lt;/td&gt;
&lt;td&gt;
System.Type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
ref&lt;/td&gt;
&lt;td&gt;
System.Management.Automation.PSReference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
psobject&lt;/td&gt;
&lt;td&gt;
System.Management.Automation.PSObject&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
pscustomobject&lt;/td&gt;
&lt;td&gt;
System.Management.Automation.PSObject&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
psmoduleinfo&lt;/td&gt;
&lt;td&gt;
System.Management.Automation.PSModuleInfo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
powershell&lt;/td&gt;
&lt;td&gt;
System.Management.Automation.PowerShell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
runspacefactory&lt;/td&gt;
&lt;td&gt;
System.Management.Automation.Runspaces.RunspaceFactory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
runspace&lt;/td&gt;
&lt;td&gt;
System.Management.Automation.Runspaces.Runspace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
ipaddress&lt;/td&gt;
&lt;td&gt;
System.Net.IPAddress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
wmi&lt;/td&gt;
&lt;td&gt;
System.Management.ManagementObject&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
wmisearcher&lt;/td&gt;
&lt;td&gt;
System.Management.ManagementObjectSearcher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
wmiclass&lt;/td&gt;
&lt;td&gt;
System.Management.ManagementClass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
adsi&lt;/td&gt;
&lt;td&gt;
System.DirectoryServices.DirectoryEntry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
adsisearcher&lt;/td&gt;
&lt;td&gt;
System.DirectoryServices.DirectorySearcher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
accelerators&lt;/td&gt;
&lt;td&gt;
System.Management.Automation.TypeAccelerators&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
Btw, I generated the above list with this one liner:
&lt;/p&gt;
&lt;div id="hlDiv" class="dp-highlighter"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span&gt;[accelerators]::Get.getenumerator() | `&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; select @{Name=&lt;/span&gt;&lt;span class="string"&gt;"Name"&lt;/span&gt;&lt;span&gt;;
expression={&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.key}},&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @{name=&lt;/span&gt;&lt;span class="string"&gt;"Type"&lt;/span&gt;&lt;span&gt;;
expression={&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.value}} | `&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; convertto-html -fragment &amp;gt; .\accelerators.html&amp;nbsp;&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=54e152f7-4a8d-456e-af87-65e8c6cf6cf2" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,54e152f7-4a8d-456e-af87-65e8c6cf6cf2.aspx</comments>
      <category>.NET</category>
      <category>CTP3</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=3e82586b-d5c3-4e0d-883a-74e22919247c</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,3e82586b-d5c3-4e0d-883a-74e22919247c.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,3e82586b-d5c3-4e0d-883a-74e22919247c.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=3e82586b-d5c3-4e0d-883a-74e22919247c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Just to be completely silly, I thought I’d do a series of posts on CTP3 features themed
around Christmas. Hmm. That might read better as a series of Christmas posts themed
around CTP3. A very original idea I’m sure, but hey, those who know me will know that
I never pass up the opportunity to make a bad joke. So, without further adieu:
</p>
        <p>
On the first day of Christmas, <a href="http://twitter.com/jsnover" target="_blank">Jeffrey</a> gave
to me: 
</p>
        <h3>Nested Here-Strings
</h3>
        <p>
Here-Strings can now be embedded within each other to make it even easier to construct
literal documents! Delimit any nested code between $( and ) and then continue to use
a nested string within that as if it was completely stand alone. It just works! Cool,
eh?
</p>
        <!-- Stylesheet link -->
        <link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet" />
        <!-- Code -->
        <div class="dp-highlighter" id="hlDiv">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span class="keyword">function</span>
                <span> Get-CommandDefinitionHtml {   </span>
              </span>
            </li>
            <li class="">
              <span>       </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment"># this tells powershell to allow
advanced features, </span>
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="comment"># like the [validatenotnullorempty()]
attribute below. </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    [CmdletBinding()]   </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">param</span>
              <span>(   </span>
            </li>
            <li class="alt">
              <span>        [ValidateNotNullOrEmpty()]   </span>
            </li>
            <li class="">
              <span>        [string]</span>
              <span class="variable">$name</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    )   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$command</span>
              <span> = get-command </span>
              <span class="variable">$name</span>
              <span>  </span>
            </li>
            <li class="">
              <span>       </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment"># Look mom! I'm a cmdlet! </span>
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="variable">$PSCmdlet</span>
              <span>.WriteVerbose(</span>
              <span class="string">"Dumping
HTML for "</span>
              <span> + </span>
              <span class="variable">$command</span>
              <span>)   </span>
            </li>
            <li class="alt">
              <span>       </span>
            </li>
            <li class="">
              <span>@</span>
              <span class="string">" </span>  
</li>
            <li class="alt">
              <span>
                <span class="string">    &lt;html&gt; </span> </span>
            </li>
            <li class="">
              <span>
                <span class="string">        &lt;head&gt; </span> </span>
            </li>
            <li class="alt">
              <span>
                <span class="string">           
&lt;title&gt;$($command.name)&lt;/title&gt; </span> </span>
            </li>
            <li class="">
              <span>
                <span class="string">        &lt;/head&gt; </span> </span>
            </li>
            <li class="alt">
              <span>
                <span class="string">        &lt;body&gt; </span> </span>
            </li>
            <li class="">
              <span>
                <span class="string">           
&lt;table border="</span>
                <span>1</span>
                <span class="string">"&gt; </span> </span>
            </li>
            <li class="alt">
              <span>
                <span class="string">$( </span> </span>
            </li>
            <li class="">
              <span>
                <span class="string">    $command.parametersets | % { </span> </span>
            </li>
            <li class="alt">
              <span>
                <span class="string">@"</span>
                <span>  </span>
              </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>            &lt;tr&gt;   </span>
            </li>
            <li class="">
              <span>               
&lt;td&gt;$(</span>
              <span class="variable">$_</span>
              <span>.name)&lt;/td&gt;   </span>
            </li>
            <li class="alt">
              <span>               
&lt;td&gt;   </span>
            </li>
            <li class="">
              <span>                   
&lt;table border=</span>
              <span class="string">"1"</span>
              <span>&gt;   </span>
            </li>
            <li class="alt">
              <span>                       
&lt;tr&gt;   </span>
            </li>
            <li class="">
              <span>                           
&lt;th colspan=</span>
              <span class="string">"8"</span>
              <span>&gt;Parameters&lt;/th&gt;   </span>
            </li>
            <li class="alt">
              <span>                               </span>
            </li>
            <li class="">
              <span>$(   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="variable">$count</span>
              <span> =
0   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="variable">$_</span>
              <span>.parameters
| % {   </span>
            </li>
            <li class="alt">
              <span>            </span>
              <span class="keyword">if</span>
              <span> (0
-eq (</span>
              <span class="variable">$count</span>
              <span> % 8)) {   </span>
            </li>
            <li class="">
              <span>@</span>
              <span class="string">" </span>  
</li>
            <li class="alt">
              <span>
                <span class="string">                       
&lt;/tr&gt; </span> </span>
            </li>
            <li class="">
              <span>
                <span class="string">                       
&lt;tr&gt; </span> </span>
            </li>
            <li class="alt">
              <span>
                <span class="string">"</span>
                <span>@   </span>
              </span>
            </li>
            <li class="">
              <span>            }                   </span>
            </li>
            <li class="alt">
              <span>@</span>
              <span class="string">" </span>  
</li>
            <li class="">
              <span>
                <span class="string">                           
&lt;td&gt;$($_.name)&lt;/td&gt; </span> </span>
            </li>
            <li class="alt">
              <span>
                <span class="string">"</span>
                <span>@               </span>
              </span>
            </li>
            <li class="">
              <span>            </span>
              <span class="variable">$count</span>
              <span>++   </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li class="">
              <span>)   </span>
            </li>
            <li class="alt">
              <span>                       
&lt;/tr&gt;                           </span>
            </li>
            <li class="">
              <span>                   
&lt;/table&gt;   </span>
            </li>
            <li class="alt">
              <span>               
&lt;/td&gt;   </span>
            </li>
            <li class="">
              <span>            &lt;/tr&gt;   </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="string">"@ </span>  
</li>
            <li class="">
              <span>
                <span class="string">    } </span> </span>
            </li>
            <li class="alt">
              <span>
                <span class="string">) </span> </span>
            </li>
            <li class="">
              <span>
                <span class="string">           
&lt;/table&gt;         </span> </span>
            </li>
            <li class="alt">
              <span>
                <span class="string">        &lt;/body&gt; </span> </span>
            </li>
            <li class="">
              <span>
                <span class="string">    &lt;/html&gt; </span> </span>
            </li>
            <li class="alt">
              <span>
                <span class="string">"</span>
                <span>@       </span>
              </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>Get-CommandDefinitionHtml get-item &gt; out.html   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># show in browser </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>invoke-item out.html  </span>
            </li>
          </ol>
        </div>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=3e82586b-d5c3-4e0d-883a-74e22919247c" />
      </body>
      <title>The Twelve days of PowerShell 2.0 CTP3!</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,3e82586b-d5c3-4e0d-883a-74e22919247c.aspx</guid>
      <link>http://www.nivot.org/2008/12/23/TheTwelveDaysOfPowerShell20CTP3.aspx</link>
      <pubDate>Tue, 23 Dec 2008 21:16:03 GMT</pubDate>
      <description>&lt;p&gt;
Just to be completely silly, I thought I’d do a series of posts on CTP3 features themed
around Christmas. Hmm. That might read better as a series of Christmas posts themed
around CTP3. A very original idea I’m sure, but hey, those who know me will know that
I never pass up the opportunity to make a bad joke. So, without further adieu:
&lt;/p&gt;
&lt;p&gt;
On the first day of Christmas, &lt;a href="http://twitter.com/jsnover" target="_blank"&gt;Jeffrey&lt;/a&gt; gave
to me: 
&lt;/p&gt;
&lt;h3&gt;Nested Here-Strings
&lt;/h3&gt;
&lt;p&gt;
Here-Strings can now be embedded within each other to make it even easier to construct
literal documents! Delimit any nested code between $( and ) and then continue to use
a nested string within that as if it was completely stand alone. It just works! Cool,
eh?
&lt;/p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet"&gt;
&lt;!-- Code --&gt;
&lt;div class="dp-highlighter" id="hlDiv"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="keyword"&gt;function&lt;/span&gt;&lt;span&gt; Get-CommandDefinitionHtml {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# this tells powershell to allow
advanced features, &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# like the [validatenotnullorempty()]
attribute below. &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [CmdletBinding()]&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;param&lt;/span&gt;&lt;span&gt;(&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ValidateNotNullOrEmpty()]&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [string]&lt;/span&gt;&lt;span class="variable"&gt;$name&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$command&lt;/span&gt;&lt;span&gt; = get-command &lt;/span&gt;&lt;span class="variable"&gt;$name&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# Look mom! I'm a cmdlet! &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$PSCmdlet&lt;/span&gt;&lt;span&gt;.WriteVerbose(&lt;/span&gt;&lt;span class="string"&gt;"Dumping
HTML for "&lt;/span&gt;&lt;span&gt; + &lt;/span&gt;&lt;span class="variable"&gt;$command&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;@&lt;/span&gt;&lt;span class="string"&gt;" &lt;/span&gt;&amp;nbsp;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;html&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;head&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;title&amp;gt;$($command.name)&amp;lt;/title&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/head&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;body&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;table border="&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span class="string"&gt;"&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;$( &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $command.parametersets | % { &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;@"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&amp;gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;td&amp;gt;$(&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.name)&amp;lt;/td&amp;gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;td&amp;gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;table border=&lt;/span&gt;&lt;span class="string"&gt;"1"&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;tr&amp;gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;th colspan=&lt;/span&gt;&lt;span class="string"&gt;"8"&lt;/span&gt;&lt;span&gt;&amp;gt;Parameters&amp;lt;/th&amp;gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;$(&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$count&lt;/span&gt;&lt;span&gt; =
0&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.parameters
| % {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (0
-eq (&lt;/span&gt;&lt;span class="variable"&gt;$count&lt;/span&gt;&lt;span&gt; % 8)) {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;@&lt;/span&gt;&lt;span class="string"&gt;" &lt;/span&gt;&amp;nbsp;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/tr&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;tr&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;"&lt;/span&gt;&lt;span&gt;@&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;@&lt;/span&gt;&lt;span class="string"&gt;" &lt;/span&gt;&amp;nbsp;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;td&amp;gt;$($_.name)&amp;lt;/td&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;"&lt;/span&gt;&lt;span&gt;@&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$count&lt;/span&gt;&lt;span&gt;++&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/tr&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/table&amp;gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/td&amp;gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="string"&gt;"@ &lt;/span&gt;&amp;nbsp;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;) &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/table&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/body&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;span class="string"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/html&amp;gt; &lt;/span&gt;&amp;nbsp;&lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="string"&gt;"&lt;/span&gt;&lt;span&gt;@&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;Get-CommandDefinitionHtml get-item &amp;gt; out.html&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# show in browser &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;invoke-item out.html&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=3e82586b-d5c3-4e0d-883a-74e22919247c" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,3e82586b-d5c3-4e0d-883a-74e22919247c.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>CTP3</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=aecfef34-9b4a-460d-84fa-ab5259f14e1d</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,aecfef34-9b4a-460d-84fa-ab5259f14e1d.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,aecfef34-9b4a-460d-84fa-ab5259f14e1d.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=aecfef34-9b4a-460d-84fa-ab5259f14e1d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
To quote the completely understated download blurb:
</p>
        <blockquote>
          <p>
            <em>Windows PowerShell V2 CTP3 introduces several significant features to Windows
PowerShell 1.0 and Windows PowerShell V2 CTPs that extends its use, improves its usability,
and allows you to control and manage the Windows environment more easily and comprehensively.</em>
          </p>
        </blockquote>
        <p>
The release notes are quite extensive. Here is the section on breaking changes from
CTP2: 
</p>
        <p>
          <b>Breaking Changes to Windows PowerShell V2 (CTP2)</b>
        </p>
        <p>
          <b>
          </b>
        </p>
        <p align="left">
The following changes in Windows PowerShell V2.0 CTP3 might prevent features designed
for Windows PowerShell 2.0 CTP2 from working correctly. 
</p>
        <p align="left">
          <a name="_Setup_with_scripts">
          </a>
        </p>
        <ul>
          <li>
            <div align="left">Following cmdlets have been renamed<b></b></div>
            <ul>
              <li>
                <div align="left">Add-Module to Import-Module<b></b></div>
              </li>
              <li>
                <div align="left">Get-Event to Get-WinEvent<b></b></div>
              </li>
              <li>
                <div align="left">*-Runspace to *-PSSession<b></b></div>
              </li>
              <li>
                <div align="left">Push-Runspace to Enter-PSSession<b></b></div>
              </li>
              <li>
                <div align="left">Pop-Runspace to Exit-PSSession<b></b></div>
              </li>
              <li>
                <div align="left">*-PSEvent to *-Event<b></b></div>
              </li>
              <li>
                <div align="left">Register-PSEvent to Register-EngineEvent<b></b></div>
              </li>
              <li>
                <div align="left">*-PSTransaction to *-Transaction<b></b></div>
              </li>
              <li>
                <div align="left">*-PSJob to *-Job<b></b></div>
              </li>
              <li>
                <div align="left">*-PSEventSubscriber to *-EventSubscriber<b></b></div>
              </li>
              <li>
                <div align="left">*-Bite to *-FileTransfer<b></b></div>
              </li>
            </ul>
          </li>
        </ul>
        <p align="left">
          <b>
          </b>
        </p>
        <ul>
          <li>
            <div align="left">Following parameters have been renamed
</div>
            <ul>
              <li>
                <div align="left">Import-LocalizedData: Culture to UICulture
</div>
              </li>
              <li>
                <div align="left">Invoke-Command: Runspace to Session, Shell to ConfigurationName
</div>
              </li>
              <li>
                <div align="left">Get-Job: SessionId to Id 
</div>
              </li>
              <li>
                <div align="left">Receive-Job: Runspace to Session, SessionId to Id
</div>
              </li>
              <li>
                <div align="left">Remove-Job: SessionId to Id
</div>
              </li>
              <li>
                <div align="left">Start-Job: Command to Scriptblock
</div>
              </li>
              <li>
                <div align="left">Stop-Job: SessionId to Id
</div>
              </li>
              <li>
                <div align="left">Wait-Job: SessionId to Id
</div>
              </li>
              <li>
                <div align="left">Get-PSSession: RemoteRunspaceID to InstanceId, SessionId to Id
</div>
              </li>
              <li>
                <div align="left">New-PSSession: Runspace to Session, Shell to ConfigurationName
</div>
              </li>
              <li>
                <div align="left">Enter-PSSession: Runspace to Session, RemoteRunspaceID to InstanceId,
SessionId to Id, Shell to ConfigurationName
</div>
              </li>
              <li>
                <div align="left">Remove-PSSession: Runspace to Session, RemoteRunspaceID to InstanceId,
SessionId to Id
</div>
              </li>
            </ul>
          </li>
        </ul>
        <p align="left">
          <b>
          </b>
        </p>
        <ul>
          <li>
            <div align="left">Following parameters have been deleted
</div>
            <ul>
              <li>
                <div align="left">Export-ModuleMember: Update, ExportList
</div>
              </li>
              <li>
                <div align="left">Set-Service: Include, Exclude
</div>
              </li>
            </ul>
          </li>
        </ul>
        <p align="left">
          <b>
          </b>
        </p>
        <ul>
          <li>
            <div align="left">Following variables have been renamed<b></b></div>
            <ul>
              <li>
                <div align="left">$CommandLineParameters to $PSBoundParameters<b></b></div>
              </li>
              <li>
                <div align="left">$PSPackagePath to $PSModulePath<b></b></div>
              </li>
            </ul>
          </li>
        </ul>
        <p align="left">
          <b>
          </b>
        </p>
        <ul>
          <li>
            <div align="left">Packages have been renamed to Modules. Packages folder is now renamed
to Modules folder. A module imported into another module is now treated as a nested
module instead of a peer module. This allows a new module to wrap or repackage one
or more existing modules.
</div>
          </li>
        </ul>
        <p align="left">
          <b>
          </b>
        </p>
        <ul>
          <li>
            <div align="left">"Script cmdlets" have been renamed to "advanced functions." The
“cmdlet” keyword has been replaced with the “function” keyword.<b></b>For script
cmdlet functionality, use CmdletBinding attribute in the function’s param block. For
more information, see about_functions_advanced.
</div>
          </li>
        </ul>
        <ul>
          <li>
            <div align="left">The Config-WSMan.ps1 script in the $pshome directory has been replaced
by the Enable-PSRemoting function. To configure your system for WS-Management remoting,
use the following command<b>:</b></div>
          </li>
        </ul>
        <p align="left">
          <b>Enable-PSRemoting –force</b>
        </p>
        <p align="left">
          <b>
          </b>
        </p>
        <p align="left">
          <i>Note: If you have upgraded from the Windows PowerShell V2 CTP2 release to the Windows
PowerShell V2 CTP3 release, to configure your system for WS-Management remoting, type:</i>
        </p>
        <p align="left">
          <b>Unregister-PSSessionConfiguration * -force;</b>
        </p>
        <p align="left">
          <b>Register-PSSessionConfiguration Microsoft.PowerShell –force;</b>
        </p>
        <p align="left">
          <b>Enable-PSRemoting –force</b>
        </p>
        <ul>
          <li>
            <div align="left">In the Out-GridView cmdlet, the drop-down list used to filter objects
is now called “Query” instead of “Filter”.<b></b></div>
          </li>
        </ul>
        <p align="left">
          <b>
          </b>
        </p>
        <ul>
          <li>
            <div align="left">The following changes have been made to Windows PowerShell Integrated
Scripting Environment (ISE):
</div>
          </li>
        </ul>
        <ul>
          <ul>
            <li>
              <div align="left">The name of the application has changed from “Graphical Windows
PowerShell” to “Windows PowerShell Integrated Scripting Environment (ISE)”
</div>
            </li>
            <li>
              <div align="left">The executable name has changed from “gpowershell.exe” to “powershell_ise.exe”
</div>
            </li>
            <li>
              <div align="left">The profile name has changed from “\Users\&lt;username&gt;\Documents\WindowsPowerShell\Microsoft.GPowerShell_profile.ps1”
to “\Users\&lt;username&gt;\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1”
</div>
            </li>
            <li>
              <div align="left">The term “runspace” has been replaced with “PowerShell tab”.
</div>
            </li>
          </ul>
        </ul>
        <p>
Get it from <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c913aeab-d7b4-4bb1-a958-ee6d7fe307bc" target="_blank">http://www.microsoft.com/downloads/details.aspx?FamilyID=c913aeab-d7b4-4bb1-a958-ee6d7fe307bc</a> –
piping hot! <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=aecfef34-9b4a-460d-84fa-ab5259f14e1d" /></p>
      </body>
      <title>PowerShell 2.0 CTP3 has arrived!</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,aecfef34-9b4a-460d-84fa-ab5259f14e1d.aspx</guid>
      <link>http://www.nivot.org/2008/12/23/PowerShell20CTP3HasArrived.aspx</link>
      <pubDate>Tue, 23 Dec 2008 02:59:52 GMT</pubDate>
      <description>&lt;p&gt;
To quote the completely understated download blurb:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;Windows PowerShell V2 CTP3 introduces several significant features to Windows
PowerShell 1.0 and Windows PowerShell V2 CTPs that extends its use, improves its usability,
and allows you to control and manage the Windows environment more easily and comprehensively.&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The release notes are quite extensive. Here is the section on breaking changes from
CTP2: 
&lt;p&gt;
&lt;b&gt;Breaking Changes to Windows PowerShell V2 (CTP2)&lt;/b&gt; 
&lt;p&gt;
&lt;b&gt;&lt;/b&gt; 
&lt;p align="left"&gt;
The following changes in Windows PowerShell V2.0 CTP3 might prevent features designed
for Windows PowerShell 2.0 CTP2 from working correctly. 
&lt;p align="left"&gt;
&lt;a name="_Setup_with_scripts"&gt;&lt;/a&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;Following cmdlets have been renamed&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;Add-Module to Import-Module&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Get-Event to Get-WinEvent&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;*-Runspace to *-PSSession&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Push-Runspace to Enter-PSSession&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Pop-Runspace to Exit-PSSession&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;*-PSEvent to *-Event&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Register-PSEvent to Register-EngineEvent&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;*-PSTransaction to *-Transaction&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;*-PSJob to *-Job&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;*-PSEventSubscriber to *-EventSubscriber&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;*-Bite to *-FileTransfer&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="left"&gt;
&lt;b&gt;&lt;/b&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;Following parameters have been renamed
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;Import-LocalizedData: Culture to UICulture
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Invoke-Command: Runspace to Session, Shell to ConfigurationName
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Get-Job: SessionId to Id 
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Receive-Job: Runspace to Session, SessionId to Id
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Remove-Job: SessionId to Id
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Start-Job: Command to Scriptblock
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Stop-Job: SessionId to Id
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Wait-Job: SessionId to Id
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Get-PSSession: RemoteRunspaceID to InstanceId, SessionId to Id
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;New-PSSession: Runspace to Session, Shell to ConfigurationName
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Enter-PSSession: Runspace to Session, RemoteRunspaceID to InstanceId,
SessionId to Id, Shell to ConfigurationName
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Remove-PSSession: Runspace to Session, RemoteRunspaceID to InstanceId,
SessionId to Id
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="left"&gt;
&lt;b&gt;&lt;/b&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;Following parameters have been deleted
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;Export-ModuleMember: Update, ExportList
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Set-Service: Include, Exclude
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="left"&gt;
&lt;b&gt;&lt;/b&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;Following variables have been renamed&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;$CommandLineParameters to $PSBoundParameters&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;$PSPackagePath to $PSModulePath&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="left"&gt;
&lt;b&gt;&lt;/b&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;Packages have been renamed to Modules. Packages folder is now renamed
to Modules folder. A module imported into another module is now treated as a nested
module instead of a peer module. This allows a new module to wrap or repackage one
or more existing modules.
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="left"&gt;
&lt;b&gt;&lt;/b&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;"Script cmdlets" have been renamed to "advanced functions." The
“cmdlet” keyword has been replaced with the “function” keyword.&lt;b&gt; &lt;/b&gt;For script
cmdlet functionality, use CmdletBinding attribute in the function’s param block. For
more information, see about_functions_advanced.
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;The Config-WSMan.ps1 script in the $pshome directory has been replaced
by the Enable-PSRemoting function. To configure your system for WS-Management remoting,
use the following command&lt;b&gt;:&lt;/b&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="left"&gt;
&lt;b&gt;Enable-PSRemoting –force&lt;/b&gt; 
&lt;p align="left"&gt;
&lt;b&gt;&lt;/b&gt; 
&lt;p align="left"&gt;
&lt;i&gt;Note: If you have upgraded from the Windows PowerShell V2 CTP2 release to the Windows
PowerShell V2 CTP3 release, to configure your system for WS-Management remoting, type:&lt;/i&gt; 
&lt;p align="left"&gt;
&lt;b&gt;Unregister-PSSessionConfiguration * -force;&lt;/b&gt; 
&lt;p align="left"&gt;
&lt;b&gt;Register-PSSessionConfiguration Microsoft.PowerShell –force;&lt;/b&gt; 
&lt;p align="left"&gt;
&lt;b&gt;Enable-PSRemoting –force&lt;/b&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;In the Out-GridView cmdlet, the drop-down list used to filter objects
is now called “Query” instead of “Filter”.&lt;b&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p align="left"&gt;
&lt;b&gt;&lt;/b&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;The following changes have been made to Windows PowerShell Integrated
Scripting Environment (ISE):
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;The name of the application has changed from “Graphical Windows
PowerShell” to “Windows PowerShell Integrated Scripting Environment (ISE)”
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;The executable name has changed from “gpowershell.exe” to “powershell_ise.exe”
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;The profile name has changed from “\Users\&amp;lt;username&amp;gt;\Documents\WindowsPowerShell\Microsoft.GPowerShell_profile.ps1”
to “\Users\&amp;lt;username&amp;gt;\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1”
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;The term “runspace” has been replaced with “PowerShell tab”.
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;p&gt;
Get it from &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c913aeab-d7b4-4bb1-a958-ee6d7fe307bc" target="_blank"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=c913aeab-d7b4-4bb1-a958-ee6d7fe307bc&lt;/a&gt; –
piping hot! &lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=aecfef34-9b4a-460d-84fa-ab5259f14e1d" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,aecfef34-9b4a-460d-84fa-ab5259f14e1d.aspx</comments>
      <category>.NET</category>
      <category>CTP3</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=f18d408c-6381-446a-aa62-e5751a432ccb</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,f18d408c-6381-446a-aa62-e5751a432ccb.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,f18d408c-6381-446a-aa62-e5751a432ccb.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=f18d408c-6381-446a-aa62-e5751a432ccb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This time around, I thought I’d show how to work with programmatically generated dynamic
parameters, as opposed to the statically defined sets we saw the last time. The context
here is a fairly silly Cmdlet, but it’s good enough to demonstrate the concept end
to end. It’s a Cmdlet for removing a file. It takes one string parameter which is
the path to the file. The dynamic parameter I’m going to add is a –Force parameter.
The trick is, this parameter will only be added if the current user is an administrator
(XP), or is elevated as one (Vista). 
</p>
        <p>
This first portion of the Cmdlet defines the usual stuff like a verb and noun. This
time though, I’m using a regular class constructor. It’s not often you see constructors
in simple Cmdlets because typically all one would usually do is override one or more
of the three processing methods BeginProcessing, ProcessRecord and EndProcessing.
In this case, I need to create a instance of a “<a href="http://msdn.microsoft.com/en-us/library/system.management.automation.runtimedefinedparameterdictionary(VS.85).aspx" target="_blank">RuntimeDefinedParameterDictionary</a>,”
which does exactly what it says on the tin. It’s a dictionary of parameters, the key
being a string (the name of the parameter) and the value being a instance of a RuntimeDefinedParameter
class. These classes are all members of the System.Management.Automation namespace. 
</p>
        <p>
In the constructor, I’m calling a generic method defined as AddDynamicParameter&lt;T&gt;(string
name). This is only called if the current user is an admin. I’ve defined three generic
helper methods which you can see a little further down below.
</p>
        <!-- Stylesheet link -->
        <link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet" />
        <!-- Code -->
        <div class="dp-highlighter" id="hlDiv">
          <div class="bar">
          </div>
          <ol class="dp-c">
            <li class="alt">
              <span>
                <span>[Cmdlet(VerbsCommon.Remove, NOUN_FILE)]   </span>
              </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="keyword">public</span>
              <span> </span>
              <span class="keyword">class</span>
              <span> RemoveFileCommand
: PSCmdlet, IDynamicParameters   </span>
            </li>
            <li class="alt">
              <span>{   </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">const</span>
              <span> </span>
              <span class="keyword">string</span>
              <span> NOUN_FILE     
= </span>
              <span class="string">"File"</span>
              <span>;   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">const</span>
              <span> </span>
              <span class="keyword">string</span>
              <span> SWITCH_FORCE  
= </span>
              <span class="string">"Force"</span>
              <span>;   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">readonly</span>
              <span> RuntimeDefinedParameterDictionary
_parameters;   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">public</span>
              <span> RemoveFileCommand()   </span>
            </li>
            <li class="">
              <span>    {   </span>
            </li>
            <li class="alt">
              <span>        _parameters = </span>
              <span class="keyword">new</span>
              <span> RuntimeDefinedParameterDictionary();   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="comment">// we
only want to add the -Force parameter if </span>
              <span>  </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="comment">// the
current user is an administrator </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>        var principal = </span>
              <span class="keyword">new</span>
              <span> WindowsPrincipal(WindowsIdentity.GetCurrent());   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="comment">// if
vista and not elevated, this will be false even </span>
              <span>  </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="comment">// if
you are a member of administrators. </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">if</span>
              <span> (principal.IsInRole(WindowsBuiltInRole.Administrator))   </span>
            </li>
            <li class="">
              <span>        {   </span>
            </li>
            <li class="alt">
              <span>            </span>
              <span class="keyword">this</span>
              <span>.AddDynamicParameter&lt;SwitchParameter&gt;(SWITCH_FORCE);   </span>
            </li>
            <li class="">
              <span>        }   </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    [Parameter]   </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">public</span>
              <span> </span>
              <span class="keyword">string</span>
              <span> FilePath   </span>
            </li>
            <li class="alt">
              <span>    {   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">get</span>
              <span>;   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">set</span>
              <span>;   </span>
            </li>
            <li class="">
              <span>    }    </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">protected</span>
              <span> </span>
              <span class="keyword">override</span>
              <span> </span>
              <span class="keyword">void</span>
              <span> EndProcessing()   </span>
            </li>
            <li class="alt">
              <span>    {   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="comment">// does
file exist? </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">if</span>
              <span> (File.Exists(FilePath))   </span>
            </li>
            <li class="">
              <span>        {   </span>
            </li>
            <li class="alt">
              <span>            RemoveFile();   </span>
            </li>
            <li class="">
              <span>        }   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">else</span>
              <span>  </span>
            </li>
            <li class="">
              <span>        {   </span>
            </li>
            <li class="alt">
              <span>            WriteWarning(FilePath
+ </span>
              <span class="string">" does not exist."</span>
              <span>);   </span>
            </li>
            <li class="">
              <span>        }   </span>
            </li>
            <li class="alt">
              <span>    }  </span>
            </li>
          </ol>
        </div>
        <p>
This is a simple piece of code who’s role is to remove the file specified by the user.
I’ve omitted the actual code that would delete the file for brevity. I’m using another
helper method to see if the –Force parameter has been added to the Cmdlet’s definition,
and if so, was it specified by the invoker of the Cmdlet. The idea is here is that
the Cmdlet will not remove the file if it’s marked Read-Only, but if –Force is specified
it <em>will</em> remove the R/O attribute and continue as planned. 
</p>
        <div class="dp-highlighter" id="hlDiv">
          <div class="bar">
          </div>
          <ol class="dp-c">
            <li class="alt">
              <span>
                <span class="keyword">private</span>
                <span> </span>
                <span class="keyword">void</span>
                <span> RemoveFile()   </span>
              </span>
            </li>
            <li class="">
              <span>{   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment">// read file attributes </span>
              <span>  </span>
            </li>
            <li class="">
              <span>    var attribs = File.GetAttributes(FilePath);   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="comment">// is read-only attribute set? </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">if</span>
              <span> ((attribs &amp;
FileAttributes.ReadOnly) == FileAttributes.ReadOnly)   </span>
            </li>
            <li class="">
              <span>    {   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">bool</span>
              <span> shouldForce;   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="comment">// see
if the dynamic switch -Force was added (and specified) </span>
              <span>  </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">if</span>
              <span> (TryGetSwitchParameter(SWITCH_FORCE, </span>
              <span class="keyword">out</span>
              <span> shouldForce))   </span>
            </li>
            <li class="alt">
              <span>        {   </span>
            </li>
            <li class="">
              <span>            WriteVerbose(</span>
              <span class="string">"Force.IsPresent:
"</span>
              <span> + shouldForce);   </span>
            </li>
            <li class="alt">
              <span>        }   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">if</span>
              <span> (shouldForce)   </span>
            </li>
            <li class="">
              <span>        {   </span>
            </li>
            <li class="alt">
              <span>            RemoveReadOnlyAttribute();   </span>
            </li>
            <li class="">
              <span>        }   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">else</span>
              <span>  </span>
            </li>
            <li class="">
              <span>        {   </span>
            </li>
            <li class="alt">
              <span>            WriteWarning(FilePath
+ </span>
              <span class="string">" is marked Read-Only!"</span>
              <span>);   </span>
            </li>
            <li class="">
              <span>            </span>
              <span class="keyword">return</span>
              <span>;   </span>
            </li>
            <li class="alt">
              <span>        }   </span>
            </li>
            <li class="">
              <span>    }   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="comment">// ... code to remove file ... </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>}  </span>
            </li>
          </ol>
        </div>
        <p>
And the final piece is here. The first method GetDynamicParameters, belongs to the
IDynamicParameters interface and tells PowerShell that the Cmdlet may return extra
parameters not defined on the class itself. In this case, we are returning a RuntimeDefinedParameterDictionary
instead of a <a href="http://www.nivot.org/2008/12/02/Quickstart2DynamicParameters1Of3StaticallyDefinedParameters.aspx" target="_blank">statically
defined parameters on a nested class</a>. 
</p>
        <div class="dp-highlighter" id="hlDiv">
          <div class="bar">
          </div>
          <ol class="dp-c">
            <li class="alt">
              <span>
                <span class="keyword">public</span>
                <span> </span>
                <span class="keyword">object</span>
                <span> GetDynamicParameters()   </span>
              </span>
            </li>
            <li class="">
              <span>{   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">return</span>
              <span> _parameters;   </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment">// add a simple parameter of type T to this cmdlet </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">void</span>
              <span> AddDynamicParameter&lt;T&gt;(</span>
              <span class="keyword">string</span>
              <span> name)   </span>
            </li>
            <li class="">
              <span>{   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment">// create a parameter of type
T. </span>
              <span>  </span>
            </li>
            <li class="">
              <span>    var parameter = </span>
              <span class="keyword">new</span>
              <span> RuntimeDefinedParameter   </span>
            </li>
            <li class="alt">
              <span>                   
{   </span>
            </li>
            <li class="">
              <span>                       
Name = name,   </span>
            </li>
            <li class="alt">
              <span>                       
ParameterType = </span>
              <span class="keyword">typeof</span>
              <span> (T),                                   </span>
            </li>
            <li class="">
              <span>                   
};   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="comment">// add the [parameter] attribute </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    var attrib = </span>
              <span class="keyword">new</span>
              <span> ParameterAttribute   </span>
            </li>
            <li class="">
              <span>                
{                                </span>
            </li>
            <li class="alt">
              <span>                    
ParameterSetName =   </span>
            </li>
            <li class="">
              <span>                       
ParameterAttribute.AllParameterSets   </span>
            </li>
            <li class="alt">
              <span>                
};   </span>
            </li>
            <li class="">
              <span>       </span>
            </li>
            <li class="alt">
              <span>    parameter.Attributes.Add(attrib);   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    _parameters.Add(name, parameter);   </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">bool</span>
              <span> TryGetSwitchParameter(</span>
              <span class="keyword">string</span>
              <span> name, </span>
              <span class="keyword">out</span>
              <span> </span>
              <span class="keyword">bool</span>
              <span> isPresent)   </span>
            </li>
            <li class="alt">
              <span>{   </span>
            </li>
            <li class="">
              <span>    RuntimeDefinedParameter parameter;   </span>
            </li>
            <li class="alt">
              <span>       </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">if</span>
              <span> (TryGetDynamicParameter(name, </span>
              <span class="keyword">out</span>
              <span> parameter))   </span>
            </li>
            <li class="alt">
              <span>    {   </span>
            </li>
            <li class="">
              <span>        isPresent = parameter.IsSet;   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">return</span>
              <span> </span>
              <span class="keyword">true</span>
              <span>;   </span>
            </li>
            <li class="">
              <span>    }   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    isPresent = </span>
              <span class="keyword">false</span>
              <span>;   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">return</span>
              <span> </span>
              <span class="keyword">false</span>
              <span>;   </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment">// get a parameter of type T. </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">bool</span>
              <span> TryGetParameter&lt;T&gt;(</span>
              <span class="keyword">string</span>
              <span> name, </span>
              <span class="keyword">out</span>
              <span> T
value)   </span>
            </li>
            <li class="">
              <span>{   </span>
            </li>
            <li class="alt">
              <span>    RuntimeDefinedParameter parameter;   </span>
            </li>
            <li class="">
              <span>       </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">if</span>
              <span> (TryGetDynamicParameter(name, </span>
              <span class="keyword">out</span>
              <span> parameter))   </span>
            </li>
            <li class="">
              <span>    {   </span>
            </li>
            <li class="alt">
              <span>        value = (T)parameter.Value;   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">return</span>
              <span> </span>
              <span class="keyword">true</span>
              <span>;   </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    value = </span>
              <span class="keyword">default</span>
              <span>(T);   </span>
            </li>
            <li class="">
              <span>       </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">return</span>
              <span> </span>
              <span class="keyword">false</span>
              <span>;   </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment">// try to get a dynamically added parameter </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">bool</span>
              <span> TryGetDynamicParameter(</span>
              <span class="keyword">string</span>
              <span> name, </span>
              <span class="keyword">out</span>
              <span> RuntimeDefinedParameter
value)   </span>
            </li>
            <li class="">
              <span>{   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">if</span>
              <span> (_parameters.ContainsKey(name))   </span>
            </li>
            <li class="">
              <span>    {   </span>
            </li>
            <li class="alt">
              <span>        value = _parameters[name];   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">return</span>
              <span> </span>
              <span class="keyword">true</span>
              <span>;   </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment">// need to set this before leaving
the method </span>
              <span>  </span>
            </li>
            <li class="">
              <span>    value = </span>
              <span class="keyword">null</span>
              <span>;   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">return</span>
              <span> </span>
              <span class="keyword">false</span>
              <span>;   </span>
            </li>
            <li class="alt">
              <span>}   </span>
            </li>
          </ol>
        </div>
        <p>
Finally, the three helper methods are revealed. One is used for checking for dynamic
SwitchParameters, the next is for ordinary parameters that return type T, the generic
argument. The third method, TryGetDynamicParameter is used by the first two methods. 
</p>
        <p>
I hope this helps reveal some of the mystery behind dynamic parameters on Cmdlets.
There is one more type of dynamic parameter that I will be examining in one of my
next few posts, that is the scenario where a provider (like the FileSystemProvider
or RegistryProvider) passes a dynamic parameter to a Cmdlet. In this particular case,
the provider can only pass dynamic parameters to the built-in Cmdlets that operate
on providers, e.g. Get-ChildItem, Get-Item, Get-ItemProperty etc.
</p>
        <p>
Have fun!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=f18d408c-6381-446a-aa62-e5751a432ccb" />
      </body>
      <title>Quickstart #3: Dynamic Parameters 2 of 3 – Runtime Defined Parameters</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,f18d408c-6381-446a-aa62-e5751a432ccb.aspx</guid>
      <link>http://www.nivot.org/2008/12/21/Quickstart3DynamicParameters2Of3RuntimeDefinedParameters.aspx</link>
      <pubDate>Sun, 21 Dec 2008 22:28:27 GMT</pubDate>
      <description>&lt;p&gt;
This time around, I thought I’d show how to work with programmatically generated dynamic
parameters, as opposed to the statically defined sets we saw the last time. The context
here is a fairly silly Cmdlet, but it’s good enough to demonstrate the concept end
to end. It’s a Cmdlet for removing a file. It takes one string parameter which is
the path to the file. The dynamic parameter I’m going to add is a –Force parameter.
The trick is, this parameter will only be added if the current user is an administrator
(XP), or is elevated as one (Vista). 
&lt;/p&gt;
&lt;p&gt;
This first portion of the Cmdlet defines the usual stuff like a verb and noun. This
time though, I’m using a regular class constructor. It’s not often you see constructors
in simple Cmdlets because typically all one would usually do is override one or more
of the three processing methods BeginProcessing, ProcessRecord and EndProcessing.
In this case, I need to create a instance of a “&lt;a href="http://msdn.microsoft.com/en-us/library/system.management.automation.runtimedefinedparameterdictionary(VS.85).aspx" target="_blank"&gt;RuntimeDefinedParameterDictionary&lt;/a&gt;,”
which does exactly what it says on the tin. It’s a dictionary of parameters, the key
being a string (the name of the parameter) and the value being a instance of a RuntimeDefinedParameter
class. These classes are all members of the System.Management.Automation namespace. 
&lt;/p&gt;
&lt;p&gt;
In the constructor, I’m calling a generic method defined as AddDynamicParameter&amp;lt;T&amp;gt;(string
name). This is only called if the current user is an admin. I’ve defined three generic
helper methods which you can see a little further down below.
&lt;/p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet"&gt;
&lt;!-- Code --&gt;
&lt;div class="dp-highlighter" id="hlDiv"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-c"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span&gt;[Cmdlet(VerbsCommon.Remove, NOUN_FILE)]&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt; RemoveFileCommand
: PSCmdlet, IDynamicParameters&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;{&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;const&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; NOUN_FILE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
= &lt;/span&gt;&lt;span class="string"&gt;"File"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;const&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; SWITCH_FORCE&amp;nbsp;&amp;nbsp;
= &lt;/span&gt;&lt;span class="string"&gt;"Force"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;readonly&lt;/span&gt;&lt;span&gt; RuntimeDefinedParameterDictionary
_parameters;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt; RemoveFileCommand()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _parameters = &lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; RuntimeDefinedParameterDictionary();&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// we
only want to add the -Force parameter if &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// the
current user is an administrator &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var principal = &lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; WindowsPrincipal(WindowsIdentity.GetCurrent());&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// if
vista and not elevated, this will be false even &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// if
you are a member of administrators. &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (principal.IsInRole(WindowsBuiltInRole.Administrator))&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;this&lt;/span&gt;&lt;span&gt;.AddDynamicParameter&amp;lt;SwitchParameter&amp;gt;(SWITCH_FORCE);&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Parameter]&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; FilePath&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;get&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;set&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt; EndProcessing()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// does
file exist? &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (File.Exists(FilePath))&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RemoveFile();&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WriteWarning(FilePath
+ &lt;/span&gt;&lt;span class="string"&gt;" does not exist."&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
This is a simple piece of code who’s role is to remove the file specified by the user.
I’ve omitted the actual code that would delete the file for brevity. I’m using another
helper method to see if the –Force parameter has been added to the Cmdlet’s definition,
and if so, was it specified by the invoker of the Cmdlet. The idea is here is that
the Cmdlet will not remove the file if it’s marked Read-Only, but if –Force is specified
it &lt;em&gt;will&lt;/em&gt; remove the R/O attribute and continue as planned. 
&lt;/p&gt;
&lt;div class="dp-highlighter" id="hlDiv"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-c"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt; RemoveFile()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;{&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// read file attributes &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var attribs = File.GetAttributes(FilePath);&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// is read-only attribute set? &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; ((attribs &amp;amp;
FileAttributes.ReadOnly) == FileAttributes.ReadOnly)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;bool&lt;/span&gt;&lt;span&gt; shouldForce;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// see
if the dynamic switch -Force was added (and specified) &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (TryGetSwitchParameter(SWITCH_FORCE, &lt;/span&gt;&lt;span class="keyword"&gt;out&lt;/span&gt;&lt;span&gt; shouldForce))&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WriteVerbose(&lt;/span&gt;&lt;span class="string"&gt;"Force.IsPresent:
"&lt;/span&gt;&lt;span&gt; + shouldForce);&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (shouldForce)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RemoveReadOnlyAttribute();&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WriteWarning(FilePath
+ &lt;/span&gt;&lt;span class="string"&gt;" is marked Read-Only!"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// ... code to remove file ... &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;}&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
And the final piece is here. The first method GetDynamicParameters, belongs to the
IDynamicParameters interface and tells PowerShell that the Cmdlet may return extra
parameters not defined on the class itself. In this case, we are returning a RuntimeDefinedParameterDictionary
instead of a &lt;a href="http://www.nivot.org/2008/12/02/Quickstart2DynamicParameters1Of3StaticallyDefinedParameters.aspx" target="_blank"&gt;statically
defined parameters on a nested class&lt;/a&gt;. 
&lt;/p&gt;
&lt;div class="dp-highlighter" id="hlDiv"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-c"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;object&lt;/span&gt;&lt;span&gt; GetDynamicParameters()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;{&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt; _parameters;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;// add a simple parameter of type T to this cmdlet &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt; AddDynamicParameter&amp;lt;T&amp;gt;(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; name)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;{&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// create a parameter of type
T. &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var parameter = &lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; RuntimeDefinedParameter&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
{&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Name = name,&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ParameterType = &lt;/span&gt;&lt;span class="keyword"&gt;typeof&lt;/span&gt;&lt;span&gt; (T),&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
};&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// add the [parameter] attribute &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var attrib = &lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; ParameterAttribute&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ParameterSetName =&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ParameterAttribute.AllParameterSets&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
};&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; parameter.Attributes.Add(attrib);&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _parameters.Add(name, parameter);&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;bool&lt;/span&gt;&lt;span&gt; TryGetSwitchParameter(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; name, &lt;/span&gt;&lt;span class="keyword"&gt;out&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;bool&lt;/span&gt;&lt;span&gt; isPresent)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;{&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RuntimeDefinedParameter parameter;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (TryGetDynamicParameter(name, &lt;/span&gt;&lt;span class="keyword"&gt;out&lt;/span&gt;&lt;span&gt; parameter))&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; isPresent = parameter.IsSet;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;true&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; isPresent = &lt;/span&gt;&lt;span class="keyword"&gt;false&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;false&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;// get a parameter of type T. &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;bool&lt;/span&gt;&lt;span&gt; TryGetParameter&amp;lt;T&amp;gt;(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; name, &lt;/span&gt;&lt;span class="keyword"&gt;out&lt;/span&gt;&lt;span&gt; T
value)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;{&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RuntimeDefinedParameter parameter;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (TryGetDynamicParameter(name, &lt;/span&gt;&lt;span class="keyword"&gt;out&lt;/span&gt;&lt;span&gt; parameter))&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = (T)parameter.Value;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;true&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = &lt;/span&gt;&lt;span class="keyword"&gt;default&lt;/span&gt;&lt;span&gt;(T);&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;false&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;// try to get a dynamically added parameter &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;bool&lt;/span&gt;&lt;span&gt; TryGetDynamicParameter(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; name, &lt;/span&gt;&lt;span class="keyword"&gt;out&lt;/span&gt;&lt;span&gt; RuntimeDefinedParameter
value)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;{&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (_parameters.ContainsKey(name))&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = _parameters[name];&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;true&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;// need to set this before leaving
the method &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = &lt;/span&gt;&lt;span class="keyword"&gt;null&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;false&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
Finally, the three helper methods are revealed. One is used for checking for dynamic
SwitchParameters, the next is for ordinary parameters that return type T, the generic
argument. The third method, TryGetDynamicParameter is used by the first two methods. 
&lt;/p&gt;
&lt;p&gt;
I hope this helps reveal some of the mystery behind dynamic parameters on Cmdlets.
There is one more type of dynamic parameter that I will be examining in one of my
next few posts, that is the scenario where a provider (like the FileSystemProvider
or RegistryProvider) passes a dynamic parameter to a Cmdlet. In this particular case,
the provider can only pass dynamic parameters to the built-in Cmdlets that operate
on providers, e.g. Get-ChildItem, Get-Item, Get-ItemProperty etc.
&lt;/p&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=f18d408c-6381-446a-aa62-e5751a432ccb" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,f18d408c-6381-446a-aa62-e5751a432ccb.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>Providers</category>
      <category>SnapIns</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=1a659290-6c82-444d-83d7-89e9e16911dc</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,1a659290-6c82-444d-83d7-89e9e16911dc.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,1a659290-6c82-444d-83d7-89e9e16911dc.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=1a659290-6c82-444d-83d7-89e9e16911dc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The dynamic duo / masterminds of PowerShell will be cornered and fiercely grilled
by none other than our very own master podcaster, Hal Rottenberg this Thursday. 
From the mouth of the suffixed one himself: 
</p>
        <blockquote>
          <p>
Coming up on the PowerScripting Live show this Thursday will be Jeffrey Snover, 
<br />
the architect for PowerShell as I’m sure you all know, and he’ll be accompanied 
<br />
by none other than Bruce Payette, author of PowerShell in Action and a core 
<br />
developer on the PowerShell team. 
</p>
          <p>
We’re excited and we hope you can make it this Thursday at 9pm EST! 
</p>
          <p>
The live stream address is <a href="http://www.ustream.tv/channel/powerscripting-podcast">http://www.ustream.tv/channel/powerscripting-podcast</a></p>
        </blockquote>
        <p>
So if you want to get the lowdown on CTP3 (maybe), join us, the unwashed masses as
we clamour to be near our idols. A lock of their hair and a signed discarded printout
of directions to building 18 could be yours! 
</p>
        <p>
I made that last bit up. Who cares! This is going to be cool! Join us! <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=1a659290-6c82-444d-83d7-89e9e16911dc" /></p>
      </body>
      <title>PowerScripting Podcast: The Big Two</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,1a659290-6c82-444d-83d7-89e9e16911dc.aspx</guid>
      <link>http://www.nivot.org/2008/12/15/PowerScriptingPodcastTheBigTwo.aspx</link>
      <pubDate>Mon, 15 Dec 2008 21:14:40 GMT</pubDate>
      <description>&lt;p&gt;
The dynamic duo / masterminds of PowerShell will be cornered and fiercely grilled
by none other than our very own master podcaster, Hal Rottenberg this Thursday.&amp;nbsp;
From the mouth of the suffixed one himself: 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Coming up on the PowerScripting Live show this Thursday will be Jeffrey Snover, 
&lt;br&gt;
the architect for PowerShell as I’m sure you all know, and he’ll be accompanied 
&lt;br&gt;
by none other than Bruce Payette, author of PowerShell in Action and a core 
&lt;br&gt;
developer on the PowerShell team. 
&lt;p&gt;
We’re excited and we hope you can make it this Thursday at 9pm EST! 
&lt;p&gt;
The live stream address is &lt;a href="http://www.ustream.tv/channel/powerscripting-podcast"&gt;http://www.ustream.tv/channel/powerscripting-podcast&lt;/a&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
So if you want to get the lowdown on CTP3 (maybe), join us, the unwashed masses as
we clamour to be near our idols. A lock of their hair and a signed discarded printout
of directions to building 18 could be yours! 
&lt;p&gt;
I made that last bit up. Who cares! This is going to be cool! Join us! &lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=1a659290-6c82-444d-83d7-89e9e16911dc" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,1a659290-6c82-444d-83d7-89e9e16911dc.aspx</comments>
      <category>.NET</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=25c5913c-39b3-4269-8264-69e9e42f3bd9</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,25c5913c-39b3-4269-8264-69e9e42f3bd9.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,25c5913c-39b3-4269-8264-69e9e42f3bd9.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=25c5913c-39b3-4269-8264-69e9e42f3bd9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Now this is cool. I’ve always wanted to try out TDD, but as I’m primarily a SharePoint
developer, a lot of the time my code is written on my laptop running XP, so I can’t
actually test anything since SharePoint won’t install there. The folks at Bamboo Solutions
came up with some clever hacks to get WSS 3.0 and MOSS running on Vista, but it’s
a bit of a heavyweight solution, especially when you consider this:
</p>
        <blockquote>
          <p>
Typemock are offering their new product for <a href="http://www.typemock.com/sharepointpage.php?utm_source=sp_bb&amp;utm_medium=blog_4sp&amp;utm_campaign=sp_bb">unit
testing SharePoint</a> called Isolator For SharePoint, for a special introduction
price. it is the only tool that allows you to <a href="http://blog.typemock.com/2008/11/newisolatorforsharepointtoolforunittest.html?utm_source=typeblog&amp;utm_medium=sp_bb&amp;utm_campaign=typeblog">unit
test SharePoint</a> without a SharePoint server. To learn more <a href="http://www.typemock.com/sharepointpage.php?utm_source=sp_bb&amp;utm_medium=blog_4sp&amp;utm_campaign=sp_bb">click
here</a>. 
</p>
          <p>
            <strike>
              <strong>The first 50 bloggers </strong>who blog this text in their blog and
tell us about it, will get a Full Isolator license, Free. for rules and info </strike>
            <a href="http://blog.typemock.com/2008/11/newisolatorforsharepointtoolforunittest.html">
              <strike>click
here</strike>
            </a>
            <strike>.</strike>
          </p>
        </blockquote>
        <p>
Unfortunately the competition is actually over, but it’s still worth a peek! <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=25c5913c-39b3-4269-8264-69e9e42f3bd9" /></p>
      </body>
      <title>Unit Testing SharePoint Code without SharePoint</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,25c5913c-39b3-4269-8264-69e9e42f3bd9.aspx</guid>
      <link>http://www.nivot.org/2008/12/14/UnitTestingSharePointCodeWithoutSharePoint.aspx</link>
      <pubDate>Sun, 14 Dec 2008 23:58:36 GMT</pubDate>
      <description>&lt;p&gt;
Now this is cool. I’ve always wanted to try out TDD, but as I’m primarily a SharePoint
developer, a lot of the time my code is written on my laptop running XP, so I can’t
actually test anything since SharePoint won’t install there. The folks at Bamboo Solutions
came up with some clever hacks to get WSS 3.0 and MOSS running on Vista, but it’s
a bit of a heavyweight solution, especially when you consider this:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Typemock are offering their new product for &lt;a href="http://www.typemock.com/sharepointpage.php?utm_source=sp_bb&amp;amp;utm_medium=blog_4sp&amp;amp;utm_campaign=sp_bb"&gt;unit
testing SharePoint&lt;/a&gt; called Isolator For SharePoint, for a special introduction
price. it is the only tool that allows you to &lt;a href="http://blog.typemock.com/2008/11/newisolatorforsharepointtoolforunittest.html?utm_source=typeblog&amp;amp;utm_medium=sp_bb&amp;amp;utm_campaign=typeblog"&gt;unit
test SharePoint&lt;/a&gt; without a SharePoint server. To learn more &lt;a href="http://www.typemock.com/sharepointpage.php?utm_source=sp_bb&amp;amp;utm_medium=blog_4sp&amp;amp;utm_campaign=sp_bb"&gt;click
here&lt;/a&gt;. 
&lt;p&gt;
&lt;strike&gt;&lt;strong&gt;The first 50 bloggers &lt;/strong&gt;who blog this text in their blog and
tell us about it, will get a Full Isolator license, Free. for rules and info &lt;/strike&gt;&lt;a href="http://blog.typemock.com/2008/11/newisolatorforsharepointtoolforunittest.html"&gt;&lt;strike&gt;click
here&lt;/strike&gt;&lt;/a&gt;&lt;strike&gt;.&lt;/strike&gt; 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Unfortunately the competition is actually over, but it’s still worth a peek! &lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=25c5913c-39b3-4269-8264-69e9e42f3bd9" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,25c5913c-39b3-4269-8264-69e9e42f3bd9.aspx</comments>
      <category>.NET</category>
      <category>MOSS</category>
      <category>SharePoint</category>
      <category>TDD</category>
      <category>WSS</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=d447c284-125a-4b58-9893-dda0aabde494</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,d447c284-125a-4b58-9893-dda0aabde494.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,d447c284-125a-4b58-9893-dda0aabde494.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=d447c284-125a-4b58-9893-dda0aabde494</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Normally parameters for a Cmdlet are defined directly as properties on the Cmdlet
class itself. There are a few other ways for a Cmdlet to define parameters, and in
this short series of three parts, I’ll cover the three variants you’ll likely to encounter
as you become a more experienced PowerShell developer. First thing you need to do
is to implement the System.Management.Automation.IDynamicParameters interface on your
Cmdlet. This interface has one member, GetDynamicParameters. This interface can be
implemented on either a Provider or a Cmdlet. In the former case, a provider is able
to add new parameters at runtime to certain built-in Cmdlets like Get-ChildItem, Get-Item
&amp; Get-ItemProperty. It is typically used in a path context-aware manner – e.g.
depending on whether the current argument is a folder or item, and what Type such
a folder or item might be. We’re just to cover the Cmdlet variant in this post.
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/QuickstartDynamicParameters1of3Staticall_ED7E/image_2.png">
            <img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="285" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/QuickstartDynamicParameters1of3Staticall_ED7E/image_thumb.png" width="640" border="0" />
          </a>
        </p>
        <p>
My example is just a simple Cmdlet named Get-OSVersion. It writes out Environment.OSVersion
to the pipeline, and will dynamically add a parameter. It adds –EnsureElevated if
you’re running Vista or higher, otherwise it will add –EnsureAdministrator. Statically
defined dynamic parameter sets are defined by creating a simple class and decorating
that class with parameter/properties you want to surface as if that class was the
Cmdlet itself, then returning it from the GetDynamicProperties method at runtime.
Simple! 
</p>
        <!-- Stylesheet link -->
        <link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" rel="stylesheet" type="text/css" />
        <!-- Code -->
        <div class="dp-highlighter" id="hlDiv">
          <div class="bar">
          </div>
          <ol class="dp-c">
            <li class="alt">
              <span>
                <span>[Cmdlet(VerbsCommon.Get, </span>
                <span class="string">"OSVersion"</span>
                <span>)]
  </span>
              </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="keyword">public</span>
              <span> </span>
              <span class="keyword">class</span>
              <span> GetOSVersionCommand : PSCmdlet, IDynamicParameters
  </span>
            </li>
            <li class="alt">
              <span>{   </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">const</span>
              <span> </span>
              <span class="keyword">string</span>
              <span> SWITCH_VISTA = </span>
              <span class="string">"EnsureElevated"</span>
              <span>;
  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">const</span>
              <span> </span>
              <span class="keyword">string</span>
              <span> SWITCH_WINXP = </span>
              <span class="string">"EnsureAdministrator"</span>
              <span>;
  </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">protected</span>
              <span> </span>
              <span class="keyword">override</span>
              <span> </span>
              <span class="keyword">void</span>
              <span> EndProcessing()
  </span>
            </li>
            <li class="">
              <span>    {   </span>
            </li>
            <li class="alt">
              <span>        WriteObject(Environment.OSVersion);
  </span>
            </li>
            <li class="">
              <span>           </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">string</span>
              <span> switchName = IsVistaOrHigher() ?
  </span>
            </li>
            <li class="">
              <span>            SWITCH_VISTA : SWITCH_WINXP;
  </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="comment">// not really a warning, just nice yellow text. </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>        WriteWarning(String.Format(</span>
              <span class="string">"{0}.IsPresent {1}"</span>
              <span>,
  </span>
            </li>
            <li class="">
              <span>            switchName, IsSwitchPresent(switchName)));
  </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment">// IDynamicParameters.GetDynamicParameters </span>
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">public</span>
              <span> </span>
              <span class="keyword">object</span>
              <span> GetDynamicParameters()
  </span>
            </li>
            <li class="alt">
              <span>    {   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">if</span>
              <span> (IsVistaOrHigher())
  </span>
            </li>
            <li class="alt">
              <span>        {   </span>
            </li>
            <li class="">
              <span>            </span>
              <span class="keyword">return</span>
              <span> </span>
              <span class="keyword">new</span>
              <span> VistaParameters();
  </span>
            </li>
            <li class="alt">
              <span>        }   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">else</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>        {   </span>
            </li>
            <li class="">
              <span>            </span>
              <span class="keyword">return</span>
              <span> </span>
              <span class="keyword">new</span>
              <span> WinXPParameters();
  </span>
            </li>
            <li class="alt">
              <span>        }   </span>
            </li>
            <li class="">
              <span>    }   </span>
            </li>
            <li class="alt">
              <span>       </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">bool</span>
              <span> IsSwitchPresent(</span>
              <span class="keyword">string</span>
              <span> name)
  </span>
            </li>
            <li class="alt">
              <span>    {   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="comment">// parameters bound at runtime </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>        Dictionary&lt;</span>
              <span class="keyword">string</span>
              <span>, </span>
              <span class="keyword">object</span>
              <span>&gt; parameters = MyInvocation.BoundParameters;
  </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="comment">// determine whether switch is set </span>
              <span>  </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">if</span>
              <span> (parameters.ContainsKey(name))
  </span>
            </li>
            <li class="alt">
              <span>        {   </span>
            </li>
            <li class="">
              <span>            </span>
              <span class="keyword">return</span>
              <span> ((SwitchParameter) parameters[name]).IsPresent;
  </span>
            </li>
            <li class="alt">
              <span>        }   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">return</span>
              <span> </span>
              <span class="keyword">false</span>
              <span>;
  </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">private</span>
              <span> </span>
              <span class="keyword">static</span>
              <span> </span>
              <span class="keyword">bool</span>
              <span> IsVistaOrHigher()
  </span>
            </li>
            <li class="">
              <span>    {   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">return</span>
              <span> (Environment.OSVersion.Version.Major &gt;= 6);
  </span>
            </li>
            <li class="">
              <span>    }   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="comment">// dynamic parameters for Vista </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">internal</span>
              <span> </span>
              <span class="keyword">class</span>
              <span> VistaParameters
  </span>
            </li>
            <li class="">
              <span>    {   </span>
            </li>
            <li class="alt">
              <span>        [Parameter]   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">public</span>
              <span> SwitchParameter EnsureElevated
  </span>
            </li>
            <li class="alt">
              <span>        {   </span>
            </li>
            <li class="">
              <span>            </span>
              <span class="keyword">get</span>
              <span>; </span>
              <span class="keyword">set</span>
              <span>;
  </span>
            </li>
            <li class="alt">
              <span>        }   </span>
            </li>
            <li class="">
              <span>    }   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="comment">// dynamic parameters for Windows XP </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment">// (powershell won't run on windows 2000 ;-)) </span>
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">internal</span>
              <span> </span>
              <span class="keyword">class</span>
              <span> WinXPParameters
  </span>
            </li>
            <li class="alt">
              <span>    {   </span>
            </li>
            <li class="">
              <span>        [Parameter]   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="keyword">public</span>
              <span> SwitchParameter EnsureAdministrator
  </span>
            </li>
            <li class="">
              <span>        {   </span>
            </li>
            <li class="alt">
              <span>            </span>
              <span class="keyword">get</span>
              <span>; </span>
              <span class="keyword">set</span>
              <span>;
  </span>
            </li>
            <li class="">
              <span>        }   </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li class="">
              <span>}  </span>
            </li>
          </ol>
        </div>
        <p>
Of course, adding Dynamic Parameters is no good if you don’t know how to read them
back. In the code, you can see I’m using MyInvocation.BoundParameters to check if
the Switches have been set. 
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=d447c284-125a-4b58-9893-dda0aabde494" />
      </body>
      <title>Quickstart #2: Dynamic Parameters 1 of 3 – Statically Defined Parameters</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,d447c284-125a-4b58-9893-dda0aabde494.aspx</guid>
      <link>http://www.nivot.org/2008/12/02/Quickstart2DynamicParameters1Of3StaticallyDefinedParameters.aspx</link>
      <pubDate>Tue, 02 Dec 2008 22:21:10 GMT</pubDate>
      <description>&lt;p&gt;
Normally parameters for a Cmdlet are defined directly as properties on the Cmdlet
class itself. There are a few other ways for a Cmdlet to define parameters, and in
this short series of three parts, I’ll cover the three variants you’ll likely to encounter
as you become a more experienced PowerShell developer. First thing you need to do
is to implement the System.Management.Automation.IDynamicParameters interface on your
Cmdlet. This interface has one member, GetDynamicParameters. This interface can be
implemented on either a Provider or a Cmdlet. In the former case, a provider is able
to add new parameters at runtime to certain built-in Cmdlets like Get-ChildItem, Get-Item
&amp;amp; Get-ItemProperty. It is typically used in a path context-aware manner – e.g.
depending on whether the current argument is a folder or item, and what Type such
a folder or item might be. We’re just to cover the Cmdlet variant in this post.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/QuickstartDynamicParameters1of3Staticall_ED7E/image_2.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="285" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/QuickstartDynamicParameters1of3Staticall_ED7E/image_thumb.png" width="640" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
My example is just a simple Cmdlet named Get-OSVersion. It writes out Environment.OSVersion
to the pipeline, and will dynamically add a parameter. It adds –EnsureElevated if
you’re running Vista or higher, otherwise it will add –EnsureAdministrator. Statically
defined dynamic parameter sets are defined by creating a simple class and decorating
that class with parameter/properties you want to surface as if that class was the
Cmdlet itself, then returning it from the GetDynamicProperties method at runtime.
Simple! 
&lt;/p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" rel="stylesheet" type="text/css" /&gt;
&lt;!-- Code --&gt;
&lt;div class=dp-highlighter id=hlDiv&gt;
&lt;div class=bar&gt;
&lt;/div&gt;
&lt;ol class=dp-c&gt;
&lt;li class=alt&gt;
&lt;span&gt;&lt;span&gt;[Cmdlet(VerbsCommon.Get,&amp;nbsp;&lt;/span&gt;&lt;span class=string&gt;"OSVersion"&lt;/span&gt;&lt;span&gt;)]
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class=keyword&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;GetOSVersionCommand&amp;nbsp;:&amp;nbsp;PSCmdlet,&amp;nbsp;IDynamicParameters
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;const&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;SWITCH_VISTA&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class=string&gt;"EnsureElevated"&lt;/span&gt;&lt;span&gt;;
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;const&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;SWITCH_WINXP&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class=string&gt;"EnsureAdministrator"&lt;/span&gt;&lt;span&gt;;
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;protected&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;override&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;void&lt;/span&gt;&lt;span&gt;&amp;nbsp;EndProcessing()
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteObject(Environment.OSVersion);
&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;switchName&amp;nbsp;=&amp;nbsp;IsVistaOrHigher()&amp;nbsp;?
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SWITCH_VISTA&amp;nbsp;:&amp;nbsp;SWITCH_WINXP;
&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=comment&gt;//&amp;nbsp;not&amp;nbsp;really&amp;nbsp;a&amp;nbsp;warning,&amp;nbsp;just&amp;nbsp;nice&amp;nbsp;yellow&amp;nbsp;text. &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteWarning(String.Format(&lt;/span&gt;&lt;span class=string&gt;"{0}.IsPresent&amp;nbsp;{1}"&lt;/span&gt;&lt;span&gt;,
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switchName,&amp;nbsp;IsSwitchPresent(switchName)));
&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=comment&gt;//&amp;nbsp;IDynamicParameters.GetDynamicParameters &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;object&lt;/span&gt;&lt;span&gt;&amp;nbsp;GetDynamicParameters()
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(IsVistaOrHigher())
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;VistaParameters();
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;WinXPParameters();
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;bool&lt;/span&gt;&lt;span&gt;&amp;nbsp;IsSwitchPresent(&lt;/span&gt;&lt;span class=keyword&gt;string&lt;/span&gt;&lt;span&gt;&amp;nbsp;name)
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=comment&gt;//&amp;nbsp;parameters&amp;nbsp;bound&amp;nbsp;at&amp;nbsp;runtime &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dictionary&amp;lt;&lt;/span&gt;&lt;span class=keyword&gt;string&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;object&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;nbsp;parameters&amp;nbsp;=&amp;nbsp;MyInvocation.BoundParameters;
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=comment&gt;//&amp;nbsp;determine&amp;nbsp;whether&amp;nbsp;switch&amp;nbsp;is&amp;nbsp;set &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(parameters.ContainsKey(name))
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;((SwitchParameter)&amp;nbsp;parameters[name]).IsPresent;
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;false&lt;/span&gt;&lt;span&gt;;
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;private&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;bool&lt;/span&gt;&lt;span&gt;&amp;nbsp;IsVistaOrHigher()
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;(Environment.OSVersion.Version.Major&amp;nbsp;&amp;gt;=&amp;nbsp;6);
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=comment&gt;//&amp;nbsp;dynamic&amp;nbsp;parameters&amp;nbsp;for&amp;nbsp;Vista &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;internal&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;VistaParameters
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Parameter] &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;SwitchParameter&amp;nbsp;EnsureElevated
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;get&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;set&lt;/span&gt;&lt;span&gt;;
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=comment&gt;//&amp;nbsp;dynamic&amp;nbsp;parameters&amp;nbsp;for&amp;nbsp;Windows&amp;nbsp;XP &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=comment&gt;//&amp;nbsp;(powershell&amp;nbsp;won't&amp;nbsp;run&amp;nbsp;on&amp;nbsp;windows&amp;nbsp;2000&amp;nbsp;;-)) &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;internal&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;WinXPParameters
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Parameter] &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;SwitchParameter&amp;nbsp;EnsureAdministrator
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;get&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&lt;/span&gt;&lt;span class=keyword&gt;set&lt;/span&gt;&lt;span&gt;;
&amp;nbsp;&amp;nbsp;&lt;/span&gt;&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
Of course, adding Dynamic Parameters is no good if you don’t know how to read them
back. In the code, you can see I’m using MyInvocation.BoundParameters to check if
the Switches have been set. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=d447c284-125a-4b58-9893-dda0aabde494" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,d447c284-125a-4b58-9893-dda0aabde494.aspx</comments>
      <category>.NET</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>Vista</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=ff314040-e2e2-4237-bde6-15e8969c0a99</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,ff314040-e2e2-4237-bde6-15e8969c0a99.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,ff314040-e2e2-4237-bde6-15e8969c0a99.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=ff314040-e2e2-4237-bde6-15e8969c0a99</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It seems lots of people are catching the <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> bug
these days. People who previously considered themselves as administrators have learned
enough of the magic from using PowerShell from day to day over the last few months
that they feel comfortable enough to tinker around with C#. 
</p>
        <p>
This is an example Cmdlet skeleton that is designed to work with Files and Directories.
It looks after resolving wildcards, supports –WhatIf and –Confirm, accepting files
and/or directories from the pipeline or accepting strings of paths from the pipeine.
It also ensures that the only types of paths it can accept lie on the File System.
Here’s an example of the invocation styles it supports:
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Quickstart1ACmdletThatProcessesFilesandD_FCDC/cmdlet_2.png">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="cmdlet" border="0" alt="cmdlet" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Quickstart1ACmdletThatProcessesFilesandD_FCDC/cmdlet_thumb.png" width="537" height="480" />
          </a>
        </p>
        <p>
Here’s the source code for this. It doesn’t really do a lot. It spits out two different
types of custom objects: one for a file, and another for a directory. Feel free to
do what you like with it; it’s yours. Have fun.
</p>
        <pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px">
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">using</span> System; </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">using</span> System.Collections.Generic; </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">using</span> System.IO; </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">using</span> System.Management.Automation; </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">using</span> Microsoft.PowerShell.Commands; </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">namespace</span> PSQuickStart </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">{
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">    [Cmdlet(VerbsCommon.Get, Noun,
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        DefaultParameterSetName = ParmamSetPath,
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        SupportsShouldProcess = <span style="color: #0000ff">true</span>) </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">    ]
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> GetFileMetadataCommand
: PSCmdlet </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">    {
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">const</span>
            <span style="color: #0000ff">string</span> Noun
= "<span style="color: #8b0000">FileMetadata</span>"; </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">const</span>
            <span style="color: #0000ff">string</span> ParamSetLiteral
= "<span style="color: #8b0000">Literal</span>"; </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">const</span>
            <span style="color: #0000ff">string</span> ParmamSetPath
= "<span style="color: #8b0000">Path</span>"; </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">string</span>[]
_paths; </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">bool</span> _shouldExpandWildcards; </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        [Parameter(
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            Position = 0,
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            Mandatory = <span style="color: #0000ff">true</span>, </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            ValueFromPipeline = <span style="color: #0000ff">false</span>, </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            ValueFromPipelineByPropertyName = <span style="color: #0000ff">true</span>, </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            ParameterSetName = ParamSetLiteral)
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        ]
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        [Alias("<span style="color: #8b0000">PSPath</span>")] </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        [ValidateNotNullOrEmpty]
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">string</span>[]
LiteralPath </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        {
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span> _paths;
} </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">set</span> {
_paths = <span style="color: #0000ff">value</span>; } </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        [Parameter(
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            Position = 0,
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            Mandatory = <span style="color: #0000ff">true</span>, </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            ValueFromPipeline = <span style="color: #0000ff">true</span>, </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            ValueFromPipelineByPropertyName = <span style="color: #0000ff">true</span>, </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            ParameterSetName = ParmamSetPath)
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        ]
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        [ValidateNotNullOrEmpty]
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">string</span>[]
Path </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        {
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span> _paths;
} </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">set</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            {
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                _shouldExpandWildcards = <span style="color: #0000ff">true</span>; </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                _paths = <span style="color: #0000ff">value</span>; </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            }
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">protected</span>
            <span style="color: #0000ff">override</span>
            <span style="color: #0000ff">void</span> ProcessRecord() </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        {
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">foreach</span> (<span style="color: #0000ff">string</span> path <span style="color: #0000ff">in</span> _paths) </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            {
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
This will hold information about the provider containing</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
the items that this path string might resolve to. </span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                ProviderInfo provider;
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
This will be used by the method that processes literal paths</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                PSDriveInfo drive;
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
this contains the paths to process for this iteration of the</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
loop to resolve and optionally expand wildcards.</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                List&lt;<span style="color: #0000ff">string</span>&gt;
filePaths = <span style="color: #0000ff">new</span> List&lt;<span style="color: #0000ff">string</span>&gt;(); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">if</span> (_shouldExpandWildcards) </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                {
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
Turn *.txt into foo.txt,foo2.txt etc.</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
if path is just "foo.txt," it will return unchanged.</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                    filePaths.AddRange(<span style="color: #0000ff">this</span>.GetResolvedProviderPathFromPSPath(path, <span style="color: #0000ff">out</span> provider)); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">else</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                {
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
no wildcards, so don't try to expand any * or ? symbols. </span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                    filePaths.Add(<span style="color: #0000ff">this</span>.SessionState.Path.GetUnresolvedProviderPathFromPSPath( </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                        path, <span style="color: #0000ff">out</span> provider, <span style="color: #0000ff">out</span> drive)); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
ensure that this path (or set of paths after wildcard expansion)</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
is on the filesystem. A wildcard can never expand to span multiple</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
providers.</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">if</span> (IsFileSystemPath(provider,
path) == <span style="color: #0000ff">false</span>) </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                {
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
no, so skip to next path in _paths.</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">continue</span>; </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                }
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
at this point, we have a list of paths on the filesystem.</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">foreach</span> (<span style="color: #0000ff">string</span> filePath <span style="color: #0000ff">in</span> filePaths) </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                {
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                    PSObject custom;
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
If -whatif was supplied, do not perform the actions</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
inside this "if" statement; only show the message.</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
This block also supports the -confirm switch, where</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
you will be asked if you want to perform the action</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
"get metadata" on target: foo.txt</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">if</span> (ShouldProcess(filePath,
"<span style="color: #8b0000">Get Metadata</span>")) </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                    {
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">if</span> (Directory.Exists(filePath)) </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                        {
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                            custom = GetDirectoryCustomObject(<span style="color: #0000ff">new</span> DirectoryInfo(filePath)); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                        }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">else</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                        {
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                            custom = GetFileCustomObject(<span style="color: #0000ff">new</span> FileInfo(filePath)); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                        }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                        WriteObject(custom);
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                    }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                }
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        }
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">private</span> PSObject
GetFileCustomObject(FileInfo file) </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        {
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
this message will be shown if the -verbose switch is given</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            WriteVerbose("<span style="color: #8b0000">GetFileCustomObject </span>"
+ file); </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
create a custom object with a few properties</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            PSObject custom = <span style="color: #0000ff">new</span> PSObject(); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            custom.Properties.Add(<span style="color: #0000ff">new</span> PSNoteProperty("<span style="color: #8b0000">Size</span>",
file.Length)); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            custom.Properties.Add(<span style="color: #0000ff">new</span> PSNoteProperty("<span style="color: #8b0000">Name</span>",
file.Name)); </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            custom.Properties.Add(<span style="color: #0000ff">new</span> PSNoteProperty("<span style="color: #8b0000">Extension</span>",
file.Extension)); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">return</span> custom; </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">private</span> PSObject
GetDirectoryCustomObject(DirectoryInfo dir) </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        {
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
this message will be shown if the -verbose switch is given</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            WriteVerbose("<span style="color: #8b0000">GetDirectoryCustomObject </span>"
+ dir); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
create a custom object with a few properties</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            PSObject custom = <span style="color: #0000ff">new</span> PSObject(); </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">int</span> files
= dir.GetFiles().Length; </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">int</span> subdirs
= dir.GetDirectories().Length; </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            custom.Properties.Add(<span style="color: #0000ff">new</span> PSNoteProperty("<span style="color: #8b0000">Files</span>",
files)); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            custom.Properties.Add(<span style="color: #0000ff">new</span> PSNoteProperty("<span style="color: #8b0000">Subdirectories</span>",
subdirs)); </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            custom.Properties.Add(<span style="color: #0000ff">new</span> PSNoteProperty("<span style="color: #8b0000">Name</span>",
dir.Name)); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">return</span> custom; </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">bool</span> IsFileSystemPath(ProviderInfo
provider, <span style="color: #0000ff">string</span> path) </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        {
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">bool</span> isFileSystem
= <span style="color: #0000ff">true</span>; </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
check that this provider is the filesystem</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">if</span> (provider.ImplementingType
!= <span style="color: #0000ff">typeof</span>(FileSystemProvider)) </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            {
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
create a .NET exception wrapping our error text</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                ArgumentException ex = <span style="color: #0000ff">new</span> ArgumentException(path
+ </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                    "<span style="color: #8b0000"> does
not resolve to a path on the FileSystem provider.</span>"); </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
wrap this in a powershell errorrecord</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                ErrorRecord error = <span style="color: #0000ff">new</span> ErrorRecord(ex,
"<span style="color: #8b0000">InvalidProvider</span>", </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                    ErrorCategory.InvalidArgument, path);
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
write a non-terminating error to pipeline</span>
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">this</span>.WriteError(error); </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #008000">//
tell our caller that the item was not on the filesystem</span>
          </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">                isFileSystem = <span style="color: #0000ff">false</span>; </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">            }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
            <span style="color: #0000ff">return</span> isFileSystem; </pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">        }
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">    }
</pre>
          <pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">}
</pre>
          <pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">
          </pre>
        </pre>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=ff314040-e2e2-4237-bde6-15e8969c0a99" />
      </body>
      <title>Quickstart #1 - A Cmdlet That Processes Files and Directories</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,ff314040-e2e2-4237-bde6-15e8969c0a99.aspx</guid>
      <link>http://www.nivot.org/2008/11/19/Quickstart1ACmdletThatProcessesFilesAndDirectories.aspx</link>
      <pubDate>Wed, 19 Nov 2008 22:58:18 GMT</pubDate>
      <description>&lt;p&gt;
It seems lots of people are catching the &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; bug
these days. People who previously considered themselves as administrators have learned
enough of the magic from using PowerShell from day to day over the last few months
that they feel comfortable enough to tinker around with C#. 
&lt;/p&gt;
&lt;p&gt;
This is an example Cmdlet skeleton that is designed to work with Files and Directories.
It looks after resolving wildcards, supports –WhatIf and –Confirm, accepting files
and/or directories from the pipeline or accepting strings of paths from the pipeine.
It also ensures that the only types of paths it can accept lie on the File System.
Here’s an example of the invocation styles it supports:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Quickstart1ACmdletThatProcessesFilesandD_FCDC/cmdlet_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="cmdlet" border="0" alt="cmdlet" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Quickstart1ACmdletThatProcessesFilesandD_FCDC/cmdlet_thumb.png" width="537" height="480"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Here’s the source code for this. It doesn’t really do a lot. It spits out two different
types of custom objects: one for a file, and another for a directory. Feel free to
do what you like with it; it’s yours. Have fun.
&lt;/p&gt;
&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.IO; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Management.Automation; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; Microsoft.PowerShell.Commands; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; PSQuickStart &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    [Cmdlet(VerbsCommon.Get, Noun,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        DefaultParameterSetName = ParmamSetPath,
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        SupportsShouldProcess = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;) &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ]
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; GetFileMetadataCommand
: PSCmdlet &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Noun
= "&lt;span style="color: #8b0000"&gt;FileMetadata&lt;/span&gt;"; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ParamSetLiteral
= "&lt;span style="color: #8b0000"&gt;Literal&lt;/span&gt;"; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ParmamSetPath
= "&lt;span style="color: #8b0000"&gt;Path&lt;/span&gt;"; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[]
_paths; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; _shouldExpandWildcards; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        [Parameter(
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Position = 0,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Mandatory = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            ValueFromPipeline = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;, &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            ValueFromPipelineByPropertyName = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            ParameterSetName = ParamSetLiteral)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        ]
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        [Alias("&lt;span style="color: #8b0000"&gt;PSPath&lt;/span&gt;")] &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        [ValidateNotNullOrEmpty]
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[]
LiteralPath &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _paths;
} &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt; {
_paths = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; } &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        [Parameter(
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Position = 0,
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Mandatory = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            ValueFromPipeline = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            ValueFromPipelineByPropertyName = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            ParameterSetName = ParmamSetPath)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        ]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        [ValidateNotNullOrEmpty]
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[]
Path &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _paths;
} &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                _shouldExpandWildcards = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                _paths = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ProcessRecord() &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; path &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; _paths) &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
This will hold information about the provider containing&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
the items that this path string might resolve to. &lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                ProviderInfo provider;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
This will be used by the method that processes literal paths&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                PSDriveInfo drive;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
this contains the paths to process for this iteration of the&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
loop to resolve and optionally expand wildcards.&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;
filePaths = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;(); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_shouldExpandWildcards) &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #008000"&gt;//
Turn *.txt into foo.txt,foo2.txt etc.&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #008000"&gt;//
if path is just "foo.txt," it will return unchanged.&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    filePaths.AddRange(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetResolvedProviderPathFromPSPath(path, &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; provider)); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #008000"&gt;//
no wildcards, so don't try to expand any * or ? symbols. &lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    filePaths.Add(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SessionState.Path.GetUnresolvedProviderPathFromPSPath( &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        path, &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; provider, &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; drive)); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
ensure that this path (or set of paths after wildcard expansion)&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
is on the filesystem. A wildcard can never expand to span multiple&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
providers.&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (IsFileSystemPath(provider,
path) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;) &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #008000"&gt;//
no, so skip to next path in _paths.&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #0000ff"&gt;continue&lt;/span&gt;; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
at this point, we have a list of paths on the filesystem.&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; filePath &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; filePaths) &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    PSObject custom;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #008000"&gt;//
If -whatif was supplied, do not perform the actions&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #008000"&gt;//
inside this "if" statement; only show the message.&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #008000"&gt;//&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #008000"&gt;//
This block also supports the -confirm switch, where&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #008000"&gt;//
you will be asked if you want to perform the action&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #008000"&gt;//
"get metadata" on target: foo.txt&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ShouldProcess(filePath,
"&lt;span style="color: #8b0000"&gt;Get Metadata&lt;/span&gt;")) &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Directory.Exists(filePath)) &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                            custom = GetDirectoryCustomObject(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DirectoryInfo(filePath)); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                            custom = GetFileCustomObject(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileInfo(filePath)); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        WriteObject(custom);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; PSObject
GetFileCustomObject(FileInfo file) &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;//
this message will be shown if the -verbose switch is given&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            WriteVerbose("&lt;span style="color: #8b0000"&gt;GetFileCustomObject &lt;/span&gt;"
+ file); &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;//
create a custom object with a few properties&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            PSObject custom = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PSObject(); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            custom.Properties.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PSNoteProperty("&lt;span style="color: #8b0000"&gt;Size&lt;/span&gt;",
file.Length)); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            custom.Properties.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PSNoteProperty("&lt;span style="color: #8b0000"&gt;Name&lt;/span&gt;",
file.Name)); &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            custom.Properties.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PSNoteProperty("&lt;span style="color: #8b0000"&gt;Extension&lt;/span&gt;",
file.Extension)); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; custom; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; PSObject
GetDirectoryCustomObject(DirectoryInfo dir) &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;//
this message will be shown if the -verbose switch is given&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            WriteVerbose("&lt;span style="color: #8b0000"&gt;GetDirectoryCustomObject &lt;/span&gt;"
+ dir); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;//
create a custom object with a few properties&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            PSObject custom = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PSObject(); &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; files
= dir.GetFiles().Length; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; subdirs
= dir.GetDirectories().Length; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            custom.Properties.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PSNoteProperty("&lt;span style="color: #8b0000"&gt;Files&lt;/span&gt;",
files)); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            custom.Properties.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PSNoteProperty("&lt;span style="color: #8b0000"&gt;Subdirectories&lt;/span&gt;",
subdirs)); &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            custom.Properties.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PSNoteProperty("&lt;span style="color: #8b0000"&gt;Name&lt;/span&gt;",
dir.Name)); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; custom; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsFileSystemPath(ProviderInfo
provider, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; path) &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; isFileSystem
= &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;//
check that this provider is the filesystem&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (provider.ImplementingType
!= &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(FileSystemProvider)) &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
create a .NET exception wrapping our error text&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                ArgumentException ex = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArgumentException(path
+ &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    "&lt;span style="color: #8b0000"&gt; does
not resolve to a path on the FileSystem provider.&lt;/span&gt;"); &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
wrap this in a powershell errorrecord&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                ErrorRecord error = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ErrorRecord(ex,
"&lt;span style="color: #8b0000"&gt;InvalidProvider&lt;/span&gt;", &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    ErrorCategory.InvalidArgument, path);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
write a non-terminating error to pipeline&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.WriteError(error); &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;//
tell our caller that the item was not on the filesystem&lt;/span&gt; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                isFileSystem = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;; &lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; isFileSystem; &lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=ff314040-e2e2-4237-bde6-15e8969c0a99" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,ff314040-e2e2-4237-bde6-15e8969c0a99.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=eb987998-0302-4577-83fb-0709c363ea88</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,eb987998-0302-4577-83fb-0709c363ea88.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,eb987998-0302-4577-83fb-0709c363ea88.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=eb987998-0302-4577-83fb-0709c363ea88</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Here’s just a quick rundown of the changes in <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> 2.0
in comparison to the last public release, CTP2. This may be helpful to those of you
who don’t have access to the Windows 7 PDC bits. <strong><font color="#d90000">Remember,
things are still subject to change - it’s not in beta yet.</font></strong></p>
        <p>
Unchanged cmdlets are not listed here.
</p>
        <table border="1" cellspacing="0" cellpadding="2" width="578">
          <tbody>
            <tr>
              <td valign="top" colspan="3">
                <p align="center">
                  <strong>Added (or renamed*) Cmdlets</strong>
                </p>
              </td>
            </tr>
            <tr>
              <td valign="top" width="206" nowrap="nowrap">
Enter-PSSession<br />
Remove-PSSession<br />
Get-PSSession<br />
Exit-PSSession<br />
Get-PSSessionConfiguration<br />
Unregister-PSSessionConfiguration<br />
Register-PSSessionConfiguration<br />
Debug-Process<br />
Test-ModuleManifest<br />
New-ModuleManifest<br />
New-WSManSessionOption<br />
New-PSSession<br />
Import-PSSession<br />
Export-PSSession<br />
Set-PSSessionConfiguration<br />
Get-WSManInstance<br />
Get-WSManCredSSP<br />
Enable-WSManCredSSP<br />
Set-WSManInstance<br />
Set-WSManQuickConfig<br />
New-WSManInstance<br />
Remove-WSManInstance</td>
              <td valign="top" width="187">
Ping-WSMan<br />
New-WebServiceProxy<br />
Get-PSTransaction<br />
Connect-WSMan<br />
Disable-WSManCredSSP<br />
Invoke-WSManAction<br />
Disconnect-WSMan<br />
Get-ComputerRestorePoint<br />
Disable-ComputerRestore<br />
Enable-ComputerRestore<br />
Get-Counter<br />
Clear-EventLog<br />
Export-Counter<br />
Import-Counter<br />
Checkpoint-Computer<br />
Restart-Computer<br />
Stop-Computer<br />
Ping-Computer<br /></td>
              <td valign="top" width="183">
Resume-BitsTransfer<br />
Set-BitsTransfer<br />
Suspend-BitsTransfer<br />
Add-BitsFile<br />
Clear-BitsTransfer<br />
Remove-EventLog<br />
Restore-Computer<br />
New-Module<br />
Get-HotFix<br />
Complete-BitsTransfer<br />
Write-EventLog<br />
Show-EventLog<br />
Limit-EventLog<br />
Get-BitsTransfer<br />
New-BitsTransfer<br />
New-EventLog</td>
            </tr>
            <tr>
              <td valign="top" colspan="3" align="middle">
                <p align="center">
                  <strong>Changed Cmdlets (parameter or parameterset differences)</strong>
                </p>
              </td>
            </tr>
            <tr>
              <td valign="top" width="206" nowrap="nowrap">
                <p>
Invoke-Command<br />
Receive-PSJob<br />
Set-WmiInstance<br />
Stop-PSJob<br />
Wait-PSJob<br />
Remove-PSJob<br />
Export-ModuleMember<br />
Start-PSJob<br />
Get-PSJob<br />
Add-Module<br />
Set-Service
</p>
              </td>
              <td valign="top" width="187">
 </td>
              <td valign="top" width="183">
 </td>
            </tr>
            <tr>
              <td valign="top" colspan="3">
                <p align="center">
                  <strong>Removed (or renamed*) Cmdlets</strong>
                </p>
              </td>
            </tr>
            <tr>
              <td valign="top" width="206" nowrap="nowrap">
                <p>
Pop-Runspace<br />
New-Runspace<br />
Push-Runspace<br />
Get-Runspace<br />
Remove-Runspace
</p>
              </td>
              <td valign="top" width="189">
 </td>
              <td valign="top" width="188">
 </td>
            </tr>
          </tbody>
        </table>
        <p>
* e.g. The *-Runspace Cmdlets have been renamed to *-PSSession
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=eb987998-0302-4577-83fb-0709c363ea88" />
      </body>
      <title>Changes from CTP2 in PowerShell 2.0 in the Windows 7 M3 “PDC” Build</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,eb987998-0302-4577-83fb-0709c363ea88.aspx</guid>
      <link>http://www.nivot.org/2008/11/14/ChangesFromCTP2InPowerShell20InTheWindows7M3PDCBuild.aspx</link>
      <pubDate>Fri, 14 Nov 2008 04:15:00 GMT</pubDate>
      <description>&lt;p&gt;
Here’s just a quick rundown of the changes in &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; 2.0
in comparison to the last public release, CTP2. This may be helpful to those of you
who don’t have access to the Windows 7 PDC bits. &lt;strong&gt;&lt;font color="#d90000"&gt;Remember,
things are still subject to change - it’s not in beta yet.&lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Unchanged cmdlets are not listed here.
&lt;/p&gt;
&lt;table border="1" cellspacing="0" cellpadding="2" width="578"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" colspan="3"&gt;
&lt;p align="center"&gt;
&lt;strong&gt;Added (or renamed*) Cmdlets&lt;/strong&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="206" nowrap&gt;
Enter-PSSession&lt;br&gt;
Remove-PSSession&lt;br&gt;
Get-PSSession&lt;br&gt;
Exit-PSSession&lt;br&gt;
Get-PSSessionConfiguration&lt;br&gt;
Unregister-PSSessionConfiguration&lt;br&gt;
Register-PSSessionConfiguration&lt;br&gt;
Debug-Process&lt;br&gt;
Test-ModuleManifest&lt;br&gt;
New-ModuleManifest&lt;br&gt;
New-WSManSessionOption&lt;br&gt;
New-PSSession&lt;br&gt;
Import-PSSession&lt;br&gt;
Export-PSSession&lt;br&gt;
Set-PSSessionConfiguration&lt;br&gt;
Get-WSManInstance&lt;br&gt;
Get-WSManCredSSP&lt;br&gt;
Enable-WSManCredSSP&lt;br&gt;
Set-WSManInstance&lt;br&gt;
Set-WSManQuickConfig&lt;br&gt;
New-WSManInstance&lt;br&gt;
Remove-WSManInstance&lt;/td&gt;
&lt;td valign="top" width="187"&gt;
Ping-WSMan&lt;br&gt;
New-WebServiceProxy&lt;br&gt;
Get-PSTransaction&lt;br&gt;
Connect-WSMan&lt;br&gt;
Disable-WSManCredSSP&lt;br&gt;
Invoke-WSManAction&lt;br&gt;
Disconnect-WSMan&lt;br&gt;
Get-ComputerRestorePoint&lt;br&gt;
Disable-ComputerRestore&lt;br&gt;
Enable-ComputerRestore&lt;br&gt;
Get-Counter&lt;br&gt;
Clear-EventLog&lt;br&gt;
Export-Counter&lt;br&gt;
Import-Counter&lt;br&gt;
Checkpoint-Computer&lt;br&gt;
Restart-Computer&lt;br&gt;
Stop-Computer&lt;br&gt;
Ping-Computer&lt;br&gt;
&lt;/td&gt;
&lt;td valign="top" width="183"&gt;
Resume-BitsTransfer&lt;br&gt;
Set-BitsTransfer&lt;br&gt;
Suspend-BitsTransfer&lt;br&gt;
Add-BitsFile&lt;br&gt;
Clear-BitsTransfer&lt;br&gt;
Remove-EventLog&lt;br&gt;
Restore-Computer&lt;br&gt;
New-Module&lt;br&gt;
Get-HotFix&lt;br&gt;
Complete-BitsTransfer&lt;br&gt;
Write-EventLog&lt;br&gt;
Show-EventLog&lt;br&gt;
Limit-EventLog&lt;br&gt;
Get-BitsTransfer&lt;br&gt;
New-BitsTransfer&lt;br&gt;
New-EventLog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" colspan="3" align="middle"&gt;
&lt;p align="center"&gt;
&lt;strong&gt;Changed Cmdlets (parameter or parameterset differences)&lt;/strong&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="206" nowrap&gt;
&lt;p&gt;
Invoke-Command&lt;br&gt;
Receive-PSJob&lt;br&gt;
Set-WmiInstance&lt;br&gt;
Stop-PSJob&lt;br&gt;
Wait-PSJob&lt;br&gt;
Remove-PSJob&lt;br&gt;
Export-ModuleMember&lt;br&gt;
Start-PSJob&lt;br&gt;
Get-PSJob&lt;br&gt;
Add-Module&lt;br&gt;
Set-Service
&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" width="187"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td valign="top" width="183"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" colspan="3"&gt;
&lt;p align="center"&gt;
&lt;strong&gt;Removed (or renamed*) Cmdlets&lt;/strong&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="206" nowrap&gt;
&lt;p&gt;
Pop-Runspace&lt;br&gt;
New-Runspace&lt;br&gt;
Push-Runspace&lt;br&gt;
Get-Runspace&lt;br&gt;
Remove-Runspace
&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="top" width="189"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td valign="top" width="188"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
* e.g. The *-Runspace Cmdlets have been renamed to *-PSSession
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=eb987998-0302-4577-83fb-0709c363ea88" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,eb987998-0302-4577-83fb-0709c363ea88.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>Windows 7</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=7618ad05-0d8e-47ad-8fe8-3de6189379ac</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,7618ad05-0d8e-47ad-8fe8-3de6189379ac.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,7618ad05-0d8e-47ad-8fe8-3de6189379ac.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=7618ad05-0d8e-47ad-8fe8-3de6189379ac</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’d say a lot of folks will be chomping at the bit for this. It’s the <a target="_blank" href="http://en.wikipedia.org/wiki/Tk_(framework)">Tk</a> to
PowerShell’s <a target="_blank" href="http://en.wikipedia.org/wiki/Tcl">Tcl</a> and
is really the final piece of the puzzle where the shell’s position as the de-facto
Windows Shell stands anyway. Well, maybe Remoting support for XP and Windows Server
2003 is ahead there just a bit, but a forms designer must be a close second. 
</p>
        <p>
Check it out: <a title="http://blog.sapien.com/index.php/2008/11/03/free-primalforms-tool-for-powershell-released/" href="http://blog.sapien.com/index.php/2008/11/03/free-primalforms-tool-for-powershell-released/">http://blog.sapien.com/index.php/2008/11/03/free-primalforms-tool-for-powershell-released/</a></p>
        <p>
Congratulations guys on shipping such a fine tool, for FREE. All it costs you is an
email address. Yah, sell your soul, it’ll be worth it.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=7618ad05-0d8e-47ad-8fe8-3de6189379ac" />
      </body>
      <title>Sapien PrimalForms GUI Editor for PowerShell Released</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,7618ad05-0d8e-47ad-8fe8-3de6189379ac.aspx</guid>
      <link>http://www.nivot.org/2008/11/04/SapienPrimalFormsGUIEditorForPowerShellReleased.aspx</link>
      <pubDate>Tue, 04 Nov 2008 17:32:56 GMT</pubDate>
      <description>&lt;p&gt;
I’d say a lot of folks will be chomping at the bit for this. It’s the &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Tk_(framework)"&gt;Tk&lt;/a&gt; to
PowerShell’s &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Tcl"&gt;Tcl&lt;/a&gt; and
is really the final piece of the puzzle where the shell’s position as the de-facto
Windows Shell stands anyway. Well, maybe Remoting support for XP and Windows Server
2003 is ahead there just a bit, but a forms designer must be a close second. 
&lt;/p&gt;
&lt;p&gt;
Check it out: &lt;a title="http://blog.sapien.com/index.php/2008/11/03/free-primalforms-tool-for-powershell-released/" href="http://blog.sapien.com/index.php/2008/11/03/free-primalforms-tool-for-powershell-released/"&gt;http://blog.sapien.com/index.php/2008/11/03/free-primalforms-tool-for-powershell-released/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Congratulations guys on shipping such a fine tool, for FREE. All it costs you is an
email address. Yah, sell your soul, it’ll be worth it.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=7618ad05-0d8e-47ad-8fe8-3de6189379ac" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,7618ad05-0d8e-47ad-8fe8-3de6189379ac.aspx</comments>
      <category>.NET</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>Windows Forms</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=a238fb63-ce04-463b-8efb-46c494d46ea2</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,a238fb63-ce04-463b-8efb-46c494d46ea2.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,a238fb63-ce04-463b-8efb-46c494d46ea2.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=a238fb63-ce04-463b-8efb-46c494d46ea2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve been performing the “resolution” listed in this article since I first discovered
the problem, but never ever did I think it was a “feature?” I was sure that I was
just the unluckiest person alive and was always working with some dodgy permissions
configuration of the 12 hive, but lo and behold, no. This is just the way it’s meant
to be. 
</p>
        <p>
Anyone else think this is just pure madness? By default any forms you create in Visual
Studio have a managed component. Hitting F5 to run deploy/debug won’t ever do the
work for you either. Why isn’t this mentioned anywhere in any sort of official capacity?
Anybody?
</p>
        <hr noshade="noshade" />
        <h3>Managed code may not be executed if an InfoPath 2007 workflow form is deployed
as a feature for a workflow
</h3>
        <h5>SYMPTOMS
</h5>
        <p>
Consider the following scenario. A Microsoft Office InfoPath 2007 workflow form contains
managed code. The form is deployed as a feature for a workflow. In this scenario,
the managed code may not be executed. 
</p>
        <h5>CAUSE
</h5>
        <p>
This issue occurs because a compiled DLL becomes part of the InfoPath form template
(XSN) file when you create managed code behind an InfoPath form. Microsoft Office
Forms Services does not extract a DLL by expanding the XSN file when the XSN file
is installed by using the features functionality. 
</p>
        <h5>RESOLUTION
</h5>
        <p>
To resolve this issue, copy the compiled DLL to the same folder to which your feature
XSN file was deployed.
</p>
        <p>
          <a title="http://support.microsoft.com/kb/930894/en-us" href="http://support.microsoft.com/kb/930894/en-us">http://support.microsoft.com/kb/930894/en-us</a>
        </p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=a238fb63-ce04-463b-8efb-46c494d46ea2" />
      </body>
      <title>Managed Code in InfoPath Workflow Task Forms - Why isn’t this categorized as a bug?</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,a238fb63-ce04-463b-8efb-46c494d46ea2.aspx</guid>
      <link>http://www.nivot.org/2008/11/03/ManagedCodeInInfoPathWorkflowTaskFormsWhyIsntThisCategorizedAsABug.aspx</link>
      <pubDate>Mon, 03 Nov 2008 21:51:58 GMT</pubDate>
      <description>&lt;p&gt;
I’ve been performing the “resolution” listed in this article since I first discovered
the problem, but never ever did I think it was a “feature?” I was sure that I was
just the unluckiest person alive and was always working with some dodgy permissions
configuration of the 12 hive, but lo and behold, no. This is just the way it’s meant
to be. 
&lt;/p&gt;
&lt;p&gt;
Anyone else think this is just pure madness? By default any forms you create in Visual
Studio have a managed component. Hitting F5 to run deploy/debug won’t ever do the
work for you either. Why isn’t this mentioned anywhere in any sort of official capacity?
Anybody?
&lt;/p&gt;
&lt;hr noshade&gt;
&lt;h3&gt;Managed code may not be executed if an InfoPath 2007 workflow form is deployed
as a feature for a workflow
&lt;/h3&gt;
&lt;h5&gt;SYMPTOMS
&lt;/h5&gt;
&lt;p&gt;
Consider the following scenario. A Microsoft Office InfoPath 2007 workflow form contains
managed code. The form is deployed as a feature for a workflow. In this scenario,
the managed code may not be executed. 
&lt;h5&gt;CAUSE
&lt;/h5&gt;
&lt;p&gt;
This issue occurs because a compiled DLL becomes part of the InfoPath form template
(XSN) file when you create managed code behind an InfoPath form. Microsoft Office
Forms Services does not extract a DLL by expanding the XSN file when the XSN file
is installed by using the features functionality. 
&lt;h5&gt;RESOLUTION
&lt;/h5&gt;
&lt;p&gt;
To resolve this issue, copy the compiled DLL to the same folder to which your feature
XSN file was deployed.
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://support.microsoft.com/kb/930894/en-us" href="http://support.microsoft.com/kb/930894/en-us"&gt;http://support.microsoft.com/kb/930894/en-us&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=a238fb63-ce04-463b-8efb-46c494d46ea2" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,a238fb63-ce04-463b-8efb-46c494d46ea2.aspx</comments>
      <category>.NET</category>
      <category>InfoPath</category>
      <category>MOSS</category>
      <category>SharePoint</category>
      <category>VSTO 3.0</category>
      <category>Workflow</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=4d5a1f8f-d39b-43fb-943f-6b2041b3efc3</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,4d5a1f8f-d39b-43fb-943f-6b2041b3efc3.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,4d5a1f8f-d39b-43fb-943f-6b2041b3efc3.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=4d5a1f8f-d39b-43fb-943f-6b2041b3efc3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One thing I’ve noticed about the SharePoint callback-based Activities in Workflow
is that they are extremely flakey if you try to reference the member variable reference
for the owning Activity directly instead of casting the “sender” argument in the event
handler itself. You have a SharePoint SetState Activity, for exmaple, along with the
corresponding MethodInvoking hook and I don’t mean the State Machine transition Activity,
but rather the SharePoint-specific Activity that lets you override the Workflow’s
overall state string using the &lt;ExtendedStatusColumnValues&gt; metadata in Workflow.xml.
In my case, I use the MySetState_MethodInvoking hook to set the state at runtime depending
on several conditions. If I try to set properties on the workflow's MySetState member
variable directly like this:
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="kwrd">private</span>
            <span class="kwrd">void</span> MySetState_MethodInvoking(<span class="kwrd">object</span> sender,
EventArgs e) {</pre>
          <pre>
            <span class="kwrd">this</span>.MySetState.State = SPWorkflowStatus.Max
+ 2;</pre>
          <pre class="alt">}</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
This just plainly doesn’t work reliably. It doesn’t throw any exceptions, in fact
it looks to work just fine, except the state is not changed. The same seems to go
for any other of the SharePoint interfaces that involve callbacks. In my experience,
they just don’t work most of the time especially if the workflow dehydrates before
the callback is invoked. This leads me to think that there are some quirky interactions
going on internally that somehow cause the workflow to ignore your attempts to change
anything, perhaps due to the workflow getting rehydrated after you have made the changes,
or who knows. All I know is that if you want this stuff to work reliably, ALWAYS CAST
THE SENDER to your target Activity before attempting to manipulate the owning Activity.
Using the member variable is just flakey. If anyone has any information on this, let
me know. This works reliably:
</p>
        <pre class="csharpcode">
          <span class="kwrd">private</span> vid MySetState_MethodInvoking(<span class="kwrd">object</span> sender,
EventArgs e) { ((SetState)sender).State = SPWorkflowStatus.Max + 2; }</pre>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
Anyway, have fun.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=4d5a1f8f-d39b-43fb-943f-6b2041b3efc3" />
      </body>
      <title>Tips on SharePoint Workflow, SharePoint Activities and MethodInvoking callbacks</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,4d5a1f8f-d39b-43fb-943f-6b2041b3efc3.aspx</guid>
      <link>http://www.nivot.org/2008/11/03/TipsOnSharePointWorkflowSharePointActivitiesAndMethodInvokingCallbacks.aspx</link>
      <pubDate>Mon, 03 Nov 2008 15:45:31 GMT</pubDate>
      <description>&lt;p&gt;
One thing I’ve noticed about the SharePoint callback-based Activities in Workflow
is that they are extremely flakey if you try to reference the member variable reference
for the owning Activity directly instead of casting the “sender” argument in the event
handler itself. You have a SharePoint SetState Activity, for exmaple, along with the
corresponding MethodInvoking hook and I don’t mean the State Machine transition Activity,
but rather the SharePoint-specific Activity that lets you override the Workflow’s
overall state string using the &amp;lt;ExtendedStatusColumnValues&amp;gt; metadata in Workflow.xml.
In my case, I use the MySetState_MethodInvoking hook to set the state at runtime depending
on several conditions. If I try to set properties on the workflow's MySetState member
variable directly like this:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MySetState_MethodInvoking(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender,
EventArgs e) {&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.MySetState.State = SPWorkflowStatus.Max
+ 2;&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
This just plainly doesn’t work reliably. It doesn’t throw any exceptions, in fact
it looks to work just fine, except the state is not changed. The same seems to go
for any other of the SharePoint interfaces that involve callbacks. In my experience,
they just don’t work most of the time especially if the workflow dehydrates before
the callback is invoked. This leads me to think that there are some quirky interactions
going on internally that somehow cause the workflow to ignore your attempts to change
anything, perhaps due to the workflow getting rehydrated after you have made the changes,
or who knows. All I know is that if you want this stuff to work reliably, ALWAYS CAST
THE SENDER to your target Activity before attempting to manipulate the owning Activity.
Using the member variable is just flakey. If anyone has any information on this, let
me know. This works reliably:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; vid MySetState_MethodInvoking(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender,
EventArgs e) { ((SetState)sender).State = SPWorkflowStatus.Max + 2; }&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
Anyway, have fun.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=4d5a1f8f-d39b-43fb-943f-6b2041b3efc3" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,4d5a1f8f-d39b-43fb-943f-6b2041b3efc3.aspx</comments>
      <category>.NET</category>
      <category>MOSS</category>
      <category>SharePoint</category>
      <category>Workflow</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=775897d5-6c8b-46b3-94fe-cace9b5d3477</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,775897d5-6c8b-46b3-94fe-cace9b5d3477.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,775897d5-6c8b-46b3-94fe-cace9b5d3477.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=775897d5-6c8b-46b3-94fe-cace9b5d3477</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Fellow <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> MVP
and <strike>developer</strike> all-round expert administrator <a target="_blank" href="http://www.bsonposh.com/">Brandon
Shell</a> asked me how he could navigate to a Cmdlet’s implementation in Lutz Roeder’s <a target="_blank" href="http://www.red-gate.com/products/reflector/">Reflector</a> --
which has now been acquired by Red-Gate Software btw. At first I was going to explain
to him how snap-ins work and how to figure out where things are, and then a really
simple trick hit me that uses some fairly secret command-line parameter that Reflector
can accept, namely the /select parameter:
</p>
        <!-- Stylesheet link -->
        <link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" />
        <!-- Code -->
        <div id="hlDiv" class="dp-highlighter">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span class="keyword">function</span>
                <span> Reflect-Cmdlet {   </span>
              </span>
            </li>
            <li>
              <span>    </span>
              <span class="keyword">param</span>
              <span>([Management.Automation.CommandInfo]</span>
              <span class="variable">$command</span>
              <span>)   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">if</span>
              <span> (</span>
              <span class="variable">$input</span>
              <span>)
{   </span>
            </li>
            <li>
              <span>        trap { </span>
              <span class="variable">$_</span>
              <span>;
break }   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="variable">$command</span>
              <span> = </span>
              <span class="variable">$input</span>
              <span> |
select -first 1   </span>
            </li>
            <li>
              <span>    }       </span>
            </li>
            <li class="alt">
              <span>          </span>
            </li>
            <li>
              <span>    </span>
              <span class="comment"># resolve to command if this
is an alias </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">while</span>
              <span> (</span>
              <span class="variable">$command</span>
              <span>.CommandType
-eq </span>
              <span class="string">"Alias"</span>
              <span>) {   </span>
            </li>
            <li>
              <span>        </span>
              <span class="variable">$command</span>
              <span> = </span>
              <span class="builtin">Get-Command</span>
              <span> (</span>
              <span class="variable">$command</span>
              <span>.definition)   </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li>
              <span>       </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$name</span>
              <span> = </span>
              <span class="variable">$command</span>
              <span>.ImplementingType       </span>
            </li>
            <li>
              <span>    </span>
              <span class="variable">$DLL</span>
              <span> = </span>
              <span class="variable">$command</span>
              <span>.DLL   </span>
            </li>
            <li class="alt">
              <span>       </span>
            </li>
            <li>
              <span>    </span>
              <span class="keyword">if</span>
              <span> (-not (gcm reflector.exe
-ea silentlycontinue)) {   </span>
            </li>
            <li class="alt">
              <span>        throw </span>
              <span class="string">"I
can't find Reflector.exe in your path."</span>
              <span>  </span>
            </li>
            <li>
              <span>    }   </span>
            </li>
            <li class="alt">
              <span>        </span>
            </li>
            <li>
              <span>    reflector /select:</span>
              <span class="variable">$name</span>
              <span> </span>
              <span class="variable">$DLL</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>}  </span>
            </li>
          </ol>
        </div>
        <p>
Just pipe the output of get-command to it, like: <font size="4" face="Cordia New"><strong>gcm
dir | reflect-cmdlet</strong></font> and Reflector will open up with the class selected
(it takes a few seconds).
</p>
        <p>
          <strong>Update: </strong>Doug pointed out in a comment that the gcm reflector.exe
line could benefit from an erroraction to keep it silent on failure, so only the throw
message shows. Thanks Doug!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=775897d5-6c8b-46b3-94fe-cace9b5d3477" />
      </body>
      <title>A trick to jump directly to a Cmdlet’s implementation in Reflector</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,775897d5-6c8b-46b3-94fe-cace9b5d3477.aspx</guid>
      <link>http://www.nivot.org/2008/10/30/ATrickToJumpDirectlyToACmdletsImplementationInReflector.aspx</link>
      <pubDate>Thu, 30 Oct 2008 18:44:40 GMT</pubDate>
      <description>&lt;p&gt;
Fellow &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; MVP
and &lt;strike&gt;developer&lt;/strike&gt; all-round expert administrator &lt;a target=_blank href="http://www.bsonposh.com/"&gt;Brandon
Shell&lt;/a&gt; asked me how he could navigate to a Cmdlet’s implementation in Lutz Roeder’s &lt;a target=_blank href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt; --
which has now been acquired by Red-Gate Software btw. At first I was going to explain
to him how snap-ins work and how to figure out where things are, and then a really
simple trick hit me that uses some fairly secret command-line parameter that Reflector
can accept, namely the /select parameter:
&lt;/p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link rel=stylesheet type=text/css href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css"&gt;
&lt;!-- Code --&gt;
&lt;div id=hlDiv class=dp-highlighter&gt;
&lt;div class=bar&gt;
&lt;/div&gt;
&lt;ol class=dp-rb&gt;
&lt;li class=alt&gt;
&lt;span&gt;&lt;span class=keyword&gt;function&lt;/span&gt;&lt;span&gt; Reflect-Cmdlet {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class=keyword&gt;param&lt;/span&gt;&lt;span&gt;([Management.Automation.CommandInfo]&lt;/span&gt;&lt;span class=variable&gt;$command&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class=keyword&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=variable&gt;$input&lt;/span&gt;&lt;span&gt;)
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; trap { &lt;/span&gt;&lt;span class=variable&gt;$_&lt;/span&gt;&lt;span&gt;;
break }&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class=variable&gt;$command&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class=variable&gt;$input&lt;/span&gt;&lt;span&gt; |
select -first 1&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class=comment&gt;# resolve to command if this is
an alias &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class=keyword&gt;while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=variable&gt;$command&lt;/span&gt;&lt;span&gt;.CommandType
-eq &lt;/span&gt;&lt;span class=string&gt;"Alias"&lt;/span&gt;&lt;span&gt;) {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class=variable&gt;$command&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class=builtin&gt;Get-Command&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=variable&gt;$command&lt;/span&gt;&lt;span&gt;.definition)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class=variable&gt;$name&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class=variable&gt;$command&lt;/span&gt;&lt;span&gt;.ImplementingType&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class=variable&gt;$DLL&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class=variable&gt;$command&lt;/span&gt;&lt;span&gt;.DLL&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class=keyword&gt;if&lt;/span&gt;&lt;span&gt; (-not (gcm reflector.exe
-ea silentlycontinue)) {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw &lt;/span&gt;&lt;span class=string&gt;"I
can't find Reflector.exe in your path."&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=alt&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; reflector /select:&lt;/span&gt;&lt;span class=variable&gt;$name&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=variable&gt;$DLL&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=alt&gt;
&lt;span&gt;}&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
Just pipe the output of get-command to it, like: &lt;font size=4 face="Cordia New"&gt;&lt;strong&gt;gcm
dir | reflect-cmdlet&lt;/strong&gt;&lt;/font&gt; and Reflector will open up with the class selected
(it takes a few seconds).
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update: &lt;/strong&gt;Doug pointed out in a comment that the gcm reflector.exe
line could benefit from an erroraction to keep it silent on failure, so only the throw
message shows. Thanks Doug!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=775897d5-6c8b-46b3-94fe-cace9b5d3477" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,775897d5-6c8b-46b3-94fe-cace9b5d3477.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=a69ea7cd-8f3a-40a7-a2cf-e0bfa249ab3f</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,a69ea7cd-8f3a-40a7-a2cf-e0bfa249ab3f.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,a69ea7cd-8f3a-40a7-a2cf-e0bfa249ab3f.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=a69ea7cd-8f3a-40a7-a2cf-e0bfa249ab3f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The verbs list for naming your Cmdlets is pretty strict. You should definitely
try to pick one of the known verbs. You can see them here:
</p>
        <p>
          <font face="Courier New">function Get-Verb {<br />
    [psobject].assembly.getexportedtypes() | `<br />
        ? {$_.name -like "Verbs*"} | gm -static
-membertype property | `<br />
        sort Name | select Name<br />
}</font>
        </p>
        <p>
          <font face="Courier New">ps&gt; Get-Verb</font>
        </p>
        <p>
The noun end of the spectrum is pretty open-ended. Single nouns are better, and try
to use the singular if you can. Cmdlets typically return <strong>one</strong> or more
objects. so the singular form is the convention - better than trying to name your
Cmdlet "Get-Noun(s)" which is just plain silly. 
</p>
        <p>
To prefix or not to prefix: this is a sticky one. The Religious Right, aka the Microsoft
Powershell team, dictate that you should not prefix. The reality is more complicated
and is under constant debate. If you pick a verb-noun pair that already exists and
is currently loaded into powershell, you must disambiguate the command with the snapin
name (snapinname\verb-noun) or it won't run. The snapin name is typically long and
ugly. A noun prefix is typically short and sweet. The problem with the latter is that
your commands are now harder to discover for someone who doesn't know they are there
(and as such doesn't know your magic prefix). Ultimately though, people load your
snapin explicitly and should know the prefix, so I tend to lean towards this although
I feel a strong connection with the "One Noun Way."
</p>
        <p>
(taken from one of my newgroup posts)
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=a69ea7cd-8f3a-40a7-a2cf-e0bfa249ab3f" />
      </body>
      <title>Naming your Cmdlets and Functions: Verbs and Nouns</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,a69ea7cd-8f3a-40a7-a2cf-e0bfa249ab3f.aspx</guid>
      <link>http://www.nivot.org/2008/10/15/NamingYourCmdletsAndFunctionsVerbsAndNouns.aspx</link>
      <pubDate>Wed, 15 Oct 2008 16:20:19 GMT</pubDate>
      <description>&lt;p&gt;
The verbs list for naming your Cmdlets&amp;nbsp;is pretty strict. You should definitely
try to pick one of the known verbs. You can see them here:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;function Get-Verb {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [psobject].assembly.getexportedtypes() | `&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ? {$_.name -like "Verbs*"} | gm -static
-membertype property | `&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sort Name | select Name&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;ps&amp;gt; Get-Verb&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The noun end of the spectrum is pretty open-ended. Single nouns are better, and try
to use the singular if you can. Cmdlets typically return &lt;strong&gt;one&lt;/strong&gt; or more
objects. so the singular form is the convention - better than trying to name your
Cmdlet "Get-Noun(s)" which is just plain silly. 
&lt;/p&gt;
&lt;p&gt;
To prefix or not to prefix: this is a sticky one. The Religious Right, aka the Microsoft
Powershell team, dictate that you should not prefix. The reality is more complicated
and is under constant debate. If you pick a verb-noun pair that already exists and
is currently loaded into powershell, you must disambiguate the command with the snapin
name (snapinname\verb-noun) or it won't run. The snapin name is typically long and
ugly. A noun prefix is typically short and sweet. The problem with the latter is that
your commands are now harder to discover for someone who doesn't know they are there
(and as such doesn't know your magic prefix). Ultimately though, people load your
snapin explicitly and should know the prefix, so I tend to lean towards this although
I feel a strong&amp;nbsp;connection with the "One Noun Way."
&lt;/p&gt;
&lt;p&gt;
(taken from&amp;nbsp;one of my&amp;nbsp;newgroup posts)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=a69ea7cd-8f3a-40a7-a2cf-e0bfa249ab3f" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,a69ea7cd-8f3a-40a7-a2cf-e0bfa249ab3f.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PowerShell 2.0</category>
      <category>SnapIns</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=a14ab954-281f-4424-adbb-5b2032104628</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,a14ab954-281f-4424-adbb-5b2032104628.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,a14ab954-281f-4424-adbb-5b2032104628.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=a14ab954-281f-4424-adbb-5b2032104628</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is just a post containing all the issues I’ve run into over the last six months
while working with MOSS Workflows, InfoPath and Visual Studio 2008/VSTO 3.0. I’ve
been using these tools in this combination for a while now, but it’s only the last
six months where I decided to take a note every time I ran into something. Don’t get
me wrong though. This is more of a post aimed at helping others in their quest for
abdominal hull-integrity while working with these tools, not attacking the toolset.
Ultimately, the Office Suite and the corresponding tools are working together better
than ever before, but unfortunately with large teams working relatively independently
you’re just going to get these kind of problems. To be brutally honest, I think VSTO
3.0 is a saddle-sore on the otherwise supple and leathery hide of Visual Studio 2008
and the disparity in their respective product quality is way too pronounced to be
ignored. 
</p>
        <p>
Anyway, I’m not going to make much attempt to explain each case for non-SharePoint
people, but if you’re involved in this area, you’ll know where I’m coming from. The
following list contains Glitches and Gotchas. 
</p>
        <h3>Glitches
</h3>
        <p>
First though, the <strong>Glitches</strong>, in no particular order. These are the
lovingly hand-crafted defects and “product quality issues” that will first cause your
stomach muscles to contract somewhat, then violently spasm so hard that that first
loop of intestine will pop out to nestle amongst the fat cells and veins in the fleshy
meadow of your lower-epidermis. Don’t say I didn’t warn you.
</p>
        <h5>Publish an Installable Form Template (requires Visual Studio)
</h5>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/vs2008-vs-not-installed-properly_2.png">
            <img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="vs2008-vs-not-installed-properly" border="0" alt="vs2008-vs-not-installed-properly" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/vs2008-vs-not-installed-properly_thumb.png" width="669" height="117" />
          </a>
        </p>
        <p>
If you try to publish a form as "an installable template (requires visual studio)"
from within Visual Studio 2008 (even with sp1), VSTO, in its infinite wisdom tries
to use<strong> visual studio 2005 </strong>devenv.exe<strong> </strong>executable
to do it! And it fails spectacularly 'cos it's not installed, or if it is installed
it's part of some vs-shell install for some other office app like office macros IDE,
or Internet Explorer’s “script debugger” shell for example.
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/vs2008-infopath-vs2005_2.png">
            <img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="vs2008-infopath-vs2005" border="0" alt="vs2008-infopath-vs2005" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/vs2008-infopath-vs2005_thumb.png" width="583" height="80" />
          </a>
        </p>
        <h5>Publishing a Form to an explicitly-included Managed Path
</h5>
        <p>
Trying to publish a form to a SiteCollection sitting on an explicitly-included managed
path fails with "getting the site content type columns failed." Workaround? Don’t
publish forms to Managed Paths. It’s b0rked.
</p>
        <h5>“An exception occurred during loading of business logic” - Publishing XSNs with
CodeBehind to SharePoint
</h5>
        <p>
If you perform a cursory search for the title, you’ll find lots of herniated VSTO
users having issues with this. InfoPath Forms Services on MOSS Enterprise is a fickle
beast; a beast that will have you tucking those intestinal loops back into your torso
with a pencil before you can say “FileNotFoundException, whuh?”
</p>
        <p>
XSN files are actually CAB files. When Forms Services loads them up to be rendered
into Browser Forms, it has to load the embedded DLL into memory. It has an extremely
hard time doing this sometimes. Particularly when you store your XSN files in a subdirectory
under your workflow feature, say like one called Forms. It appears that the form loads
ok, but Forms Services is looking for the DLL in the <em>root</em> of your feature.
Even sometimes if you have the XSN in the root of your feature, it still won’t find
and extract/load the embedded DLL. <strong>The only way to avoid this it appears is
to manually extract the DLL and place it in the root of the feature yourself </strong>after
you have deployed the workflow solution.
</p>
        <p>
Some strange things I’ve observed about Forms Services on MOSS Enterprise:
</p>
        <ul>
          <li>
            <div align="left">Uploading a codebehind-XSN  file via central admin automatically
extracts dll/pdb into feature directory but...
</div>
          </li>
          <li>
            <div align="left">Deploying a codebehind-XSN with  workflow feature does <strong>not</strong> extract
dll/pdb.
</div>
          </li>
          <li>
            <div align="left">Upgrading a codebehind-XSN with central admin creates new subdir
in feature folder, modifies feature.xml to point to it but does <strong>not</strong> extract
the form's codebehind dll/pdb into new subdir either.
</div>
          </li>
        </ul>
        <p>
These seem to be some rather serious looking issues to me.
</p>
        <h5>VSTO Designer ToolPane Content Shrinks
</h5>
        <p>
Occasionally the Design ToolPane in VS2008/VSTO inexplicably changes size, with the
contents of it being set at about 1cm wide.<a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/b0rked-vsto-toolpane_2.png"><img style="border-right-width: 0px; margin: 10px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="b0rked-vsto-toolpane" border="0" alt="b0rked-vsto-toolpane" align="right" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/b0rked-vsto-toolpane_thumb.png" width="300" height="457" /></a></p>
A restart of Visual Studio or close/reopen of the project usually fixes this.<br /><h5>Workflow Designer Screws Up Layout of Nested States
</h5><p>
The workflow designer in VS 2008 (even sp1) will screw up the formatting of nested
states in a state machine workflow - they get randomly offset to the left or right
so they are half occluded by the containing state. Yay.
</p><h5>Views ToolPane Is Blank For a Form that has Views
</h5><p>
Views created in infopath sometimes do not appear in vs2008 project built around that
imported XSN. Weirdly, the toolpane is completely white/blank. A restart of Visual
Studio or close/reopen of the project usually fixes this.
</p><h5>Manipulating Files In “InfoPath Form Template” Project Folder Is a Bad Idea
</h5><p>
Deleting/modifying/renaming a file in the "infopath form template" meta-folder in
Visual Studio 2008 does not fix the reference in the manifest.xsf file. The form is
then <strong>impossible to open</strong> until you fix the references within the manifest
by closing the form designer and opening the XSF with the XML handler through a right-click.
Why does VSTO even let you modify embedded resources if it won’t update the manifest
for you?
</p><h5>The magical secondary DataSource ItemMetadata.xml
</h5><p>
The secondary DataSource (for receive data) ItemMetadata.xml has _two_ ways of being
added as a resource - the second way (prompted at end of import). You can either add
it as a resource when you initially point VSTO/InfoPath at it, or if you don’t do
it then you get a second chance at the end of import to add it as a resource. This
is confusing.
</p><h5>Converting an embedded DataSource to site-relative format and placing into a 
Data Connection Library can leave the required field "Title" empty
</h5><p>
This enforces the UDCX files to be permanently checked out - trying to update the
title field by hand does <strong>not</strong> work - it remains blank at every attempt
to change it when done directly or via bulk edit DataGrid view. It sometimes exclaims
that the files are checked out to another user even though they are plainly checked
out to me. Worst of all, only *I* can use the InfoPath form that uses this DataSource
so it’s starts out a looking like “it works for me” issue.  Anyone else cannot
use the form - DataSource loading fails - ULS log says "root element is missing" -
after much debugging, it appears that anyone (apart from me the author) attempting
to download the UDCX file gets a 0 length file - you can test this by getting the
poor user to try to download the UDCX from the connection library. This is because
only an author of a checked-out file can read it.  
</p><p><strong>Hacky Fix:</strong> Remove ReadOnly attribute from the list-level UDCX content
type and mark the Title column as optional, then check-in the connections. Title be
damned!
</p><p>
This all started when I enabled Versioning for the connection library before converting
my data sources. Not sure if that’s relevant. 
</p><h5>BDC randomly losing ServerContext while inside Event Receiver triggered from Workflow
context
</h5><p>
The TLS slot for the resource provider SqlSessionProvider sometimes ends up being
null on the Event Receiver's thread. If you’re not following me, you probably don’t
need to understand this any further.
</p><h3>Gotchas
</h3><p>
These are not so much glitches are they are things that can trip you up and/or be
considered “non-obvious” behavioural quirks. While they may give you an upset tummy,
you are not going to be trussed up in a Spigelian torso-bangle any time soon.
</p><h5>A Workflow Continually Spawns New Instances of Itself 
</h5><p>
When you have a workflow added to a document library and the workflow updates the
list item when it is running, a new workflow will spawn once the .Update() method
is executed on the list item. To update the item without having a new worklfow started,
use .SystemUpdate(). Duh.
</p><h5>"The database returns an error. Failed to enable constraints." When InfoPath DataBinds
</h5><p>
Changing the query directly in a UDCX file inside a data connection library may cause
"The database returns an error. Failed to enable constraints. One or more rows contain
values violating non-null, unique, or foreign-key constraints" errors from live InfoPath
forms because the data source schema in InfoPath no longer matches (especially if
you increase the length of a returned field) - after you change the UDCX, you must
go through the "manage data connections" and choose "modify" for that connection and
go through the wizard without changing anything. This will cause InfoPath to re-sync
the schema.
</p><h5>How The Hell Can I Render The Form Version On The Form Itself?
</h5><p>
Tip: insert form version with the expression: substring-before( substring-after( /processing-instruction()[local-name(.)
= "mso-infoPathSolution"], 'solutionVersion="'), '"')
</p><p>
I can’t remember where I got this, I didn’t write it myself. Thanks to the original
author.
</p><h5>Why Can’t SharePoint Find My Forms for my Workflow?
</h5><p>
The Form URN will change if you don't name your form exactly as you did (e.g. accept
the default) in "file &gt; form properties" when publishing it with the publishing
wizard.
</p><h5>Why Can’t My Workflow Forms Find My Data Connections?
</h5><p>
Site relative data connections stored in a data connection library work fine for InfoPath
published forms bound to a content type in a site; also form security will stay at
domain. But they can’t be found if these same forms are used in a workflow. Use “centrally
managed” data connections instead. 
</p><h5>Why Does Visual Studio Put Referenced DLLs Bound For the GAC Into My InfoPath
XSN?
</h5><p>
If you reference other feature projects in the same solution that deploy into GAC,
be sure that they exist in the GAC <strong>before</strong> building the InfoPath project's
XSN - if they are not in the GAC, they will be copied into the XSN by default. Duh.
</p><h5>How Do I Uninstall My Workflow I was Debugging In Visual Studio?
</h5><p>
Workflow features deployed via vs2008 F5/start debugging have no obvious means of
being "undeployed." you must use <a target="_blank" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=46B6BF86-E35D-4870-B214-4D7B72B02BF9">VSTO
1.0 PowerTools</a> "Feature Sweeper" to remove it; this is a dependency for workflow
forms registered in central admin.
</p><h5>Why Are The TaskProperties Hashtables So Weird?
</h5><p>
ExtendedProperties Hashtables leaves root XML fields as keys, and nested xml as my:schema
formatted XML for Hashtable values. Strangely, the Workflow API has a public XmlToHashtable
method on a utility class, but not the inverse to pull it back out of ExtendedProperties.
Duh. 
</p><h5>Where The Hell Did The Form Publish Menu Disappear to?
</h5><p>
You cannot publish the InfoPath form unless you have the designer open, even though
you can only have one form per project and you might just have a single project in
the solution. This is annoying when your forms are large and sluggish to open.
</p><h5 align="left">Why do some VS SharePoint Activities have a User (string) property
and others a UserID (int) property?
</h5><p>
I wish I knew. This is just another silly design (in)decision. All SPUsers in SharePoint
have both a Login (string) and a PrincipalID (int). If you want to set the Logging
Activity’s UserId (int) to the id of a person who performed a Workflow Modification
User (string), you have to convert, persist and expose these properties yourselves
before you can bind to an activity using the designer. Duh.
</p><p>
I use a method like this:
</p><code style="display: block; font-size: 10pt">id = Contact.FromName(executor, this.workflowProperties.Web).PrincipalID;</code><h5></h5><h5>Why is Visual Studio 2008  SP1’s Workflow Designer Host still such a dog? 
</h5><p>
You and <a target="_blank" href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3808068&amp;SiteID=1">thousands
of other people</a> would love to know the answer. IMHO, it’s too complex to have
been written in Managed Code (e.g. C#). It should have been native C++ from day one.
All that synchronizing intellisense, XOML and the visual designer is just too much
for it. God help you if you throw in any real-time refactoring tools on top of that. 
</p><h3>Summary
</h3><p></p><p>
Despite all this moaning, SharePoint in conjunction with Visual Studio 2008 is a powerful
combination. Nothing to be sniffed at all; I actually love it (most of the time.)
</p><p>
Have fun.
</p><img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=a14ab954-281f-4424-adbb-5b2032104628" /></body>
      <title>Why VSTO 3.0, Visual Studio 2008, SharePoint+Windows Workflow And InfoPath Might Give You A Hernia</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,a14ab954-281f-4424-adbb-5b2032104628.aspx</guid>
      <link>http://www.nivot.org/2008/09/30/WhyVSTO30VisualStudio2008SharePointWindowsWorkflowAndInfoPathMightGiveYouAHernia.aspx</link>
      <pubDate>Tue, 30 Sep 2008 18:19:44 GMT</pubDate>
      <description>&lt;p&gt;
This is just a post containing all the issues I’ve run into over the last six months
while working with MOSS Workflows, InfoPath and Visual Studio 2008/VSTO 3.0. I’ve
been using these tools in this combination for a while now, but it’s only the last
six months where I decided to take a note every time I ran into something. Don’t get
me wrong though. This is more of a post aimed at helping others in their quest for
abdominal hull-integrity while working with these tools, not attacking the toolset.
Ultimately, the Office Suite and the corresponding tools are working together better
than ever before, but unfortunately with large teams working relatively independently
you’re just going to get these kind of problems. To be brutally honest, I think VSTO
3.0 is a saddle-sore on the otherwise supple and leathery hide of Visual Studio 2008
and the disparity in their respective product quality is way too pronounced to be
ignored. 
&lt;/p&gt;
&lt;p&gt;
Anyway, I’m not going to make much attempt to explain each case for non-SharePoint
people, but if you’re involved in this area, you’ll know where I’m coming from. The
following list contains Glitches and Gotchas. 
&lt;/p&gt;
&lt;h3&gt;Glitches
&lt;/h3&gt;
&lt;p&gt;
First though, the &lt;strong&gt;Glitches&lt;/strong&gt;, in no particular order. These are the
lovingly hand-crafted defects and “product quality issues” that will first cause your
stomach muscles to contract somewhat, then violently spasm so hard that that first
loop of intestine will pop out to nestle amongst the fat cells and veins in the fleshy
meadow of your lower-epidermis. Don’t say I didn’t warn you.
&lt;/p&gt;
&lt;h5&gt;Publish an Installable Form Template (requires Visual Studio)
&lt;/h5&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/vs2008-vs-not-installed-properly_2.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="vs2008-vs-not-installed-properly" border="0" alt="vs2008-vs-not-installed-properly" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/vs2008-vs-not-installed-properly_thumb.png" width="669" height="117"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
If you try to publish a form as "an installable template (requires visual studio)"
from within Visual Studio 2008 (even with sp1), VSTO, in its infinite wisdom tries
to use&lt;strong&gt; visual studio 2005 &lt;/strong&gt;devenv.exe&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;executable
to do it! And it fails spectacularly 'cos it's not installed, or if it is installed
it's part of some vs-shell install for some other office app like office macros IDE,
or Internet Explorer’s “script debugger” shell for example.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/vs2008-infopath-vs2005_2.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="vs2008-infopath-vs2005" border="0" alt="vs2008-infopath-vs2005" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/vs2008-infopath-vs2005_thumb.png" width="583" height="80"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;h5&gt;Publishing a Form to an explicitly-included Managed Path
&lt;/h5&gt;
&lt;p&gt;
Trying to publish a form to a SiteCollection sitting on an explicitly-included managed
path fails with "getting the site content type columns failed." Workaround? Don’t
publish forms to Managed Paths. It’s b0rked.
&lt;/p&gt;
&lt;h5&gt;“An exception occurred during loading of business logic” - Publishing XSNs with
CodeBehind to SharePoint
&lt;/h5&gt;
&lt;p&gt;
If you perform a cursory search for the title, you’ll find lots of herniated VSTO
users having issues with this. InfoPath Forms Services on MOSS Enterprise is a fickle
beast; a beast that will have you tucking those intestinal loops back into your torso
with a pencil before you can say “FileNotFoundException, whuh?”
&lt;/p&gt;
&lt;p&gt;
XSN files are actually CAB files. When Forms Services loads them up to be rendered
into Browser Forms, it has to load the embedded DLL into memory. It has an extremely
hard time doing this sometimes. Particularly when you store your XSN files in a subdirectory
under your workflow feature, say like one called Forms. It appears that the form loads
ok, but Forms Services is looking for the DLL in the &lt;em&gt;root&lt;/em&gt; of your feature.
Even sometimes if you have the XSN in the root of your feature, it still won’t find
and extract/load the embedded DLL. &lt;strong&gt;The only way to avoid this it appears is
to manually extract the DLL and place it in the root of the feature yourself &lt;/strong&gt;after
you have deployed the workflow solution.
&lt;/p&gt;
&lt;p&gt;
Some strange things I’ve observed about Forms Services on MOSS Enterprise:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="left"&gt;Uploading a codebehind-XSN&amp;nbsp; file via central admin automatically
extracts dll/pdb into feature directory but...
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Deploying a codebehind-XSN with&amp;nbsp; workflow feature does &lt;strong&gt;not&lt;/strong&gt; extract
dll/pdb.
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Upgrading a codebehind-XSN with central admin creates new subdir
in feature folder, modifies feature.xml to point to it but does &lt;strong&gt;not&lt;/strong&gt; extract
the form's codebehind dll/pdb into new subdir either.
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
These seem to be some rather serious looking issues to me.
&lt;/p&gt;
&lt;h5&gt;VSTO Designer ToolPane Content Shrinks
&lt;/h5&gt;
&lt;p&gt;
Occasionally the Design ToolPane in VS2008/VSTO inexplicably changes size, with the
contents of it being set at about 1cm wide.&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/b0rked-vsto-toolpane_2.png"&gt;&lt;img style="border-right-width: 0px; margin: 10px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="b0rked-vsto-toolpane" border="0" alt="b0rked-vsto-toolpane" align="right" src="http://www.nivot.org/content/binary/WindowsLiveWriter/Why.0VisualStudio2008WindowsWorkflowAndI_95B8/b0rked-vsto-toolpane_thumb.png" width="300" height="457"&gt;&lt;/a&gt;
&lt;/p&gt;
A restart of Visual Studio or close/reopen of the project usually fixes this.&lt;br&gt;
&lt;h5&gt;Workflow Designer Screws Up Layout of Nested States
&lt;/h5&gt;
&lt;p&gt;
The workflow designer in VS 2008 (even sp1) will screw up the formatting of nested
states in a state machine workflow - they get randomly offset to the left or right
so they are half occluded by the containing state. Yay.
&lt;/p&gt;
&lt;h5&gt;Views ToolPane Is Blank For a Form that has Views
&lt;/h5&gt;
&lt;p&gt;
Views created in infopath sometimes do not appear in vs2008 project built around that
imported XSN. Weirdly, the toolpane is completely white/blank. A restart of Visual
Studio or close/reopen of the project usually fixes this.
&lt;/p&gt;
&lt;h5&gt;Manipulating Files In “InfoPath Form Template” Project Folder Is a Bad Idea
&lt;/h5&gt;
&lt;p&gt;
Deleting/modifying/renaming a file in the "infopath form template" meta-folder in
Visual Studio 2008 does not fix the reference in the manifest.xsf file. The form is
then &lt;strong&gt;impossible to open&lt;/strong&gt; until you fix the references within the manifest
by closing the form designer and opening the XSF with the XML handler through a right-click.
Why does VSTO even let you modify embedded resources if it won’t update the manifest
for you?
&lt;/p&gt;
&lt;h5&gt;The magical secondary DataSource ItemMetadata.xml
&lt;/h5&gt;
&lt;p&gt;
The secondary DataSource (for receive data) ItemMetadata.xml has _two_ ways of being
added as a resource - the second way (prompted at end of import). You can either add
it as a resource when you initially point VSTO/InfoPath at it, or if you don’t do
it then you get a second chance at the end of import to add it as a resource. This
is confusing.
&lt;/p&gt;
&lt;h5&gt;Converting an embedded DataSource to site-relative format and placing into a&amp;nbsp;
Data Connection Library can leave the required field "Title" empty
&lt;/h5&gt;
&lt;p&gt;
This enforces the UDCX files to be permanently checked out - trying to update the
title field by hand does &lt;strong&gt;not&lt;/strong&gt; work - it remains blank at every attempt
to change it when done directly or via bulk edit DataGrid view. It sometimes exclaims
that the files are checked out to another user even though they are plainly checked
out to me. Worst of all, only *I* can use the InfoPath form that uses this DataSource
so it’s starts out a looking like “it works for me” issue.&amp;nbsp; Anyone else cannot
use the form - DataSource loading fails - ULS log says "root element is missing" -
after much debugging, it appears that anyone (apart from me the author) attempting
to download the UDCX file gets a 0 length file - you can test this by getting the
poor user to try to download the UDCX from the connection library. This is because
only an author of a checked-out file can read it.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Hacky Fix:&lt;/strong&gt; Remove ReadOnly attribute from the list-level UDCX content
type and mark the Title column as optional, then check-in the connections. Title be
damned!
&lt;/p&gt;
&lt;p&gt;
This all started when I enabled Versioning for the connection library before converting
my data sources. Not sure if that’s relevant. 
&lt;/p&gt;
&lt;h5&gt;BDC randomly losing ServerContext while inside Event Receiver triggered from Workflow
context
&lt;/h5&gt;
&lt;p&gt;
The TLS slot for the resource provider SqlSessionProvider sometimes ends up being
null on the Event Receiver's thread. If you’re not following me, you probably don’t
need to understand this any further.
&lt;/p&gt;
&lt;h3&gt;Gotchas
&lt;/h3&gt;
&lt;p&gt;
These are not so much glitches are they are things that can trip you up and/or be
considered “non-obvious” behavioural quirks. While they may give you an upset tummy,
you are not going to be trussed up in a Spigelian torso-bangle any time soon.
&lt;/p&gt;
&lt;h5&gt;A Workflow Continually Spawns New Instances of Itself 
&lt;/h5&gt;
&lt;p&gt;
When you have a workflow added to a document library and the workflow updates the
list item when it is running, a new workflow will spawn once the .Update() method
is executed on the list item. To update the item without having a new worklfow started,
use .SystemUpdate(). Duh.
&lt;/p&gt;
&lt;h5&gt;"The database returns an error. Failed to enable constraints." When InfoPath DataBinds
&lt;/h5&gt;
&lt;p&gt;
Changing the query directly in a UDCX file inside a data connection library may cause
"The database returns an error. Failed to enable constraints. One or more rows contain
values violating non-null, unique, or foreign-key constraints" errors from live InfoPath
forms because the data source schema in InfoPath no longer matches (especially if
you increase the length of a returned field) - after you change the UDCX, you must
go through the "manage data connections" and choose "modify" for that connection and
go through the wizard without changing anything. This will cause InfoPath to re-sync
the schema.
&lt;/p&gt;
&lt;h5&gt;How The Hell Can I Render The Form Version On The Form Itself?
&lt;/h5&gt;
&lt;p&gt;
Tip: insert form version with the expression: substring-before( substring-after( /processing-instruction()[local-name(.)
= "mso-infoPathSolution"], 'solutionVersion="'), '"')
&lt;/p&gt;
&lt;p&gt;
I can’t remember where I got this, I didn’t write it myself. Thanks to the original
author.
&lt;/p&gt;
&lt;h5&gt;Why Can’t SharePoint Find My Forms for my Workflow?
&lt;/h5&gt;
&lt;p&gt;
The Form URN will change if you don't name your form exactly as you did (e.g. accept
the default) in "file &amp;gt; form properties" when publishing it with the publishing
wizard.
&lt;/p&gt;
&lt;h5&gt;Why Can’t My Workflow Forms Find My Data Connections?
&lt;/h5&gt;
&lt;p&gt;
Site relative data connections stored in a data connection library work fine for InfoPath
published forms bound to a content type in a site; also form security will stay at
domain. But they can’t be found if these same forms are used in a workflow. Use “centrally
managed” data connections instead. 
&lt;/p&gt;
&lt;h5&gt;Why Does Visual Studio Put Referenced DLLs Bound For the GAC Into My InfoPath
XSN?
&lt;/h5&gt;
&lt;p&gt;
If you reference other feature projects in the same solution that deploy into GAC,
be sure that they exist in the GAC &lt;strong&gt;before&lt;/strong&gt; building the InfoPath project's
XSN - if they are not in the GAC, they will be copied into the XSN by default. Duh.
&lt;/p&gt;
&lt;h5&gt;How Do I Uninstall My Workflow I was Debugging In Visual Studio?
&lt;/h5&gt;
&lt;p&gt;
Workflow features deployed via vs2008 F5/start debugging have no obvious means of
being "undeployed." you must use &lt;a target="_blank" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=46B6BF86-E35D-4870-B214-4D7B72B02BF9"&gt;VSTO
1.0 PowerTools&lt;/a&gt; "Feature Sweeper" to remove it; this is a dependency for workflow
forms registered in central admin.
&lt;/p&gt;
&lt;h5&gt;Why Are The TaskProperties Hashtables So Weird?
&lt;/h5&gt;
&lt;p&gt;
ExtendedProperties Hashtables leaves root XML fields as keys, and nested xml as my:schema
formatted XML for Hashtable values. Strangely, the Workflow API has a public XmlToHashtable
method on a utility class, but not the inverse to pull it back out of ExtendedProperties.
Duh. 
&lt;/p&gt;
&lt;h5&gt;Where The Hell Did The Form Publish Menu Disappear to?
&lt;/h5&gt;
&lt;p&gt;
You cannot publish the InfoPath form unless you have the designer open, even though
you can only have one form per project and you might just have a single project in
the solution. This is annoying when your forms are large and sluggish to open.
&lt;/p&gt;
&lt;h5 align="left"&gt;Why do some VS SharePoint Activities have a User (string) property
and others a UserID (int) property?
&lt;/h5&gt;
&lt;p&gt;
I wish I knew. This is just another silly design (in)decision. All SPUsers in SharePoint
have both a Login (string) and a PrincipalID (int). If you want to set the Logging
Activity’s UserId (int) to the id of a person who performed a Workflow Modification
User (string), you have to convert, persist and expose these properties yourselves
before you can bind to an activity using the designer. Duh.
&lt;/p&gt;
&lt;p&gt;
I use a method like this:
&lt;/p&gt;
&lt;code style="display: block; font-size: 10pt"&gt;id = Contact.FromName(executor, this.workflowProperties.Web).PrincipalID;&lt;/code&gt; 
&lt;h5&gt;
&lt;/h5&gt;
&lt;h5&gt;Why is Visual Studio 2008&amp;nbsp; SP1’s Workflow Designer Host still such a dog? 
&lt;/h5&gt;
&lt;p&gt;
You and &lt;a target="_blank" href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3808068&amp;amp;SiteID=1"&gt;thousands
of other people&lt;/a&gt; would love to know the answer. IMHO, it’s too complex to have
been written in Managed Code (e.g. C#). It should have been native C++ from day one.
All that synchronizing intellisense, XOML and the visual designer is just too much
for it. God help you if you throw in any real-time refactoring tools on top of that. 
&lt;/p&gt;
&lt;h3&gt;Summary
&lt;/h3&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Despite all this moaning, SharePoint in conjunction with Visual Studio 2008 is a powerful
combination. Nothing to be sniffed at all; I actually love it (most of the time.)
&lt;/p&gt;
&lt;p&gt;
Have fun.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=a14ab954-281f-4424-adbb-5b2032104628" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,a14ab954-281f-4424-adbb-5b2032104628.aspx</comments>
      <category>.NET</category>
      <category>InfoPath</category>
      <category>SharePoint</category>
      <category>Visual Studio</category>
      <category>VSTO 3.0</category>
      <category>XML</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=d340c0ef-8353-4c7a-80b2-f730cc349ef2</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,d340c0ef-8353-4c7a-80b2-f730cc349ef2.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,d340c0ef-8353-4c7a-80b2-f730cc349ef2.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=d340c0ef-8353-4c7a-80b2-f730cc349ef2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Resharper (or R#) is an absolute gem of a tool. After using it for a year, I really
don’t know how I got along without before. If you write code in .NET (C# or VB.NET),
you owe it to yourself to try it out. Version 4.0 was the first to support C# 3.0:
</p>
        <blockquote>
          <p>
ReSharper 4 Full Edition and C# Edition extend language support to C# 3.0, including
LINQ, implicitly typed locals and arrays, extension methods, automatic properties,
lambda expressions, object &amp; collection initializers, anonymous types, expression
trees, and partial methods. ReSharper not only analyzes the new constructs, but provides
C# 3.0-related enhancements in a number of areas — specifically, warnings, suggestions,
code completion options, refactorings, and templates.
</p>
        </blockquote>
        <p align="left">
The guys at <a target="_blank" href="http://www.jetbrains.com">Jetbrains</a> just
released versus 4.1. They offer a free thirty-day trial over at <a title="http://www.jetbrains.com/resharper/" href="http://www.jetbrains.com/resharper/">http://www.jetbrains.com/resharper/</a> –
do it!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=d340c0ef-8353-4c7a-80b2-f730cc349ef2" />
      </body>
      <title>Resharper 4.1 is released</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,d340c0ef-8353-4c7a-80b2-f730cc349ef2.aspx</guid>
      <link>http://www.nivot.org/2008/09/14/Resharper41IsReleased.aspx</link>
      <pubDate>Sun, 14 Sep 2008 19:15:12 GMT</pubDate>
      <description>&lt;p&gt;
Resharper (or R#) is an absolute gem of a tool. After using it for a year, I really
don’t know how I got along without before. If you write code in .NET (C# or VB.NET),
you owe it to yourself to try it out. Version 4.0 was the first to support C# 3.0:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
ReSharper 4 Full Edition and C# Edition extend language support to C# 3.0, including
LINQ, implicitly typed locals and arrays, extension methods, automatic properties,
lambda expressions, object &amp;amp; collection initializers, anonymous types, expression
trees, and partial methods. ReSharper not only analyzes the new constructs, but provides
C# 3.0-related enhancements in a number of areas — specifically, warnings, suggestions,
code completion options, refactorings, and templates.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p align="left"&gt;
The guys at &lt;a target="_blank" href="http://www.jetbrains.com"&gt;Jetbrains&lt;/a&gt; just
released versus 4.1. They offer a free thirty-day trial over at &lt;a title="http://www.jetbrains.com/resharper/" href="http://www.jetbrains.com/resharper/"&gt;http://www.jetbrains.com/resharper/&lt;/a&gt; –
do it!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=d340c0ef-8353-4c7a-80b2-f730cc349ef2" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,d340c0ef-8353-4c7a-80b2-f730cc349ef2.aspx</comments>
      <category>.NET</category>
      <category>LINQ</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=75d3d044-495a-4ec2-a417-7f14db9cd548</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,75d3d044-495a-4ec2-a417-7f14db9cd548.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,75d3d044-495a-4ec2-a417-7f14db9cd548.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=75d3d044-495a-4ec2-a417-7f14db9cd548</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
Are you sick and tired of switching the VMWare virtual network adapters from the “public”
network profile to a “private” network profile each time you reboot or do something
else that causes Vista/Win2008 to forget what you told it to do ten minutes ago? This
is probably a familiar sigh (I’m using Workstation):
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/VMWareVMNETAdaptersShowingasUnidentified_9E9E/vmware-unidentified-network_2.png">
            <img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="vmware-unidentified-network" border="0" alt="vmware-unidentified-network" src="http://www.nivot.org/content/binary/WindowsLiveWriter/VMWareVMNETAdaptersShowingasUnidentified_9E9E/vmware-unidentified-network_thumb.png" width="640" height="432" />
          </a>
        </p>
        <p>
As you can see, the lower two connections are seen to be in a “Public network.” This
has the net effect of making Windows believe the whole machine is exposed to a public
network, and it will trigger the public profile for Windows Firewall. This is normally
a good thing, but in this case it’s just an annoyance. These two network connections
are not actually external gateways that can let in the bad guys. They are just dummy
adapters for VMWare’s host bridging which allow the virtual machine to access the
host machine’s network. Because they don’t identify themselves properly, they are
flagged as an “unidentified network,” and your changes are never persisted. 
</p>
        <p>
So what do you do? The magic information is buried in <a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb201634.aspx">MSDN</a>:
</p>
        <blockquote>
          <p>
Vista automatically identifies and monitors the networks to which a computer connects.
If the NDIS_DEVICE_TYPE_ENDPOINT flag is set, the device is an endpoint device and
is not a connection to a true external network. Consequently, Windows ignores the
endpoint device when Windows identifies networks. The Network Awareness APIs indicate
that the device does not connect the computer to a network. For end users in this
situation, the Network and Sharing Center and the network icon in the notification
area do not show the NDIS endpoint device as connected. However, the connection is
shown in the Network Connections Folder. Also, if NDIS_DEVICE_TYPE_ENDPOINT is set,
the Windows Firewall ignores the connection when Windows Firewall enforces public,
private, or domain policies. 
</p>
        </blockquote>
        <p>
So I hacked together a <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> script
that will scan your adapters for VMWare’s virtual NICs and make the necessary registry
changes. It will also disable/enable cycle the adapters so that the changes take effect.
After this is done, you will see them in your Network Connections page – albeit lacking
a network category -- and the connections will no longer appear in the Network and
Sharing Center nor will they affect your Windows Firewall policy no matter how many
times you reboot!<!-- Stylesheet link --></p>
        <link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" />
        <!-- Code -->
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/VMWareVMNETAdaptersShowingasUnidentified_9E9E/vmware-unidentified-network-1_2.png">
            <img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" title="vmware-unidentified-network-1" border="0" alt="vmware-unidentified-network-1" src="http://www.nivot.org/content/binary/WindowsLiveWriter/VMWareVMNETAdaptersShowingasUnidentified_9E9E/vmware-unidentified-network-1_thumb.png" width="644" height="108" />
          </a>
        </p>
        <p>
Here’s the script source below. It requires that you run it in an elevated shell in
order to write the registry changes and cycle the adapters’ enabled state.
</p>
        <div id="hlDiv" class="dp-highlighter">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span class="comment"># see http://msdn2.microsoft.com/en-us/library/bb201634.aspx </span>
                <span>  </span>
              </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># *NdisDeviceType  </span>
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># The type of the device. The default value is
zero, which indicates a standard </span>
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># networking device that connects to a network. </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># </span>
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># Set *NdisDeviceType to NDIS_DEVICE_TYPE_ENDPOINT
(1) if this device is an </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># endpoint device and is not a true network interface
that connects to a network. </span>
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># For example, you must specify NDIS_DEVICE_TYPE_ENDPOINT
for devices such as </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># smart phones that use a networking infrastructure
to communicate to the local </span>
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># computer system but do not provide connectivity
to an external network.  </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># </span>
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># Usage: run in an elevated shell (vista/longhorn)
or as adminstrator (xp/2003). </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># </span>
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># PS&gt; .\fix-vmnet-adapters.ps1 </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># boilerplate elevation check </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="variable">$identity</span>
              <span> = [Security.Principal.WindowsIdentity]::GetCurrent()   </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$principal</span>
              <span> = new-object Security.Principal.WindowsPrincipal </span>
              <span class="variable">$identity</span>
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="variable">$elevated</span>
              <span> = </span>
              <span class="variable">$principal</span>
              <span>.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="keyword">if</span>
              <span> (-not </span>
              <span class="variable">$elevated</span>
              <span>)
{   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$error</span>
              <span> = </span>
              <span class="string">"Sorry,
you need to run this script"</span>
              <span>  </span>
            </li>
            <li>
              <span>    </span>
              <span class="keyword">if</span>
              <span> ([System.Environment]::OSVersion.Version.Major
-gt 5) {   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="variable">$error</span>
              <span> += </span>
              <span class="string">"
in an elevated shell."</span>
              <span>  </span>
            </li>
            <li>
              <span>    } </span>
              <span class="keyword">else</span>
              <span> {   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="variable">$error</span>
              <span> += </span>
              <span class="string">"
as Administrator."</span>
              <span>  </span>
            </li>
            <li>
              <span>    }   </span>
            </li>
            <li class="alt">
              <span>    throw </span>
              <span class="variable">$error</span>
              <span>  </span>
            </li>
            <li>
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="keyword">function</span>
              <span> confirm {   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$host</span>
              <span>.ui.PromptForChoice(</span>
              <span class="string">"Continue"</span>
              <span>, </span>
              <span class="string">"Process
adapter?"</span>
              <span>,   </span>
            </li>
            <li>
              <span>        [Management.Automation.Host.ChoiceDescription[]]@(</span>
              <span class="string">"&amp;No"</span>
              <span>, </span>
              <span class="string">"&amp;Yes"</span>
              <span>),
0) -eq </span>
              <span class="variable">$true</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>}   </span>
            </li>
            <li>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># adapters key </span>
              <span>  </span>
            </li>
            <li>
              <span>pushd </span>
              <span class="string">'hklm:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}'</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li>
              <span>
              </span>
              <span class="comment"># ignore and continue on error </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>dir -ea 0  | % {   </span>
            </li>
            <li>
              <span>    </span>
              <span class="variable">$node</span>
              <span> = </span>
              <span class="variable">$_</span>
              <span>.pspath   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$desc</span>
              <span> = gp </span>
              <span class="variable">$node</span>
              <span> -name
driverdesc   </span>
            </li>
            <li>
              <span>    </span>
              <span class="keyword">if</span>
              <span> (</span>
              <span class="variable">$desc</span>
              <span> -like </span>
              <span class="string">"*vmware*"</span>
              <span>)
{   </span>
            </li>
            <li class="alt">
              <span>        write-host (</span>
              <span class="string">"Found
adapter: {0} "</span>
              <span> -f </span>
              <span class="variable">$desc</span>
              <span>.driverdesc)   </span>
            </li>
            <li>
              <span>        </span>
              <span class="keyword">if</span>
              <span> (confirm)
{   </span>
            </li>
            <li class="alt">
              <span>            new-itemproperty </span>
              <span class="variable">$node</span>
              <span> -name </span>
              <span class="string">'*NdisDeviceType'</span>
              <span> -propertytype
dword -value 1   </span>
            </li>
            <li>
              <span>        }   </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li>
              <span>}   </span>
            </li>
            <li class="alt">
              <span>popd   </span>
            </li>
            <li>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># disable/enable network adapters </span>
              <span>  </span>
            </li>
            <li>
              <span>gwmi win32_networkadapter | ? {</span>
              <span class="variable">$_</span>
              <span>.name
-like </span>
              <span class="string">"*vmware*"</span>
              <span> } | % {   </span>
            </li>
            <li class="alt">
              <span>       </span>
            </li>
            <li>
              <span>    </span>
              <span class="comment"># disable </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    write-host -nonew </span>
              <span class="string">"Disabling
$($_.name) ... "</span>
              <span>  </span>
            </li>
            <li>
              <span>    </span>
              <span class="variable">$result</span>
              <span> = </span>
              <span class="variable">$_</span>
              <span>.Disable()   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="keyword">if</span>
              <span> (</span>
              <span class="variable">$result</span>
              <span>.ReturnValue
-eq -0) { write-host </span>
              <span class="string">" success."</span>
              <span> } </span>
              <span class="keyword">else</span>
              <span> {
write-host </span>
              <span class="string">" failed."</span>
              <span> }   </span>
            </li>
            <li>
              <span>       </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment"># enable </span>
              <span>  </span>
            </li>
            <li>
              <span>    write-host -nonew </span>
              <span class="string">"Enabling $($_.name)
... "</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$result</span>
              <span> = </span>
              <span class="variable">$_</span>
              <span>.Enable()   </span>
            </li>
            <li>
              <span>    </span>
              <span class="keyword">if</span>
              <span> (</span>
              <span class="variable">$result</span>
              <span>.ReturnValue
-eq -0) { write-host </span>
              <span class="string">" success."</span>
              <span> } </span>
              <span class="keyword">else</span>
              <span> {
write-host </span>
              <span class="string">" failed."</span>
              <span> }   </span>
            </li>
            <li class="alt">
              <span>}   </span>
            </li>
          </ol>
        </div>
        <p>
Have fun.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=75d3d044-495a-4ec2-a417-7f14db9cd548" />
      </body>
      <title>VMWare VMNET Adapters Triggering Public Profile for Windows Firewall</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,75d3d044-495a-4ec2-a417-7f14db9cd548.aspx</guid>
      <link>http://www.nivot.org/2008/09/05/VMWareVMNETAdaptersTriggeringPublicProfileForWindowsFirewall.aspx</link>
      <pubDate>Fri, 05 Sep 2008 20:13:52 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Are you sick and tired of switching the VMWare virtual network adapters from the “public”
network profile to a “private” network profile each time you reboot or do something
else that causes Vista/Win2008 to forget what you told it to do ten minutes ago? This
is probably a familiar sigh (I’m using Workstation):
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/VMWareVMNETAdaptersShowingasUnidentified_9E9E/vmware-unidentified-network_2.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="vmware-unidentified-network" border="0" alt="vmware-unidentified-network" src="http://www.nivot.org/content/binary/WindowsLiveWriter/VMWareVMNETAdaptersShowingasUnidentified_9E9E/vmware-unidentified-network_thumb.png" width="640" height="432"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
As you can see, the lower two connections are seen to be in a “Public network.” This
has the net effect of making Windows believe the whole machine is exposed to a public
network, and it will trigger the public profile for Windows Firewall. This is normally
a good thing, but in this case it’s just an annoyance. These two network connections
are not actually external gateways that can let in the bad guys. They are just dummy
adapters for VMWare’s host bridging which allow the virtual machine to access the
host machine’s network. Because they don’t identify themselves properly, they are
flagged as an “unidentified network,” and your changes are never persisted. 
&lt;/p&gt;
&lt;p&gt;
So what do you do? The magic information is buried in &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb201634.aspx"&gt;MSDN&lt;/a&gt;:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Vista automatically identifies and monitors the networks to which a computer connects.
If the NDIS_DEVICE_TYPE_ENDPOINT flag is set, the device is an endpoint device and
is not a connection to a true external network. Consequently, Windows ignores the
endpoint device when Windows identifies networks. The Network Awareness APIs indicate
that the device does not connect the computer to a network. For end users in this
situation, the Network and Sharing Center and the network icon in the notification
area do not show the NDIS endpoint device as connected. However, the connection is
shown in the Network Connections Folder. Also, if NDIS_DEVICE_TYPE_ENDPOINT is set,
the Windows Firewall ignores the connection when Windows Firewall enforces public,
private, or domain policies. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
So I hacked together a &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; script
that will scan your adapters for VMWare’s virtual NICs and make the necessary registry
changes. It will also disable/enable cycle the adapters so that the changes take effect.
After this is done, you will see them in your Network Connections page – albeit lacking
a network category -- and the connections will no longer appear in the Network and
Sharing Center nor will they affect your Windows Firewall policy no matter how many
times you reboot!&lt;!-- Stylesheet link --&gt;
&lt;link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css"&gt;
&lt;!-- Code --&gt;&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/VMWareVMNETAdaptersShowingasUnidentified_9E9E/vmware-unidentified-network-1_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" title="vmware-unidentified-network-1" border="0" alt="vmware-unidentified-network-1" src="http://www.nivot.org/content/binary/WindowsLiveWriter/VMWareVMNETAdaptersShowingasUnidentified_9E9E/vmware-unidentified-network-1_thumb.png" width="644" height="108"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Here’s the script source below. It requires that you run it in an elevated shell in
order to write the registry changes and cycle the adapters’ enabled state.
&lt;/p&gt;
&lt;div id="hlDiv" class="dp-highlighter"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="comment"&gt;# see http://msdn2.microsoft.com/en-us/library/bb201634.aspx &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# *NdisDeviceType&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# The type of the device. The default value is
zero, which indicates a standard &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# networking device that connects to a network. &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# Set *NdisDeviceType to NDIS_DEVICE_TYPE_ENDPOINT
(1) if this device is an &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# endpoint device and is not a true network interface
that connects to a network. &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# For example, you must specify NDIS_DEVICE_TYPE_ENDPOINT
for devices such as &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# smart phones that use a networking infrastructure
to communicate to the local &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# computer system but do not provide connectivity
to an external network.&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# Usage: run in an elevated shell (vista/longhorn)
or as adminstrator (xp/2003). &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# PS&amp;gt; .\fix-vmnet-adapters.ps1 &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# boilerplate elevation check &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$identity&lt;/span&gt;&lt;span&gt; = [Security.Principal.WindowsIdentity]::GetCurrent()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$principal&lt;/span&gt;&lt;span&gt; = new-object Security.Principal.WindowsPrincipal &lt;/span&gt;&lt;span class="variable"&gt;$identity&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$elevated&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$principal&lt;/span&gt;&lt;span&gt;.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (-not &lt;/span&gt;&lt;span class="variable"&gt;$elevated&lt;/span&gt;&lt;span&gt;)
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$error&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="string"&gt;"Sorry,
you need to run this script"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; ([System.Environment]::OSVersion.Version.Major
-gt 5) {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$error&lt;/span&gt;&lt;span&gt; += &lt;/span&gt;&lt;span class="string"&gt;"
in an elevated shell."&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/span&gt;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt; {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$error&lt;/span&gt;&lt;span&gt; += &lt;/span&gt;&lt;span class="string"&gt;"
as Administrator."&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw &lt;/span&gt;&lt;span class="variable"&gt;$error&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;function&lt;/span&gt;&lt;span&gt; confirm {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$host&lt;/span&gt;&lt;span&gt;.ui.PromptForChoice(&lt;/span&gt;&lt;span class="string"&gt;"Continue"&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="string"&gt;"Process
adapter?"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Management.Automation.Host.ChoiceDescription[]]@(&lt;/span&gt;&lt;span class="string"&gt;"&amp;amp;No"&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="string"&gt;"&amp;amp;Yes"&lt;/span&gt;&lt;span&gt;),
0) -eq &lt;/span&gt;&lt;span class="variable"&gt;$true&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# adapters key &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;pushd &lt;/span&gt;&lt;span class="string"&gt;'hklm:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}'&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# ignore and continue on error &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;dir -ea 0&amp;nbsp; | % {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$node&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.pspath&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$desc&lt;/span&gt;&lt;span&gt; = gp &lt;/span&gt;&lt;span class="variable"&gt;$node&lt;/span&gt;&lt;span&gt; -name
driverdesc&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$desc&lt;/span&gt;&lt;span&gt; -like &lt;/span&gt;&lt;span class="string"&gt;"*vmware*"&lt;/span&gt;&lt;span&gt;)
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; write-host (&lt;/span&gt;&lt;span class="string"&gt;"Found
adapter: {0} "&lt;/span&gt;&lt;span&gt; -f &lt;/span&gt;&lt;span class="variable"&gt;$desc&lt;/span&gt;&lt;span&gt;.driverdesc)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (confirm)
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new-itemproperty &lt;/span&gt;&lt;span class="variable"&gt;$node&lt;/span&gt;&lt;span&gt; -name &lt;/span&gt;&lt;span class="string"&gt;'*NdisDeviceType'&lt;/span&gt;&lt;span&gt; -propertytype
dword -value 1&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;popd&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# disable/enable network adapters &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;gwmi win32_networkadapter | ? {&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.name
-like &lt;/span&gt;&lt;span class="string"&gt;"*vmware*"&lt;/span&gt;&lt;span&gt; } | % {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# disable &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; write-host -nonew &lt;/span&gt;&lt;span class="string"&gt;"Disabling
$($_.name) ... "&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$result&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Disable()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$result&lt;/span&gt;&lt;span&gt;.ReturnValue
-eq -0) { write-host &lt;/span&gt;&lt;span class="string"&gt;" success."&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt; {
write-host &lt;/span&gt;&lt;span class="string"&gt;" failed."&lt;/span&gt;&lt;span&gt; }&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# enable &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; write-host -nonew &lt;/span&gt;&lt;span class="string"&gt;"Enabling $($_.name)
... "&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$result&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Enable()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$result&lt;/span&gt;&lt;span&gt;.ReturnValue
-eq -0) { write-host &lt;/span&gt;&lt;span class="string"&gt;" success."&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt; {
write-host &lt;/span&gt;&lt;span class="string"&gt;" failed."&lt;/span&gt;&lt;span&gt; }&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
Have fun.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=75d3d044-495a-4ec2-a417-7f14db9cd548" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,75d3d044-495a-4ec2-a417-7f14db9cd548.aspx</comments>
      <category>.NET</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>Vista</category>
      <category>VMWare</category>
      <category>WMI</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=b66c3399-69ae-48cf-9c3a-7264c7ff459b</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,b66c3399-69ae-48cf-9c3a-7264c7ff459b.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,b66c3399-69ae-48cf-9c3a-7264c7ff459b.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=b66c3399-69ae-48cf-9c3a-7264c7ff459b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The new eventing infrastructure in <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> 2.0
is pretty delicious. You couldn’t do the following in 1.0 without a 3rd party snap-in
(like my <a href="http://www.codeplex.com/PSEventing" target="_blank">PSEventing</a> snapin),
but now it’s all there at the touch of your fingers. Well, it demands a bit of a sniff
around WMI too, but hey, it works well.  With this module, anytime you add or
remove a removable device like an external harddrive or USB key, or map a new network
drive in explorer, PowerShell will now automatically add or remove a corresponding
PSDrive for you.
</p>
        <!-- Stylesheet link -->
        <link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet" />
        <!-- Code -->
        <div class="dp-highlighter" id="hlDiv">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span class="comment"># AutoMount.psm1 v1.0 </span>
                <span>  </span>
              </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># Oisin "x0n" Grehan (MVP) </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$query</span>
              <span> = new-object System.Management.WqlEventQuery   </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$query</span>
              <span>.EventClassName = </span>
              <span class="string">"__InstanceOperationEvent"</span>
              <span>  </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># default to every 2 seconds </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$query</span>
              <span>.WithinInterval = new-object
System.TimeSpan 0,0,2   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># this WMI is only available with Windows 2003
and Vista (not XP it appears). </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># this could be rewritten to use different WMI
queries to support 2000/NT/XP also. </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$query</span>
              <span>.QueryString = </span>
              <span class="string">"Select
* from Win32_VolumeChangeEvent"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># attach a watcher </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$watcher</span>
              <span> = new-object System.Management.ManagementEventWatcher </span>
              <span class="variable">$query</span>
              <span>  </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># here we use -SupportEvent instead of -SourceIdentifier </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># this prevents this event from being generally
visible </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># also note the use of the call operator to invoke
a  </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># function in the scope of the module since this
action </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># occurs outside of module scope. </span>
              <span>  </span>
            </li>
            <li class="">
              <span>Register-ObjectEvent </span>
              <span class="variable">$watcher</span>
              <span> -EventName </span>
              <span class="string">"EventArrived"</span>
              <span> `   </span>
            </li>
            <li class="alt">
              <span>    -SupportEvent </span>
              <span class="string">"WMI.VolumeChange"</span>
              <span> -Action
{   </span>
            </li>
            <li class="">
              <span>        &amp; (get-module automount) VolumeChangeCallback </span>
              <span class="variable">@args</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># New PSEvents: </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment">#     PowerShell.DeviceConfigurationChanged </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment">#     PowerShell.DeviceArrived </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment">#     PowerShell.DeviceRemoved </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment">#     PowerShell.DeviceDocking </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># win32_volumechangeevent event types </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$eventTypes</span>
              <span> = @{   </span>
            </li>
            <li class="">
              <span>    1 = </span>
              <span class="string">"ConfigurationChanged"</span>
              <span>;   </span>
            </li>
            <li class="alt">
              <span>    2 = </span>
              <span class="string">"Arrived"</span>
              <span>;   </span>
            </li>
            <li class="">
              <span>    3 = </span>
              <span class="string">"Removed"</span>
              <span>;   </span>
            </li>
            <li class="alt">
              <span>    4 = </span>
              <span class="string">"Docking"</span>
              <span>;   </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># private module level callback function </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="keyword">function</span>
              <span> VolumeChangeCallback (</span>
              <span class="variable">$sender</span>
              <span>, </span>
              <span class="variable">$eventargs</span>
              <span>)
{   </span>
            </li>
            <li class="">
              <span>    trap { write-warning </span>
              <span class="variable">$_</span>
              <span> }   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="variable">$driveName</span>
              <span> = </span>
              <span class="variable">$eventArgs</span>
              <span>.NewEvent.DriveName.TrimEnd(</span>
              <span class="string">":"</span>
              <span>)   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$eventType</span>
              <span> = [int]</span>
              <span class="variable">$eventArgs</span>
              <span>.NewEvent.EventType </span>
              <span class="comment">#
was uint16 </span>
              <span>  </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$forwardedEvent</span>
              <span> = </span>
              <span class="string">"Device$($eventTypes[$eventType])"</span>
              <span>  </span>
            </li>
            <li class="">
              <span>       </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="comment"># forward a new simpler event
specific to device event type </span>
              <span>  </span>
            </li>
            <li class="">
              <span>    [void]( New-PSEvent </span>
              <span class="string">"PowerShell.$forwardedEvent"</span>
              <span> -Sender </span>
              <span class="variable">$driveName</span>
              <span> `   </span>
            </li>
            <li class="alt">
              <span>        -EventArguments </span>
              <span class="variable">$eventargs</span>
              <span> )   </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># hook up our psdrive mount / unmount events </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># and start the WMI watcher </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="keyword">function</span>
              <span> Enable-AutoMount {   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    Register-PSEvent -SourceIdentifier </span>
              <span class="string">"PowerShell.DeviceArrived"</span>
              <span> `   </span>
            </li>
            <li class="alt">
              <span>        -Action {               </span>
            </li>
            <li class="">
              <span>            new-psdrive
-name </span>
              <span class="variable">$args</span>
              <span>[0] -psprovider `   </span>
            </li>
            <li class="alt">
              <span>               
filesystem -root </span>
              <span class="string">"$args[0]:"</span>
              <span>;   </span>
            </li>
            <li class="">
              <span>         }   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    Register-PSEvent -SourceIdentifier </span>
              <span class="string">"PowerShell.DeviceRemoved"</span>
              <span> `   </span>
            </li>
            <li class="alt">
              <span>        -Action {   </span>
            </li>
            <li class="">
              <span>            remove-psdrive
-name </span>
              <span class="variable">$args</span>
              <span>[0] -ea 0; </span>
              <span class="comment">#
may not exist </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>        }   </span>
            </li>
            <li class="">
              <span>       </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$watcher</span>
              <span>.Start()   </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># tear down our psdrive mount / unmount events </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># and stop the WMI watcher </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="keyword">function</span>
              <span> Disable-AutoMount {   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    Unregister-PSEvent -SourceIdentifier </span>
              <span class="string">"PowerShell.DeviceArrived"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    Unregister-PSEvent -SourceIdentifier </span>
              <span class="string">"PowerShell.DeviceRemoved"</span>
              <span>  </span>
            </li>
            <li class="">
              <span>       </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$watcher</span>
              <span>.Stop()   </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># export functions to control automount </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>Export-ModuleMember Enable-AutoMount, Disable-AutoMount   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># start watching and (un)mounting </span>
              <span>  </span>
            </li>
            <li class="">
              <span>Enable-AutoMount  </span>
            </li>
          </ol>
        </div>
        <ul>
          <li>
            <a href="http://www.poshcode.org/525" target="_blank">
              <strong>Link to PoshCode Copy</strong>
            </a>
          </li>
        </ul>
        <p>
This only works PowerShell v2.0 CTP2, and you’ll need to save it as AutoMount.psm1
in a directory under your documents folder like so (vista example):
</p>
        <p>
%userprofile%\documents\windowspowershell\packages\automount\automount.psm1
</p>
        <p>
You can then load it with the command:
</p>
        <p>
ps&gt; add-module automount
</p>
        <p>
I have this in my profile.  You can temporarily disable automount with the function
Disable-AutoMount and reenable it at anytime with Enable-AutoMount. The module also
exposes four new events for you to consume yourself. You could, for example, hook
your own script to run anytime a device is added and/or removed. This is what I do
myself in the module. I hook a WMI event once then forward 1 of 4 possible new events
depending on the type of WMI event that was raised. 
</p>
        <p>
          <strong>NOTE: </strong>this particular flavour of WMI query only works in Vista and
Windows 2003 it appears. I’m looking into getting it working with 2000/XP also.
</p>
        <p>
Have fun!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=b66c3399-69ae-48cf-9c3a-7264c7ff459b" />
      </body>
      <title>Auto mount/unmount new PSDrives for removable drives and network shares in PowerShell v2</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,b66c3399-69ae-48cf-9c3a-7264c7ff459b.aspx</guid>
      <link>http://www.nivot.org/2008/08/16/AutoMountunmountNewPSDrivesForRemovableDrivesAndNetworkSharesInPowerShellV2.aspx</link>
      <pubDate>Sat, 16 Aug 2008 02:14:47 GMT</pubDate>
      <description>&lt;p&gt;
The new eventing infrastructure in &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; 2.0
is pretty delicious. You couldn’t do the following in 1.0 without a 3rd party snap-in
(like my &lt;a href="http://www.codeplex.com/PSEventing" target="_blank"&gt;PSEventing&lt;/a&gt; snapin),
but now it’s all there at the touch of your fingers. Well, it demands a bit of a sniff
around WMI too, but hey, it works well.&amp;nbsp; With this module, anytime you add or
remove a removable device like an external harddrive or USB key, or map a new network
drive in explorer, PowerShell will now automatically add or remove a corresponding
PSDrive for you.
&lt;/p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet"&gt;
&lt;!-- Code --&gt;
&lt;div class="dp-highlighter" id="hlDiv"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="comment"&gt;# AutoMount.psm1 v1.0 &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# Oisin "x0n" Grehan (MVP) &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$query&lt;/span&gt;&lt;span&gt; = new-object System.Management.WqlEventQuery&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$query&lt;/span&gt;&lt;span&gt;.EventClassName = &lt;/span&gt;&lt;span class="string"&gt;"__InstanceOperationEvent"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# default to every 2 seconds &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$query&lt;/span&gt;&lt;span&gt;.WithinInterval = new-object
System.TimeSpan 0,0,2&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# this WMI is only available with Windows 2003
and Vista (not XP it appears). &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# this could be rewritten to use different WMI
queries to support 2000/NT/XP also. &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$query&lt;/span&gt;&lt;span&gt;.QueryString = &lt;/span&gt;&lt;span class="string"&gt;"Select
* from Win32_VolumeChangeEvent"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# attach a watcher &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$watcher&lt;/span&gt;&lt;span&gt; = new-object System.Management.ManagementEventWatcher &lt;/span&gt;&lt;span class="variable"&gt;$query&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# here we use -SupportEvent instead of -SourceIdentifier &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# this prevents this event from being generally
visible &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# also note the use of the call operator to invoke
a&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# function in the scope of the module since this
action &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# occurs outside of module scope. &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;Register-ObjectEvent &lt;/span&gt;&lt;span class="variable"&gt;$watcher&lt;/span&gt;&lt;span&gt; -EventName &lt;/span&gt;&lt;span class="string"&gt;"EventArrived"&lt;/span&gt;&lt;span&gt; `&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -SupportEvent &lt;/span&gt;&lt;span class="string"&gt;"WMI.VolumeChange"&lt;/span&gt;&lt;span&gt; -Action
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; (get-module automount) VolumeChangeCallback &lt;/span&gt;&lt;span class="variable"&gt;@args&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# New PSEvents: &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PowerShell.DeviceConfigurationChanged &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PowerShell.DeviceArrived &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PowerShell.DeviceRemoved &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PowerShell.DeviceDocking &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# win32_volumechangeevent event types &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$eventTypes&lt;/span&gt;&lt;span&gt; = @{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 = &lt;/span&gt;&lt;span class="string"&gt;"ConfigurationChanged"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2 = &lt;/span&gt;&lt;span class="string"&gt;"Arrived"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3 = &lt;/span&gt;&lt;span class="string"&gt;"Removed"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4 = &lt;/span&gt;&lt;span class="string"&gt;"Docking"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# private module level callback function &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;function&lt;/span&gt;&lt;span&gt; VolumeChangeCallback (&lt;/span&gt;&lt;span class="variable"&gt;$sender&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="variable"&gt;$eventargs&lt;/span&gt;&lt;span&gt;)
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; trap { write-warning &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt; }&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$driveName&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$eventArgs&lt;/span&gt;&lt;span&gt;.NewEvent.DriveName.TrimEnd(&lt;/span&gt;&lt;span class="string"&gt;":"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$eventType&lt;/span&gt;&lt;span&gt; = [int]&lt;/span&gt;&lt;span class="variable"&gt;$eventArgs&lt;/span&gt;&lt;span&gt;.NewEvent.EventType &lt;/span&gt;&lt;span class="comment"&gt;#
was uint16 &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$forwardedEvent&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="string"&gt;"Device$($eventTypes[$eventType])"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# forward a new simpler event
specific to device event type &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [void]( New-PSEvent &lt;/span&gt;&lt;span class="string"&gt;"PowerShell.$forwardedEvent"&lt;/span&gt;&lt;span&gt; -Sender &lt;/span&gt;&lt;span class="variable"&gt;$driveName&lt;/span&gt;&lt;span&gt; `&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -EventArguments &lt;/span&gt;&lt;span class="variable"&gt;$eventargs&lt;/span&gt;&lt;span&gt; )&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# hook up our psdrive mount / unmount events &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# and start the WMI watcher &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;function&lt;/span&gt;&lt;span&gt; Enable-AutoMount {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Register-PSEvent -SourceIdentifier &lt;/span&gt;&lt;span class="string"&gt;"PowerShell.DeviceArrived"&lt;/span&gt;&lt;span&gt; `&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -Action {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new-psdrive
-name &lt;/span&gt;&lt;span class="variable"&gt;$args&lt;/span&gt;&lt;span&gt;[0] -psprovider `&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
filesystem -root &lt;/span&gt;&lt;span class="string"&gt;"$args[0]:"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Register-PSEvent -SourceIdentifier &lt;/span&gt;&lt;span class="string"&gt;"PowerShell.DeviceRemoved"&lt;/span&gt;&lt;span&gt; `&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -Action {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; remove-psdrive
-name &lt;/span&gt;&lt;span class="variable"&gt;$args&lt;/span&gt;&lt;span&gt;[0] -ea 0; &lt;/span&gt;&lt;span class="comment"&gt;#
may not exist &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$watcher&lt;/span&gt;&lt;span&gt;.Start()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# tear down our psdrive mount / unmount events &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# and stop the WMI watcher &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;function&lt;/span&gt;&lt;span&gt; Disable-AutoMount {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Unregister-PSEvent -SourceIdentifier &lt;/span&gt;&lt;span class="string"&gt;"PowerShell.DeviceArrived"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Unregister-PSEvent -SourceIdentifier &lt;/span&gt;&lt;span class="string"&gt;"PowerShell.DeviceRemoved"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$watcher&lt;/span&gt;&lt;span&gt;.Stop()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# export functions to control automount &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;Export-ModuleMember Enable-AutoMount, Disable-AutoMount&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# start watching and (un)mounting &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;Enable-AutoMount&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.poshcode.org/525" target="_blank"&gt;&lt;strong&gt;Link to PoshCode Copy&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
This only works PowerShell v2.0 CTP2, and you’ll need to save it as AutoMount.psm1
in a directory under your documents folder like so (vista example):
&lt;/p&gt;
&lt;p&gt;
%userprofile%\documents\windowspowershell\packages\automount\automount.psm1
&lt;/p&gt;
&lt;p&gt;
You can then load it with the command:
&lt;/p&gt;
&lt;p&gt;
ps&amp;gt; add-module automount
&lt;/p&gt;
&lt;p&gt;
I have this in my profile.&amp;nbsp; You can temporarily disable automount with the function
Disable-AutoMount and reenable it at anytime with Enable-AutoMount. The module also
exposes four new events for you to consume yourself. You could, for example, hook
your own script to run anytime a device is added and/or removed. This is what I do
myself in the module. I hook a WMI event once then forward 1 of 4 possible new events
depending on the type of WMI event that was raised. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;NOTE: &lt;/strong&gt;this particular flavour of WMI query only works in Vista and
Windows 2003 it appears. I’m looking into getting it working with 2000/XP also.
&lt;/p&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=b66c3399-69ae-48cf-9c3a-7264c7ff459b" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,b66c3399-69ae-48cf-9c3a-7264c7ff459b.aspx</comments>
      <category>.NET</category>
      <category>Eventing</category>
      <category>Modules</category>
      <category>Monad</category>
      <category>PowerShell 2.0</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=7ac02da0-f9a0-443e-9f3d-f187e1ea7502</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,7ac02da0-f9a0-443e-9f3d-f187e1ea7502.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,7ac02da0-f9a0-443e-9f3d-f187e1ea7502.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=7ac02da0-f9a0-443e-9f3d-f187e1ea7502</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It’s getting harder to post useful scripting tips for <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShell</a> these
days as there <a href="http://huddledmasses.org/" target="_blank">are</a><a href="http://bsonposh.com/" target="_blank">so</a><a href="http://thepowershellguy.com/blogs/posh/default.aspx" target="_blank">many</a><a href="http://keithhill.spaces.live.com/" target="_blank">talented</a><a href="http://www.proudlyserving.com/" target="_blank">hardcore</a><a href="http://marcoshaw.blogspot.com/" target="_blank">scripting</a><a href="http://dmitrysotnikov.wordpress.com/" target="_blank">bloggers</a> around.
My day to day is job is not system/network/server administrator; I’m a .NET developer,
having started the C# habit about eight or nine years ago with the early CLR 1.0 beta.
So, from here on in, I’ve decided that a better direction for me to take from now
on is that of a PowerShell developer,  as opposed to a scripter. There are very
few (if any?) dedicated PowerShell developer blogs around, and so I figured I should
try to fill that gap as best I can. I have a not insignificant amount of experience
writing providers, cmdlets and other widgety bits, so it’s a good time to share my
experiences. Of course, my way is not “the” way, so please reply with your own experiences/advice/mocking/whatever.
;-)
</p>
        <p>
That said, I am not eschewing scripting altogether – I have some stuff in the pipeline
(har-har) concerning areas I’m interested in, like eventing and jobs/remoting.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=7ac02da0-f9a0-443e-9f3d-f187e1ea7502" />
      </body>
      <title>Time For A Change</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,7ac02da0-f9a0-443e-9f3d-f187e1ea7502.aspx</guid>
      <link>http://www.nivot.org/2008/08/12/TimeForAChange.aspx</link>
      <pubDate>Tue, 12 Aug 2008 14:03:20 GMT</pubDate>
      <description>&lt;p&gt;
It’s getting harder to post useful scripting tips for &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; these
days as there &lt;a href="http://huddledmasses.org/" target="_blank"&gt;are&lt;/a&gt; &lt;a href="http://bsonposh.com/" target="_blank"&gt;so&lt;/a&gt; &lt;a href="http://thepowershellguy.com/blogs/posh/default.aspx" target="_blank"&gt;many&lt;/a&gt; &lt;a href="http://keithhill.spaces.live.com/" target="_blank"&gt;talented&lt;/a&gt; &lt;a href="http://www.proudlyserving.com/" target="_blank"&gt;hardcore&lt;/a&gt; &lt;a href="http://marcoshaw.blogspot.com/" target="_blank"&gt;scripting&lt;/a&gt; &lt;a href="http://dmitrysotnikov.wordpress.com/" target="_blank"&gt;bloggers&lt;/a&gt; around.
My day to day is job is not system/network/server administrator; I’m a .NET developer,
having started the C# habit about eight or nine years ago with the early CLR 1.0 beta.
So, from here on in, I’ve decided that a better direction for me to take from now
on is that of a PowerShell developer,&amp;nbsp; as opposed to a scripter. There are very
few (if any?) dedicated PowerShell developer blogs around, and so I figured I should
try to fill that gap as best I can. I have a not insignificant amount of experience
writing providers, cmdlets and other widgety bits, so it’s a good time to share my
experiences. Of course, my way is not “the” way, so please reply with your own experiences/advice/mocking/whatever.
;-)
&lt;/p&gt;
&lt;p&gt;
That said, I am not eschewing scripting altogether – I have some stuff in the pipeline
(har-har) concerning areas I’m interested in, like eventing and jobs/remoting.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=7ac02da0-f9a0-443e-9f3d-f187e1ea7502" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,7ac02da0-f9a0-443e-9f3d-f187e1ea7502.aspx</comments>
      <category>.NET</category>
      <category>Cmdlets</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>Providers</category>
      <category>PSCX</category>
      <category>PSEventing</category>
      <category>SharePoint</category>
      <category>SnapIns</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=025fd0be-b50c-4b0e-839f-3881b03677ba</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,025fd0be-b50c-4b0e-839f-3881b03677ba.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,025fd0be-b50c-4b0e-839f-3881b03677ba.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=025fd0be-b50c-4b0e-839f-3881b03677ba</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Just a handy tip - you don't have to cast enum types in powershell usually. It will
do that for you if that's the only constructor (or method) overload that makes sense: 
</p>
        <p>
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule $userName,
` 
<br />
     "Modify",  "ContainerInherit,ObjectInherit", "None",
"Allow" 
</p>
        <p>
So when I say "only overload that makes sense," what do I mean by that? Take this
method for example which has two overloads (meaning it has two different sets of parameters
you could use): 
</p>
        <p>
void MyMethod(string a, string b, string c) 
</p>
        <p>
void MyMethod(string a, enum b, string c) 
</p>
        <p>
If you try to call that method with $o.MyMethod("foo", "foo", "foo"), it will pick
the first version that takes three strings. In that case, you would have to cast/convert
the enum to its native type so that powershell will pick the right method. <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=025fd0be-b50c-4b0e-839f-3881b03677ba" /></p>
      </body>
      <title>Tips for using Enumerated Types in PowerShell</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,025fd0be-b50c-4b0e-839f-3881b03677ba.aspx</guid>
      <link>http://www.nivot.org/2008/08/11/TipsForUsingEnumeratedTypesInPowerShell.aspx</link>
      <pubDate>Mon, 11 Aug 2008 16:38:22 GMT</pubDate>
      <description>&lt;p&gt;
Just a handy tip - you don't have to cast enum types in powershell usually. It will
do that for you if that's the only constructor (or method) overload that makes sense: 
&lt;p&gt;
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule $userName,
` 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Modify",&amp;nbsp; "ContainerInherit,ObjectInherit", "None",
"Allow" 
&lt;p&gt;
So when I say "only overload that makes sense," what do I mean by that? Take this
method for example which has two overloads (meaning it has two different sets of parameters
you could use): 
&lt;p&gt;
void MyMethod(string a, string b, string c) 
&lt;p&gt;
void MyMethod(string a, enum b, string c) 
&lt;p&gt;
If you try to call that method with $o.MyMethod("foo", "foo", "foo"), it will pick
the first version that takes three strings. In that case, you would have to cast/convert
the enum to its native type so that powershell will pick the right method. &lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=025fd0be-b50c-4b0e-839f-3881b03677ba" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,025fd0be-b50c-4b0e-839f-3881b03677ba.aspx</comments>
      <category>.NET</category>
      <category>Monad</category>
      <category>PowerShell</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=93f4323a-8ce2-41ad-a165-46f98562f650</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,93f4323a-8ce2-41ad-a165-46f98562f650.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,93f4323a-8ce2-41ad-a165-46f98562f650.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=93f4323a-8ce2-41ad-a165-46f98562f650</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In the latest <a href="http://www.codeplex.com/PowerShellCX" target="_blank">PowerShellCX</a> <a href="http://www.codeplex.com/PowerShellCX/SourceControl/ListDownloadableCommits.aspx" target="_blank">changeset</a>,
archive read and extract support is finally available. Sorry there are no binary builds
yet. Use the Extract-Archive cmdlet as a stand-alone to extract all files. Use Read-Archive
to generate ArchiveEntry objects which can be piped through Where-Object for filtering
and eventual consumption by Extract-Archive (which can accept ArchiveEntry as well
as FileInfo pipeline input). I’ve got progress reporting working too for extract.
I’ve added support for reading/extracting SevenZip, Arj, BZip2, Cab, Chm, Cpio, Deb,
GZip, Iso, Lzh, Lzma, Nsis, Rar, Rpm, Tar, Wim, Z &amp; Zip.  Yes, you did see
ISO support in that list ;-) Write support is only zip, bzip2, tar and gzip still.
</p>
        <p>
There are more features coming, including encrypted archive support.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=93f4323a-8ce2-41ad-a165-46f98562f650" />
      </body>
      <title>Pscx 1.2 progress &amp;ndash; archive read and extract support coming</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,93f4323a-8ce2-41ad-a165-46f98562f650.aspx</guid>
      <link>http://www.nivot.org/2008/07/28/Pscx12ProgressNdashArchiveReadAndExtractSupportComing.aspx</link>
      <pubDate>Mon, 28 Jul 2008 09:28:00 GMT</pubDate>
      <description>&lt;p&gt;
In the latest &lt;a href="http://www.codeplex.com/PowerShellCX" target="_blank"&gt;PowerShellCX&lt;/a&gt;&amp;nbsp;&lt;a href="http://www.codeplex.com/PowerShellCX/SourceControl/ListDownloadableCommits.aspx" target="_blank"&gt;changeset&lt;/a&gt;,
archive read and extract support is finally available. Sorry there are no binary builds
yet. Use the Extract-Archive cmdlet as a stand-alone to extract all files. Use Read-Archive
to generate ArchiveEntry objects which can be piped through Where-Object for filtering
and eventual consumption by Extract-Archive (which can accept ArchiveEntry as well
as FileInfo pipeline input). I’ve got progress reporting working too for extract.
I’ve added support for reading/extracting SevenZip, Arj, BZip2, Cab, Chm, Cpio, Deb,
GZip, Iso, Lzh, Lzma, Nsis, Rar, Rpm, Tar, Wim, Z &amp;amp; Zip.&amp;nbsp; Yes, you did see
ISO support in that list ;-) Write support is only zip, bzip2, tar and gzip still.
&lt;/p&gt;
&lt;p&gt;
There are more features coming, including encrypted archive support.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=93f4323a-8ce2-41ad-a165-46f98562f650" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,93f4323a-8ce2-41ad-a165-46f98562f650.aspx</comments>
      <category>.NET</category>
      <category>CodePlex</category>
      <category>Monad</category>
      <category>PowerShell</category>
      <category>PSCX</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=c4439da9-a64c-459f-9376-b7f629fa2130</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,c4439da9-a64c-459f-9376-b7f629fa2130.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,c4439da9-a64c-459f-9376-b7f629fa2130.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=c4439da9-a64c-459f-9376-b7f629fa2130</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just hacked this one up a few minutes ago to let me get an Oracle, Access, Excel/CSV
or SQL Server database connection quickly without fiddling with provider strings and
other things that just fall out of my head as fast as they get put in. It uses an
old trick of creating a zero-length file with an UDL extension and then executing
it. The function returns an operable OleDbConnection object, albeit a closed one unless
you specifiy –Open as a switch.
</p>
        <!-- Stylesheet link -->
        <link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet" />
        <!-- Code -->
        <div class="dp-highlighter" id="hlDiv">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span class="keyword">function</span>
                <span> get-oledbconnection ([</span>
                <span class="keyword">switch</span>
                <span>]</span>
                <span class="variable">$Open</span>
                <span>)
{   </span>
              </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="variable">$null</span>
              <span> | set-content
(</span>
              <span class="variable">$udl</span>
              <span> = </span>
              <span class="string">"$([io.path]::GetTempPath())\temp.udl"</span>
              <span>);   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$psi</span>
              <span> = new-object
Diagnostics.ProcessStartInfo   </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="variable">$psi</span>
              <span>.CreateNoWindow
= </span>
              <span class="variable">$true</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$psi</span>
              <span>.UseShellExecute
= </span>
              <span class="variable">$true</span>
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="variable">$psi</span>
              <span>.FileName
= </span>
              <span class="variable">$udl</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$pi</span>
              <span> = [System.Diagnostics.Process]::Start(</span>
              <span class="variable">$psi</span>
              <span>)   </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="variable">$pi</span>
              <span>.WaitForExit()   </span>
            </li>
            <li class="alt">
              <span>    write-host (gc </span>
              <span class="variable">$udl</span>
              <span>)   </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">if</span>
              <span> (gc </span>
              <span class="variable">$udl</span>
              <span>)
{   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="variable">$conn</span>
              <span> =
new-object data.oledb.oledbconnection (gc </span>
              <span class="variable">$udl</span>
              <span>)[2]   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">if</span>
              <span> (</span>
              <span class="variable">$Open</span>
              <span>)
{ </span>
              <span class="variable">$conn</span>
              <span>.Open() }   </span>
            </li>
            <li class="alt">
              <span>    }   </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="variable">$conn</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>}   </span>
            </li>
          </ol>
        </div>
        <p>
You’ll notice I said OleDbConnection. This means you should pick an OLEDB provider
on the provider page for best (read: working) results. Cancelling returns nothing.
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/GetaquickdatabaseconnectionwithaniceGUI_11DB3/image_4.png">
            <img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="587" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/GetaquickdatabaseconnectionwithaniceGUI_11DB3/image_thumb_1.png" width="570" border="0" />
          </a>
        </p>
        <p>
Ah, how I love the little blue box of typographical terrific-ness.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=c4439da9-a64c-459f-9376-b7f629fa2130" />
      </body>
      <title>Get a quick database connection with a nice GUI</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,c4439da9-a64c-459f-9376-b7f629fa2130.aspx</guid>
      <link>http://www.nivot.org/2008/07/10/GetAQuickDatabaseConnectionWithANiceGUI.aspx</link>
      <pubDate>Thu, 10 Jul 2008 00:18:44 GMT</pubDate>
      <description>&lt;p&gt;
I just hacked this one up a few minutes ago to let me get an Oracle, Access, Excel/CSV
or SQL Server database connection quickly without fiddling with provider strings and
other things that just fall out of my head as fast as they get put in. It uses an
old trick of creating a zero-length file with an UDL extension and then executing
it. The function returns an operable OleDbConnection object, albeit a closed one unless
you specifiy –Open as a switch.
&lt;/p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet"&gt;
&lt;!-- Code --&gt;
&lt;div class="dp-highlighter" id="hlDiv"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="keyword"&gt;function&lt;/span&gt;&lt;span&gt; get-oledbconnection ([&lt;/span&gt;&lt;span class="keyword"&gt;switch&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class="variable"&gt;$Open&lt;/span&gt;&lt;span&gt;)
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$null&lt;/span&gt;&lt;span&gt; | set-content
(&lt;/span&gt;&lt;span class="variable"&gt;$udl&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="string"&gt;"$([io.path]::GetTempPath())\temp.udl"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$psi&lt;/span&gt;&lt;span&gt; = new-object
Diagnostics.ProcessStartInfo&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$psi&lt;/span&gt;&lt;span&gt;.CreateNoWindow
= &lt;/span&gt;&lt;span class="variable"&gt;$true&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$psi&lt;/span&gt;&lt;span&gt;.UseShellExecute
= &lt;/span&gt;&lt;span class="variable"&gt;$true&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$psi&lt;/span&gt;&lt;span&gt;.FileName
= &lt;/span&gt;&lt;span class="variable"&gt;$udl&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$pi&lt;/span&gt;&lt;span&gt; = [System.Diagnostics.Process]::Start(&lt;/span&gt;&lt;span class="variable"&gt;$psi&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$pi&lt;/span&gt;&lt;span&gt;.WaitForExit()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; write-host (gc &lt;/span&gt;&lt;span class="variable"&gt;$udl&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (gc &lt;/span&gt;&lt;span class="variable"&gt;$udl&lt;/span&gt;&lt;span&gt;)
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$conn&lt;/span&gt;&lt;span&gt; =
new-object data.oledb.oledbconnection (gc &lt;/span&gt;&lt;span class="variable"&gt;$udl&lt;/span&gt;&lt;span&gt;)[2]&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$Open&lt;/span&gt;&lt;span&gt;)
{ &lt;/span&gt;&lt;span class="variable"&gt;$conn&lt;/span&gt;&lt;span&gt;.Open() }&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$conn&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
You’ll notice I said OleDbConnection. This means you should pick an OLEDB provider
on the provider page for best (read: working) results. Cancelling returns nothing.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/GetaquickdatabaseconnectionwithaniceGUI_11DB3/image_4.png"&gt;&lt;img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="587" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/GetaquickdatabaseconnectionwithaniceGUI_11DB3/image_thumb_1.png" width="570" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Ah, how I love the little blue box of typographical terrific-ness.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=c4439da9-a64c-459f-9376-b7f629fa2130" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,c4439da9-a64c-459f-9376-b7f629fa2130.aspx</comments>
      <category>.NET</category>
      <category>Database</category>
      <category>Monad</category>
      <category>PowerShell</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=cb3d0ce6-5acb-4257-9939-121ced333507</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,cb3d0ce6-5acb-4257-9939-121ced333507.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,cb3d0ce6-5acb-4257-9939-121ced333507.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=cb3d0ce6-5acb-4257-9939-121ced333507</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
Why do such a thing? Well, if you’ve created your own aliases for commands and you
try to give someone your ps1 script file, it will not run because they have not got
the same aliases defined as you. Also, scripts that use fully-resolved names like
“Get-ChildItem” are more readable for a newcomer to PowerShell than one that is using
the unix-like “ls" alias for example. "Get-ChildItem" leads quite directly to the
MSDN documentation, but "ls" might lead you anywhere. Before you publish a script
online somewhere for the world to use, it’s important that you try to remove any aliases
and replace them with the native command names.
</p>
        <p>
Doing this kind of thing has been talked about before but it was always a very difficult
thing to do with PowerShell v1.0, what with the lack of <a href="http://en.wikipedia.org/wiki/Backus-Naur_form" target="_blank">BNF</a> documentation
describing the grammar etc. Thankfully, it's a lot easier to do with PowerShell v2.0
(currently at release CTP2) because the team has exposed the <a href="http://en.wikipedia.org/wiki/Lexical_analysis" target="_blank">Tokenizer</a> for
use in scripts. There's been suprisingly little use of it so far, so I figured I'd
start the ball rolling with a series of articles based around it. So, let's look at
an example script that uses aliases and put it through the meat grinder:
</p>
        <p>
          <a href="http://www.nivot.org/content/binary/WindowsLiveWriter/PSParserTricks1ResolveallAliasestoComman_F64B/image_2.png">
            <img title="image" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="418" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/PSParserTricks1ResolveallAliasestoComman_F64B/image_thumb.png" width="640" border="0" />
          </a>
        </p>
        <p>
As you can see, it spits out the expanded script to the output stream. The informational
messages are written to the host, so they won't interfere if you redirect the output
to a file like: .\resolve-aliases.ps1 in.ps1 &gt; out.ps1
</p>
        <p>
          <strong>Here's the Resolve-Aliases.ps1 script itself:</strong>
        </p>
        <!-- Stylesheet link -->
        <link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet" />
        <!-- Code -->
        <div class="dp-highlighter" id="hlDiv">
          <div class="bar">
          </div>
          <ol class="dp-rb">
            <li class="alt">
              <span>
                <span class="comment">#requires -version 2 </span>
                <span>  </span>
              </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="keyword">param</span>
              <span>(</span>
              <span class="variable">$filename</span>
              <span> =
$(throw </span>
              <span class="string">"need filename!"</span>
              <span>))   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$lines</span>
              <span> = </span>
              <span class="variable">$null</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$path</span>
              <span> = </span>
              <span class="builtin">Resolve-Path</span>
              <span> </span>
              <span class="variable">$filename</span>
              <span> -ErrorAction
0   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="keyword">if</span>
              <span> (</span>
              <span class="variable">$path</span>
              <span>)
{   </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="variable">$lines</span>
              <span> = </span>
              <span class="builtin">Get-Content</span>
              <span> </span>
              <span class="variable">$path</span>
              <span>.path   </span>
            </li>
            <li class="alt">
              <span>} </span>
              <span class="keyword">else</span>
              <span> {   </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="builtin">Write-Warning</span>
              <span> </span>
              <span class="string">"Could
not find $filename"</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    exit   </span>
            </li>
            <li class="">
              <span>}   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="comment"># Initialize </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="variable">$parser</span>
              <span> = [system.management.automation.psparser]   </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$errors</span>
              <span> = new-object system.management.automation.psparseerror[]
0   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>do {   </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$tokens</span>
              <span> = </span>
              <span class="variable">$parser</span>
              <span>:</span>
              <span class="symbol">:tokenize</span>
              <span>(</span>
              <span class="variable">$lines</span>
              <span>,
[ref]</span>
              <span class="variable">$errors</span>
              <span>)      </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="variable">$retokenize</span>
              <span> = </span>
              <span class="variable">$false</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>       </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="keyword">if</span>
              <span> (</span>
              <span class="variable">$errors</span>
              <span>.count
-gt 0) {   </span>
            </li>
            <li class="alt">
              <span>        </span>
              <span class="builtin">Write-Warning</span>
              <span> </span>
              <span class="string">"$($errors.count)
error(s) found in script."</span>
              <span>  </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="variable">$errors</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>        exit   </span>
            </li>
            <li class="">
              <span>    }   </span>
            </li>
            <li class="alt">
              <span>  </span>
            </li>
            <li class="">
              <span>    </span>
              <span class="comment"># look through tokens for commands </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>    </span>
              <span class="variable">$tokens</span>
              <span> | % {   </span>
            </li>
            <li class="">
              <span>        </span>
              <span class="keyword">if</span>
              <span> (</span>
              <span class="variable">$_</span>
              <span>.Type
-eq </span>
              <span class="string">"Command"</span>
              <span>) {   </span>
            </li>
            <li class="alt">
              <span>            </span>
              <span class="variable">$name</span>
              <span> = </span>
              <span class="variable">$_</span>
              <span>.Content   </span>
            </li>
            <li class="">
              <span>               </span>
            </li>
            <li class="alt">
              <span>            </span>
              <span class="comment">#
is it an alias? </span>
              <span>  </span>
            </li>
            <li class="">
              <span>            </span>
              <span class="comment">#
we use -literal here so '?' isn't treated as wildcard </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>            </span>
              <span class="keyword">if</span>
              <span> ((!(</span>
              <span class="variable">$name</span>
              <span> -eq </span>
              <span class="string">"."</span>
              <span>))
-and (</span>
              <span class="builtin">Test-Path</span>
              <span> -LiteralPath alias:</span>
              <span class="variable">$name</span>
              <span>))
{   </span>
            </li>
            <li class="">
              <span>                   </span>
            </li>
            <li class="alt">
              <span>                </span>
              <span class="comment">#
gcm may return more than one match, so specify "alias" </span>
              <span>  </span>
            </li>
            <li class="">
              <span>                </span>
              <span class="comment">#
filtering against name kludges the '?' alias/wildcard  </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>                </span>
              <span class="variable">$command</span>
              <span> =
gcm -CommandType alias </span>
              <span class="variable">$name</span>
              <span> | ? { </span>
              <span class="variable">$_</span>
              <span>.name
-eq </span>
              <span class="variable">$name</span>
              <span> }   </span>
            </li>
            <li class="">
              <span>                               </span>
            </li>
            <li class="alt">
              <span>                </span>
              <span class="comment">#
resolve alias which may lead to another alias </span>
              <span>  </span>
            </li>
            <li class="">
              <span>                </span>
              <span class="comment">#
so loop until we reach a non-alias </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>               
do {   </span>
            </li>
            <li class="">
              <span>                    </span>
              <span class="variable">$command</span>
              <span> = </span>
              <span class="builtin">Get-Command</span>
              <span> </span>
              <span class="variable">$command</span>
              <span>.definition   </span>
            </li>
            <li class="alt">
              <span>               
} </span>
              <span class="keyword">while</span>
              <span> (</span>
              <span class="variable">$command</span>
              <span>.CommandType
-eq </span>
              <span class="string">"Alias"</span>
              <span>)   </span>
            </li>
            <li class="">
              <span>                   </span>
            </li>
            <li class="alt">
              <span>                </span>
              <span class="builtin">Write-Host</span>
              <span> -NoNewline </span>
              <span class="string">"Resolved
"</span>
              <span>  </span>
            </li>
            <li class="">
              <span>                </span>
              <span class="builtin">Write-Host</span>
              <span> -NoNewline
-ForegroundColor yellow </span>
              <span class="variable">$name</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>               
write-host -nonewline </span>
              <span class="string">" to "</span>
              <span>    </span>
            </li>
            <li class="">
              <span>               
write-host -ForegroundColor green </span>
              <span class="variable">$command</span>
              <span>.name            </span>
            </li>
            <li class="alt">
              <span>                   </span>
            </li>
            <li class="">
              <span>                </span>
              <span class="comment">#
Use a stringbuilder to replace the alias in the line </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>                </span>
              <span class="comment">#
pointed to in the Token object. StringBuilder has a much </span>
              <span>  </span>
            </li>
            <li class="">
              <span>                </span>
              <span class="comment">#
more precise Replace method than String. This allows us to </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>                </span>
              <span class="comment">#
replace the token with 100% confidence. </span>
              <span>  </span>
            </li>
            <li class="">
              <span>                </span>
              <span class="variable">$sb</span>
              <span> = </span>
              <span class="builtin">New-Object</span>
              <span> text.stringbuilder </span>
              <span class="variable">$lines</span>
              <span>[</span>
              <span class="variable">$_</span>
              <span>.startline
- 1]   </span>
            </li>
            <li class="alt">
              <span>                </span>
              <span class="variable">$sb</span>
              <span> = </span>
              <span class="variable">$sb</span>
              <span>.replace(</span>
              <span class="variable">$name</span>
              <span>, </span>
              <span class="variable">$command</span>
              <span>.Name, </span>
              <span class="variable">$_</span>
              <span>.startcolumn
- 1, </span>
              <span class="variable">$_</span>
              <span>.length)   </span>
            </li>
            <li class="">
              <span>                </span>
              <span class="variable">$lines</span>
              <span>[</span>
              <span class="variable">$_</span>
              <span>.startline
- 1] = </span>
              <span class="variable">$sb</span>
              <span>.tostring()   </span>
            </li>
            <li class="alt">
              <span>                   </span>
            </li>
            <li class="">
              <span>                </span>
              <span class="comment">#
now that we've replaced a token, the script needs to be reparsed </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>                </span>
              <span class="comment">#
as offsets have changed on this line.  </span>
              <span>  </span>
            </li>
            <li class="">
              <span>                </span>
              <span class="variable">$retokenize</span>
              <span> = </span>
              <span class="variable">$true</span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>                   </span>
            </li>
            <li class="">
              <span>                </span>
              <span class="comment">#
break out of pipeline, (not 'do' loop) </span>
              <span>  </span>
            </li>
            <li class="alt">
              <span>               
continue;   </span>
            </li>
            <li class="">
              <span>            }   </span>
            </li>
            <li class="alt">
              <span>        }   </span>
            </li>
            <li class="">
              <span>    }   </span>
            </li>
            <li class="alt">
              <span>} </span>
              <span class="keyword">while</span>
              <span> (</span>
              <span class="variable">$retokenize</span>
              <span>)   </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="builtin">Write-Host</span>
              <span> </span>
              <span class="string">""</span>
              <span> </span>
              <span class="comment">#
blank line </span>
              <span>  </span>
            </li>
            <li class="">
              <span>  </span>
            </li>
            <li class="alt">
              <span>
              </span>
              <span class="comment"># output our modified script </span>
              <span>  </span>
            </li>
            <li class="">
              <span>
              </span>
              <span class="variable">$lines</span>
              <span>  </span>
            </li>
          </ol>
        </div>
        <p>
        </p>
        <p>
        </p>
        <p>
Of course, this requires PowerShell v2.0 CTP2. Next in the series, I'll give you a
script to check your ps1 scripts for backwards compatibility against PowerShell 1.0.
That should be handy for those naughty admins out there who despite all the warnings
have installed v2 in production. ;-)
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=cb3d0ce6-5acb-4257-9939-121ced333507" />
      </body>
      <title>PSParser Tricks #1 &amp;ndash; Resolve all Aliases to definitions in a script</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,cb3d0ce6-5acb-4257-9939-121ced333507.aspx</guid>
      <link>http://www.nivot.org/2008/07/01/PSParserTricks1NdashResolveAllAliasesToDefinitionsInAScript.aspx</link>
      <pubDate>Tue, 01 Jul 2008 22:43:07 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Why do such a thing? Well, if you’ve created your own aliases for commands and you
try to give someone your ps1 script file, it will not run because they have not got
the same aliases defined as you. Also, scripts that use fully-resolved names like
“Get-ChildItem” are more readable for a newcomer to PowerShell than one that is using
the unix-like “ls" alias for example. "Get-ChildItem" leads quite directly to the
MSDN documentation, but "ls" might lead you anywhere. Before you publish a script
online somewhere for the world to use, it’s important that you try to remove any aliases
and replace them with the native command names.
&lt;/p&gt;
&lt;p&gt;
Doing this kind of thing has been talked about before but it was always a very difficult
thing to do with PowerShell v1.0, what with the lack of &lt;a href="http://en.wikipedia.org/wiki/Backus-Naur_form" target="_blank"&gt;BNF&lt;/a&gt; documentation
describing the grammar etc. Thankfully, it's a lot easier to do with PowerShell v2.0
(currently at release CTP2) because the team has exposed the &lt;a href="http://en.wikipedia.org/wiki/Lexical_analysis" target="_blank"&gt;Tokenizer&lt;/a&gt; for
use in scripts. There's been suprisingly little use of it so far, so I figured I'd
start the ball rolling with a series of articles based around it. So, let's look at
an example script that uses aliases and put it through the meat grinder:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/PSParserTricks1ResolveallAliasestoComman_F64B/image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="418" alt="image" src="http://www.nivot.org/content/binary/WindowsLiveWriter/PSParserTricks1ResolveallAliasestoComman_F64B/image_thumb.png" width="640" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
As you can see, it spits out the expanded script to the output stream. The informational
messages are written to the host, so they won't interfere if you redirect the output
to a file like: .\resolve-aliases.ps1 in.ps1 &amp;gt; out.ps1
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Here's the Resolve-Aliases.ps1 script itself:&lt;/strong&gt;
&lt;/p&gt;
&lt;!-- Stylesheet link --&gt;
&lt;link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet"&gt;
&lt;!-- Code --&gt;
&lt;div class="dp-highlighter" id="hlDiv"&gt;
&lt;div class="bar"&gt;
&lt;/div&gt;
&lt;ol class="dp-rb"&gt;
&lt;li class="alt"&gt;
&lt;span&gt;&lt;span class="comment"&gt;#requires -version 2 &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;param&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="variable"&gt;$filename&lt;/span&gt;&lt;span&gt; =
$(throw &lt;/span&gt;&lt;span class="string"&gt;"need filename!"&lt;/span&gt;&lt;span&gt;))&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$lines&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$null&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$path&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="builtin"&gt;Resolve-Path&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="variable"&gt;$filename&lt;/span&gt;&lt;span&gt; -ErrorAction
0&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$path&lt;/span&gt;&lt;span&gt;)
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$lines&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="builtin"&gt;Get-Content&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="variable"&gt;$path&lt;/span&gt;&lt;span&gt;.path&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;} &lt;/span&gt;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt; {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="builtin"&gt;Write-Warning&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"Could
not find $filename"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;}&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# Initialize &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$parser&lt;/span&gt;&lt;span&gt; = [system.management.automation.psparser]&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$errors&lt;/span&gt;&lt;span&gt; = new-object system.management.automation.psparseerror[]
0&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;do {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$tokens&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$parser&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class="symbol"&gt;:tokenize&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="variable"&gt;$lines&lt;/span&gt;&lt;span&gt;,
[ref]&lt;/span&gt;&lt;span class="variable"&gt;$errors&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$retokenize&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$false&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$errors&lt;/span&gt;&lt;span&gt;.count
-gt 0) {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="builtin"&gt;Write-Warning&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"$($errors.count)
error(s) found in script."&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$errors&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;# look through tokens for commands &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$tokens&lt;/span&gt;&lt;span&gt; | % {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Type
-eq &lt;/span&gt;&lt;span class="string"&gt;"Command"&lt;/span&gt;&lt;span&gt;) {&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$name&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Content&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
is it an alias? &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
we use -literal here so '?' isn't treated as wildcard &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; ((!(&lt;/span&gt;&lt;span class="variable"&gt;$name&lt;/span&gt;&lt;span&gt; -eq &lt;/span&gt;&lt;span class="string"&gt;"."&lt;/span&gt;&lt;span&gt;))
-and (&lt;/span&gt;&lt;span class="builtin"&gt;Test-Path&lt;/span&gt;&lt;span&gt; -LiteralPath alias:&lt;/span&gt;&lt;span class="variable"&gt;$name&lt;/span&gt;&lt;span&gt;))
{&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
gcm may return more than one match, so specify "alias" &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
filtering against name kludges the '?' alias/wildcard&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$command&lt;/span&gt;&lt;span&gt; =
gcm -CommandType alias &lt;/span&gt;&lt;span class="variable"&gt;$name&lt;/span&gt;&lt;span&gt; | ? { &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.name
-eq &lt;/span&gt;&lt;span class="variable"&gt;$name&lt;/span&gt;&lt;span&gt; }&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
resolve alias which may lead to another alias &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
so loop until we reach a non-alias &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
do {&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$command&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="builtin"&gt;Get-Command&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="variable"&gt;$command&lt;/span&gt;&lt;span&gt;.definition&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
} &lt;/span&gt;&lt;span class="keyword"&gt;while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$command&lt;/span&gt;&lt;span&gt;.CommandType
-eq &lt;/span&gt;&lt;span class="string"&gt;"Alias"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="builtin"&gt;Write-Host&lt;/span&gt;&lt;span&gt; -NoNewline &lt;/span&gt;&lt;span class="string"&gt;"Resolved
"&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="builtin"&gt;Write-Host&lt;/span&gt;&lt;span&gt; -NoNewline
-ForegroundColor yellow &lt;/span&gt;&lt;span class="variable"&gt;$name&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
write-host -nonewline &lt;/span&gt;&lt;span class="string"&gt;" to "&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
write-host -ForegroundColor green &lt;/span&gt;&lt;span class="variable"&gt;$command&lt;/span&gt;&lt;span&gt;.name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
Use a stringbuilder to replace the alias in the line &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
pointed to in the Token object. StringBuilder has a much &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
more precise Replace method than String. This allows us to &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
replace the token with 100% confidence. &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$sb&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="builtin"&gt;New-Object&lt;/span&gt;&lt;span&gt; text.stringbuilder &lt;/span&gt;&lt;span class="variable"&gt;$lines&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.startline
- 1]&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$sb&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$sb&lt;/span&gt;&lt;span&gt;.replace(&lt;/span&gt;&lt;span class="variable"&gt;$name&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span class="variable"&gt;$command&lt;/span&gt;&lt;span&gt;.Name, &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.startcolumn
- 1, &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.length)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$lines&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.startline
- 1] = &lt;/span&gt;&lt;span class="variable"&gt;$sb&lt;/span&gt;&lt;span&gt;.tostring()&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
now that we've replaced a token, the script needs to be reparsed &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
as offsets have changed on this line.&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="variable"&gt;$retokenize&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span class="variable"&gt;$true&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span class="comment"&gt;#
break out of pipeline, (not 'do' loop) &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
continue;&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;} &lt;/span&gt;&lt;span class="keyword"&gt;while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$retokenize&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="builtin"&gt;Write-Host&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;""&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="comment"&gt;#
blank line &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt; 
&lt;li class="alt"&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="comment"&gt;# output our modified script &lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt; 
&lt;li class=""&gt;
&lt;span&gt;&lt;/span&gt;&lt;span class="variable"&gt;$lines&lt;/span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Of course, this requires PowerShell v2.0 CTP2. Next in the series, I'll give you a
script to check your ps1 scripts for backwards compatibility against PowerShell 1.0.
That should be handy for those naughty admins out there who despite all the warnings
have installed v2 in production. ;-)
&lt;/p&gt;
&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=cb3d0ce6-5acb-4257-9939-121ced333507" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,cb3d0ce6-5acb-4257-9939-121ced333507.aspx</comments>
      <category>.NET</category>
      <category>Monad</category>
      <category>PowerShell</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=59d45a0b-5cd5-4996-8015-ed24918608c4</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,59d45a0b-5cd5-4996-8015-ed24918608c4.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,59d45a0b-5cd5-4996-8015-ed24918608c4.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=59d45a0b-5cd5-4996-8015-ed24918608c4</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Someone on a private mailing list I'm on lamented the problem with powershell's '&gt;'
redirection operator defaulting inflexibly to use unicode for encoding the output
file. This is not very compatible for NT's ancient console subsystem which works best
with ASCII data. Fortunately, there's an easy workaround to fix this:
</p>
        <p>
Due to the magic of command discovery and the fact that &gt; really does use out-file,
you can "fix" this by placing the following in your $profile:<br /><br /><font face="courier ">function out-file($FilePath, $Encoding, [switch]$Append) {<br />
$input | microsoft.powershell.utility\out-file $filepath -encoding ascii `<br />
     -append:$append<br />
} </font></p>
        <p>
          <br />
From now on, &gt; will be forced to use ASCII encoding. This works because functions
have higher precedence than built-in commands in powershell's command discovery search. 
</p>
        <p>
          <strong>UPDATE: </strong>Rather annoyingly, I'm informed that this particular workaround
doesn't work on v1.0 of PowerShell. I tested the above on v2.0CTP2 only. Doh.
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=59d45a0b-5cd5-4996-8015-ed24918608c4" />
      </body>
      <title>Workaround to force PowerShell redirection operator to use ASCII encoding</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,59d45a0b-5cd5-4996-8015-ed24918608c4.aspx</guid>
      <link>http://www.nivot.org/2008/06/27/WorkaroundToForcePowerShellRedirectionOperatorToUseASCIIEncoding.aspx</link>
      <pubDate>Fri, 27 Jun 2008 16:03:07 GMT</pubDate>
      <description>&lt;p&gt;
Someone on a private mailing list I'm on lamented the problem with powershell's '&amp;gt;'
redirection operator defaulting inflexibly to use unicode for encoding the output
file. This is not very compatible for NT's ancient console subsystem which works best
with ASCII data. Fortunately, there's an easy workaround to fix this:
&lt;/p&gt;
&lt;p&gt;
Due to the magic of command discovery and the fact that &amp;gt; really does use out-file,
you can "fix" this by placing the following in your $profile:&lt;br&gt;
&lt;br&gt;
&lt;font face="courier "&gt;function out-file($FilePath, $Encoding, [switch]$Append) {&lt;br&gt;
$input | microsoft.powershell.utility\out-file $filepath -encoding ascii `&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -append:$append&lt;br&gt;
} &lt;/font&gt; 
&lt;p&gt;
&lt;br&gt;
From now on, &amp;gt; will be forced to use ASCII encoding. This works because functions
have higher precedence than built-in commands in powershell's command discovery search. 
&lt;p&gt;
&lt;strong&gt;UPDATE: &lt;/strong&gt;Rather annoyingly, I'm informed that this particular workaround
doesn't work on v1.0 of PowerShell. I tested the above on v2.0CTP2 only. Doh.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=59d45a0b-5cd5-4996-8015-ed24918608c4" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,59d45a0b-5cd5-4996-8015-ed24918608c4.aspx</comments>
      <category>.NET</category>
      <category>Monad</category>
      <category>PowerShell</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=0c6b37fa-8428-4360-be99-1fc5db89fb7e</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,0c6b37fa-8428-4360-be99-1fc5db89fb7e.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,0c6b37fa-8428-4360-be99-1fc5db89fb7e.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=0c6b37fa-8428-4360-be99-1fc5db89fb7e</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Just a quick one for the frustrated searchers out there. If you've recently installed
the SP1 beta for Visual Studio 2008 (or just the 3.5 sp1 beta alone), and you find
that you have serious difficulty using SharePoint Designer 2007 against a remote instance
of SharePoint running in a VM (or a physical machine) that <em>doesn't</em> have the
SP1 Beta bits, you know what to do. My SPD would refuse to load the master page from
my virtualized SharePoint instance until I had installed .NET 3.5 SP1 Beta onto the
virtual machine also. Just so you know!
</p>
        <img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=0c6b37fa-8428-4360-be99-1fc5db89fb7e" />
      </body>
      <title>Using SharePoint Designer with .NET 3.5 SP1 Beta</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,0c6b37fa-8428-4360-be99-1fc5db89fb7e.aspx</guid>
      <link>http://www.nivot.org/2008/06/12/UsingSharePointDesignerWithNET35SP1Beta.aspx</link>
      <pubDate>Thu, 12 Jun 2008 17:41:52 GMT</pubDate>
      <description>&lt;p&gt;
Just a quick one for the frustrated searchers out there. If you've recently installed
the SP1 beta for Visual Studio 2008 (or just the 3.5 sp1 beta alone), and you find
that you have serious difficulty using SharePoint Designer 2007 against a remote instance
of SharePoint running in a VM (or a physical machine) that &lt;em&gt;doesn't&lt;/em&gt; have the
SP1 Beta bits, you know what to do. My SPD would refuse to load the master page from
my virtualized SharePoint instance until I had installed .NET 3.5 SP1 Beta onto the
virtual machine also. Just so you know!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=0c6b37fa-8428-4360-be99-1fc5db89fb7e" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,0c6b37fa-8428-4360-be99-1fc5db89fb7e.aspx</comments>
      <category>.NET</category>
      <category>SharePoint</category>
      <category>SharePoint Designer</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://www.nivot.org/Trackback.aspx?guid=3c59a56a-8af3-4e47-ac11-b018a981662d</trackback:ping>
      <pingback:server>http://www.nivot.org/pingback.aspx</pingback:server>
      <pingback:target>http://www.nivot.org/PermaLink,guid,3c59a56a-8af3-4e47-ac11-b018a981662d.aspx</pingback:target>
      <dc:creator>Oisin Grehan</dc:creator>
      <wfw:comment>http://www.nivot.org/CommentView,guid,3c59a56a-8af3-4e47-ac11-b018a981662d.aspx</wfw:comment>
      <wfw:commentRss>http://www.nivot.org/SyndicationService.asmx/GetEntryCommentsRss?guid=3c59a56a-8af3-4e47-ac11-b018a981662d</wfw:commentRss>
      <slash:comments>5</slash:comments>
      <title>Windows Mobile PowerShell Provider</title>
      <guid isPermaLink="false">http://www.nivot.org/PermaLink,guid,3c59a56a-8af3-4e47-ac11-b018a981662d.aspx</guid>
      <link>http://www.nivot.org/2008/06/06/WindowsMobilePowerShellProvider.aspx</link>
      <pubDate>Fri, 06 Jun 2008 11:00:15 GMT</pubDate>
      <description>&lt;p align=left&gt;
In the spirit of "tidying things up," and pushing out nearly-there projects, I turned
my attention to &lt;a href="http://www.codeplex.com/PSMobile"&gt;http://www.codeplex.com/PSMobile&lt;/a&gt;.
I have&amp;nbsp;my fingers in way too many pies I think and I'm just not finding enough
time to get things finished off - but enough is enough. I am trying to&amp;nbsp;clear
my plate, and this is fruit number #2 of that attempt at self-correction. I have some
other important out of band work that I need to complete, but I find I cannot concentrate
on that until these personal projects that have been niggling me for ages are dealt
with. Anyway, lets dispel a couple of questions with a screenshot:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.nivot.org/content/binary/psmobile-screenshot.png"&gt; 
&lt;/p&gt;
&lt;h3&gt;Requirements 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
ActiveSync 4.2 or higher (or Windows Mobile Device Centre 6.0+ on Vista) &lt;a href="http://www.microsoft.com/downloads/results.aspx?pocId=&amp;amp;freetext=activesync&amp;amp;DisplayLang=en"&gt;Download&lt;/a&gt; 
&lt;li&gt;
A Windows Mobile device (PocketPC/SmartPhone 2002, 2003, 2003SE, Windows Mobile 5,
6 or 6.1) 
&lt;li&gt;
Windows PowerShell 1.0 or 2.0 (CTP) &lt;a href="http://www.microsoft.com/downloads/results.aspx?pocId=&amp;amp;freetext=powershell&amp;amp;DisplayLang=en"&gt;Download&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Features
&lt;/h3&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/WindowsMobilePowerShellProvider_C0D5/wm61-device_2.png"&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; MARGIN: 0px 0px 20px 20px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" border=0 alt=wm61-device align=right src="http://www.nivot.org/content/binary/WindowsLiveWriter/WindowsMobilePowerShellProvider_C0D5/wm61-device_thumb.png" width=184 height=244&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align=left&gt;Copy, Move, Delete items between folders on your device (including
Storage Card) with standard PowerShell Cmdlets
&lt;/div&gt;
&lt;li&gt;
&lt;div align=left&gt;Move/Copy files to/from your device and your desktop with &lt;font face="Courier New"&gt;ConvertTo-WMFile&lt;/font&gt; and &lt;font face="Courier New"&gt;ConvertFrom-WMFile&lt;/font&gt; 
&lt;/div&gt;
&lt;li&gt;
&lt;div align=left&gt;Get device information and manipulate and explore the registry with
a rich device object returned from &lt;font face="Courier New "&gt;Get-WMDevice &lt;/font&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align=left&gt;&lt;font face="Courier New"&gt;Invoke-Item&lt;/font&gt; against remote items to
or execute or trigger their associated applications 
&lt;/div&gt;
&lt;li&gt;
&lt;div align=left&gt;&lt;font face="Courier New"&gt;Invoke-Item&lt;/font&gt; with -Local switch to
attempt to execute a remote file in the context of your local desktop (e.g. office
docs or images/videos) 
&lt;/div&gt;
&lt;li&gt;
&lt;div align=left&gt;New "Mode" attributes specific to Windows Mobile file attributes: &lt;font face="courier new"&gt;(I)nRom,
Rom(M)odule&lt;/font&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align=left&gt;File/Folder objects' attributes can be modified with .Attributes properties
just like &lt;font face="Courier New"&gt;FileInfos&lt;/font&gt; etc.
&lt;/div&gt;
&lt;li&gt;
&lt;div align=left&gt;Tab completion with MoW's PowerTab &lt;a target=_blank href="http://thepowershellguy.com/blogs/posh/pages/powertab.aspx"&gt;Download&lt;/a&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;File Manipulation
&lt;/h3&gt;
&lt;p&gt;
A picture's worth a thousand words.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nivot.org/content/binary/WindowsLiveWriter/WindowsMobilePowerShellProvider_C0D5/images-screenshot_2.png"&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" border=0 alt=images-screenshot src="http://www.nivot.org/content/binary/WindowsLiveWriter/WindowsMobilePowerShellProvider_C0D5/images-screenshot_thumb.png" width=663 height=571&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;h3&gt;Cmdlets and Definitions
&lt;/h3&gt;
&lt;p&gt;
Here's a table of the syntax for the included Cmdlets.
&lt;/p&gt;
&lt;table border=1 cellspacing=0 cellpadding=2 width=600&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign=top width=140 align=middle&gt;
&lt;strong&gt;Cmdlet&lt;/strong&gt;&lt;/td&gt;
&lt;td valign=top width=285 align=middle&gt;
&lt;strong&gt;Definition&lt;/strong&gt;&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
&lt;strong&gt;WhatIf / Confirm&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
ConvertFrom-WMFile *&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-Path] 
&lt;STRING []&gt;
[-Destination] 
&lt;STRING&gt;
[-Force] [-Verbose]
&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-LiteralPath] 
&lt;STRING []&gt;
[-Destination] 
&lt;STRING&gt;
[-Force] [-Verbose]
&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
ConvertTo-WMFile *&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-Path] 
&lt;STRING []&gt;
[-Destination] 
&lt;STRING&gt;
[-Force] [-Verbose]
&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-LiteralPath] 
&lt;STRING []&gt;
[-Destination] 
&lt;STRING&gt;
[-Force] [-Verbose]
&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
Get-WMDeviceInfo&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-Verbose] 
&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
Get-WMMemoryInfo 
&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-Verbose] 
&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
Get-WMStoreInfo 
&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-Verbose] 
&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
Start-WMActiveSync 
&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-Verbose] 
&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
Stop-WMActiveSync&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-Verbose] 
&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
Start-WMProcess 
&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-LiteralPath] 
&lt;STRING&gt;
[[-Arguments] 
&lt;STRING []&gt;
] [-Verbose]
&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign=top width=140&gt;
Get-WMDevice&lt;/td&gt;
&lt;td valign=top width=285&gt;
[-Verbose]&lt;/td&gt;
&lt;td valign=top width=173 align=middle&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
&lt;em&gt;* These Cmdlets that accept a path will bind to pipeline input via PSPath property
name.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
If you've got any problems, suggestions or ideas, please post into the discussions
board on the web site. Have fun!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nivot.org/aggbug.ashx?id=3c59a56a-8af3-4e47-ac11-b018a981662d" /&gt;</description>
      <comments>http://www.nivot.org/CommentView,guid,3c59a56a-8af3-4e47-ac11-b018a981662d.aspx</comments>
      <category>.NET</category>
      <category>Compact Framework</category>
      <category>Monad</category>
      <category>Pocket PC</category>
      <category>PowerShell</category>
      <category>SmartPhone</category>
      <category>WinCE</category>
      <category>Windows Mobile</category>
    </item>
  </channel>
</rss>