<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BUGBUG: poor title</title>
	<atom:link href="http://richardberg.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://richardberg.net/blog</link>
	<description>...the same thing we do every night, Pinky...</description>
	<lastBuildDate>Mon, 27 Apr 2009 15:54:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>How to uninstall Powershell v1.0 from Windows Server 2003 R2</title>
		<link>http://richardberg.net/blog/2009/04/27/how-to-uninstall-powershell-v10-from-windows-server-2003-r2/</link>
		<comments>http://richardberg.net/blog/2009/04/27/how-to-uninstall-powershell-v10-from-windows-server-2003-r2/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 15:54:31 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=71</guid>
		<description><![CDATA[If you’re lucky, you can uninstall Powershell simply by finding the Windows update in ARP that has the signature blue icon.&#160; When I was rolling out Powershell CTP3 (now deeply integrated into our build &#38; deploy scripts), this worked on the majority of our machines.&#160; All except the TFS server, as luck would have it.&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>If you’re lucky, you can uninstall Powershell simply by finding the Windows update in <a href="http://blogs.msdn.com/oldnewthing/archive/2004/07/09/178342.aspx">ARP</a> that has the signature blue icon.&#160; When I was rolling out Powershell CTP3 (now deeply integrated into our build &amp; deploy scripts), this worked on the majority of our machines.&#160; All except the TFS server, as luck would have it.&#160; Figures!</p>
<p>According to <a href="http://support.microsoft.com/kb/926140">KB926140</a>, this will fail if you installed Powershell before you installed SP2 (or upgraded to R2) because the latter update includes the former.&#160; MSI patching is fun like that.&#160; So if you want v2.0 goodness, it’s time to do some surgery.</p>
<p><strong>WARNING: this is completely unsupported by Microsoft.&#160; It happened to work for me.&#160; YMMV.</strong></p>
<p>First you need to dig up a copy of PSCustomSetup.exe.&#160; If you have a machine that already has PS v1.0 on it, you’ll find this tool in %windir%\$NtUninstallKB926139$.&#160; (Note: the KB number may be 928439 on Vista, but I don’t have a Vista machine to say for sure.&#160; Use your “gci -filter” skillz.)&#160; Or you can dig it out of the v1.0 install package.&#160; You might also try to grab a copy of spuninst.inf that’s appropriate for your OS, just to sanity check you aren’t missing anything, though we will be hacking our own…</p>
<p>Basically, we need to manually replay the steps that the uninstaller would have taken.&#160; Ordinarily, the .inf file spells this out in a vaguely human-readable format.&#160; Thanks to the efforts of some folks around the net[1][2][3], I was able to come up with a comprehensive list.&#160; Technically it can vary from OS to OS, or even machine to machine, but you wouldn’t be here unless you had the 2003 R2 issue in particular – XP and Vista aren’t affected since PS is not part of their service packs.&#160; Plus, it’s fairly easy to abstract out the machine-specific paths with an environment variable here &amp; there.&#160; Thus, my instructions:</p>
<p>1) Copy the PSCustomSetup.exe you found to a temporary directory on the affected machine.</p>
<p>2) Copy/paste this first script block into a file named <em>uninstall.cmd</em> and save it into the temporary directory.</p>
</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:ee69b636-ec35-4f6b-a695-565a6e11433b" class="wlWriterEditableSmartContent">
<pre style="background-color:White;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">pushd </span><span style="color: #000000;">%</span><span style="color: #000000;">windir</span><span style="color: #000000;">%</span><span style="color: #000000;">\Microsoft.NET\Framework\v2.</span><span style="color: #800080;">0.50727</span><span style="color: #000000;">
ngen.exe uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">System.Management.Automation,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/</span><span style="color: #000000;">silent </span><span style="color: #000000;">/</span><span style="color: #000000;">nologo </span><span style="color: #000000;">/</span><span style="color: #000000;">NoDependencies
ngen.exe uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.ConsoleHost,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/</span><span style="color: #000000;">silent </span><span style="color: #000000;">/</span><span style="color: #000000;">nologo </span><span style="color: #000000;">/</span><span style="color: #000000;">NoDependencies
ngen.exe uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Commands.Management,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/</span><span style="color: #000000;">silent </span><span style="color: #000000;">/</span><span style="color: #000000;">nologo </span><span style="color: #000000;">/</span><span style="color: #000000;">NoDependencies
ngen.exe uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Commands.Utility,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/</span><span style="color: #000000;">silent </span><span style="color: #000000;">/</span><span style="color: #000000;">nologo </span><span style="color: #000000;">/</span><span style="color: #000000;">NoDependencies
ngen.exe uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Security,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/</span><span style="color: #000000;">silent </span><span style="color: #000000;">/</span><span style="color: #000000;">nologo </span><span style="color: #000000;">/</span><span style="color: #000000;">NoDependencies
ngen.exe uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">System.Management.Automation.resources,Version=1.0.0.0,Culture=en,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/</span><span style="color: #000000;">silent </span><span style="color: #000000;">/</span><span style="color: #000000;">nologo </span><span style="color: #000000;">/</span><span style="color: #000000;">NoDependencies
ngen.exe uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.ConsoleHost.resources,Version=1.0.0.0,Culture=en,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/</span><span style="color: #000000;">silent </span><span style="color: #000000;">/</span><span style="color: #000000;">nologo </span><span style="color: #000000;">/</span><span style="color: #000000;">NoDependencies
ngen.exe uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Commands.Management.resources,Version=1.0.0.0,Culture=en,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/</span><span style="color: #000000;">silent </span><span style="color: #000000;">/</span><span style="color: #000000;">nologo </span><span style="color: #000000;">/</span><span style="color: #000000;">NoDependencies
ngen.exe uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Commands.Utility.resources,Version=1.0.0.0,Culture=en,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/</span><span style="color: #000000;">silent </span><span style="color: #000000;">/</span><span style="color: #000000;">nologo </span><span style="color: #000000;">/</span><span style="color: #000000;">NoDependencies
ngen.exe uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Security.resources,Version=1.0.0.0,Culture=en,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/</span><span style="color: #000000;">silent </span><span style="color: #000000;">/</span><span style="color: #000000;">nologo </span><span style="color: #000000;">/</span><span style="color: #000000;">NoDependencies
popd

PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">System.Management.Automation,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;&quot;
</span><span style="color: #000000;">PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.ConsoleHost,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;&quot;
</span><span style="color: #000000;">PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Commands.Management,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;&quot;
</span><span style="color: #000000;">PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Commands.Utility,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;&quot;
</span><span style="color: #000000;">PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Security,Version=1.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;&quot;
</span><span style="color: #000000;">PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">System.Management.Automation.resources,Version=1.0.0.0,Culture=en,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;&quot;
</span><span style="color: #000000;">PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.ConsoleHost.resources,Version=1.0.0.0,Culture=en,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;&quot;
</span><span style="color: #000000;">PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Commands.Management.resources,Version=1.0.0.0,Culture=en,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;&quot;
</span><span style="color: #000000;">PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Commands.Utility.resources,Version=1.0.0.0,Culture=en,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;&quot;
</span><span style="color: #000000;">PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">uninstall </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.PowerShell.Security.resources,Version=1.0.0.0,Culture=en,PublicKeyToken=31bf3856ad364e35,ProcessorArchitecture=msil</span><span style="color: #800000;">&quot;&quot;
</span><span style="color: #000000;">PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">removeenvvariable PATH </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">C:\WINDOWS\system32\WindowsPowerShell\v1.0</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">
PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">removeenvvariable PATHEXT </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">.PSC1</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">
PSCustomSetupUtil.exe </span><span style="color: #000000;">/</span><span style="color: #000000;">wmsettingchange

rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q </span><span style="color: #000000;">%</span><span style="color: #000000;">windir</span><span style="color: #000000;">%</span><span style="color: #000000;">\$NtUninstallKB926139$
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q </span><span style="color: #000000;">%</span><span style="color: #000000;">windir</span><span style="color: #000000;">%</span><span style="color: #000000;">\system32\windowspowershell

pushd </span><span style="color: #000000;">%</span><span style="color: #000000;">windir</span><span style="color: #000000;">%</span><span style="color: #000000;">\assembly\gac_msil
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q System.Management.Automation
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q Microsoft.PowerShell.ConsoleHost
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q Microsoft.PowerShell.Commands.Management
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q Microsoft.PowerShell.Commands.Utility
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q Microsoft.PowerShell.Security
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q System.Management.Automation.resources
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q Microsoft.PowerShell.ConsoleHost.resources
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q Microsoft.PowerShell.Commands.Management.resources
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q Microsoft.PowerShell.Commands.Utility.resources
rd </span><span style="color: #000000;">/</span><span style="color: #000000;">s </span><span style="color: #000000;">/</span><span style="color: #000000;">q Microsoft.PowerShell.Security.resources
popd</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
</p>
<p>3) Open a CMD window, navigate to the temporary directory, and run the script.&#160; Watch for errors.&#160; (Post to the comments…)&#160; Make sure it’s a 64-bit CMD window if you’re on x64 Windows.</p>
<p>4) Copy this block of text to a file named <em>uninstall.reg</em> and save it to the temporary directory.&#160; Run it and accept the “yes, I really want to do this” prompt.</p>
</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:aa084303-d0b8-4fcf-ac85-e870b18f5859" class="wlWriterEditableSmartContent">
<pre style="background-color:White;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">Windows Registry Editor Version </span><span style="color: #800080;">5.00</span><span style="color: #000000;">

[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType </span><span style="color: #800080;">0</span><span style="color: #000000;">\CryptSIPDllCreateIndirectData\{603BCC1F</span><span style="color: #000000;">-</span><span style="color: #000000;">4B59</span><span style="color: #000000;">-</span><span style="color: #000000;">4E08</span><span style="color: #000000;">-</span><span style="color: #000000;">B724</span><span style="color: #000000;">-</span><span style="color: #000000;">D2C6297EF351}]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType </span><span style="color: #800080;">0</span><span style="color: #000000;">\CryptSIPDllGetSignedDataMsg\{603BCC1F</span><span style="color: #000000;">-</span><span style="color: #000000;">4B59</span><span style="color: #000000;">-</span><span style="color: #000000;">4E08</span><span style="color: #000000;">-</span><span style="color: #000000;">B724</span><span style="color: #000000;">-</span><span style="color: #000000;">D2C6297EF351}]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType </span><span style="color: #800080;">0</span><span style="color: #000000;">\CryptSIPDllIsMyFileType2\{603BCC1F</span><span style="color: #000000;">-</span><span style="color: #000000;">4B59</span><span style="color: #000000;">-</span><span style="color: #000000;">4E08</span><span style="color: #000000;">-</span><span style="color: #000000;">B724</span><span style="color: #000000;">-</span><span style="color: #000000;">D2C6297EF351}]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType </span><span style="color: #800080;">0</span><span style="color: #000000;">\CryptSIPDllPutSignedDataMsg\{603BCC1F</span><span style="color: #000000;">-</span><span style="color: #000000;">4B59</span><span style="color: #000000;">-</span><span style="color: #000000;">4E08</span><span style="color: #000000;">-</span><span style="color: #000000;">B724</span><span style="color: #000000;">-</span><span style="color: #000000;">D2C6297EF351}]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType </span><span style="color: #800080;">0</span><span style="color: #000000;">\CryptSIPDllRemoveSignedDataMsg\{603BCC1F</span><span style="color: #000000;">-</span><span style="color: #000000;">4B59</span><span style="color: #000000;">-</span><span style="color: #000000;">4E08</span><span style="color: #000000;">-</span><span style="color: #000000;">B724</span><span style="color: #000000;">-</span><span style="color: #000000;">D2C6297EF351}]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType </span><span style="color: #800080;">0</span><span style="color: #000000;">\CryptSIPDllVerifyIndirectData\{603BCC1F</span><span style="color: #000000;">-</span><span style="color: #000000;">4B59</span><span style="color: #000000;">-</span><span style="color: #000000;">4E08</span><span style="color: #000000;">-</span><span style="color: #000000;">B724</span><span style="color: #000000;">-</span><span style="color: #000000;">D2C6297EF351}]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\HotFix\KB926139]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates\Windows Server </span><span style="color: #800080;">2003</span><span style="color: #000000;">\SP2\KB926139]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates\Windows PowerShell </span><span style="color: #800080;">1.0</span><span style="color: #000000;">]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_CLASSES_ROOT\.ps1]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_CLASSES_ROOT\.ps1xml]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_CLASSES_ROOT\.psc1]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_CLASSES_ROOT\Microsoft.PowerShellConsole.</span><span style="color: #800080;">1</span><span style="color: #000000;">]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.</span><span style="color: #800080;">1</span><span style="color: #000000;">]
[</span><span style="color: #000000;">-</span><span style="color: #000000;">HKEY_CLASSES_ROOT\Microsoft.PowerShellXmlData.</span><span style="color: #800080;">1</span><span style="color: #000000;">] </span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
</p>
<p>5) Install Powershell v2.0</p>
<p>6) Clean up the temp dir.</p>
<p>Success?&#160; Hope so – if not, it’s probably time to nuke that install!&#160; (or at minimum, restore from backup)&#160; Good luck everyone.&#160; </p>
<p>Note: these instructions do not remove shortcuts from the Start Menu or anywhere else.&#160; You’ll need to do that yourself.</p>
<p>[1] <a title="http://groups.google.com/group/microsoft.public.windows.powershell/browse_thread/thread/51a54e7de0ed5d1f/eaba9eb2c0d772ec" href="http://groups.google.com/group/microsoft.public.windows.powershell/browse_thread/thread/51a54e7de0ed5d1f/eaba9eb2c0d772ec">http://groups.google.com/group/microsoft.public.windows.powershell/browse_thread/thread/51a54e7de0ed5d1f/eaba9eb2c0d772ec</a> </p>
<p>[2] <a title="http://blogs.msdn.com/powershell/archive/2007/01/09/behind-powershell-installer-for-windows-xp-windows-server-2003.aspx" href="http://blogs.msdn.com/powershell/archive/2007/01/09/behind-powershell-installer-for-windows-xp-windows-server-2003.aspx">http://blogs.msdn.com/powershell/archive/2007/01/09/behind-powershell-installer-for-windows-xp-windows-server-2003.aspx</a> </p>
<p>[3] <a title="http://marcoshaw.blogspot.com/2008/06/powershell-v2-ctpctp2-error-error.html" href="http://marcoshaw.blogspot.com/2008/06/powershell-v2-ctpctp2-error-error.html">http://marcoshaw.blogspot.com/2008/06/powershell-v2-ctpctp2-error-error.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/04/27/how-to-uninstall-powershell-v10-from-windows-server-2003-r2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The VS2008 remote debug transport (MSVSMON.EXE) does not support Silverlight?</title>
		<link>http://richardberg.net/blog/2009/04/20/the-vs2008-remote-debug-transport-msvsmonexe-does-not-support-silverlight/</link>
		<comments>http://richardberg.net/blog/2009/04/20/the-vs2008-remote-debug-transport-msvsmonexe-does-not-support-silverlight/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 23:49:29 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=70</guid>
		<description><![CDATA[So, a Silverlight app we recently deployed into production works great across a wide variety of machines, browsers, and even OS platforms…except for one poor customer.&#160; For him the app crashes soon after loading, with a strange exception deep in the SL runtime.&#160; Sounds like a job for the remote debugger, right? Bzzt.&#160; I think [...]]]></description>
			<content:encoded><![CDATA[<p>So, a Silverlight app we recently deployed into production works great across a wide variety of machines, browsers, and even OS platforms…except for one poor customer.&#160; For him the app crashes soon after loading, with a strange exception deep in the SL runtime.&#160; Sounds like a job for the remote debugger, right?</p>
<p><a href="http://silverlight.net/forums/p/16381/54429.aspx">Bzzt</a>.&#160; <em>I think we don't support remote Windows debugging for Silverlight.</em>&#160; Can anyone confirm or deny?</p>
<p>It sure doesn’t work for me.&#160; I can choose a browser from the list of processes and “Silverlight code” from the list of debuggers, but I always get “Unable to attach to the process.”</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/04/20/the-vs2008-remote-debug-transport-msvsmonexe-does-not-support-silverlight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get-TfsItemProperty is the bridge between server and local objects</title>
		<link>http://richardberg.net/blog/2009/03/27/get-tfsitemproperty-is-the-bridge-between-server-and-local-objects/</link>
		<comments>http://richardberg.net/blog/2009/03/27/get-tfsitemproperty-is-the-bridge-between-server-and-local-objects/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 02:59:34 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=67</guid>
		<description><![CDATA[Most of the real-world examples of the TFS powershell tool revolve around querying (and possibly updating) the state of the server.&#160; My first public demo, by way of Brian Harry’s blog Keith Hill’s early explorations And rightfully so: most of the operations you want to do locally are already possible without any special tools.&#160; The [...]]]></description>
			<content:encoded><![CDATA[<p>Most of the real-world examples of the TFS powershell tool revolve around querying (and possibly updating) the state of the server.&#160; </p>
<ul>
<li><a href="http://blogs.msdn.com/bharry/archive/2008/10/01/preview-of-the-next-tfs-power-tools-release.aspx">My first public demo</a>, by way of Brian Harry’s blog</li>
<li><a href="http://keithhill.spaces.live.com/blog/cns!5A8D2641E0963A97!6691.entry">Keith Hill’s early explorations</a></li>
</ul>
<p>And rightfully so: most of the operations you want to do locally are already possible without any special tools.&#160; The “Powershell snap-in system” we know and love today was created to help IT admins manage their servers – even today, only a brave few developers have completely replaced cmd.exe at their daily workstation.</p>
<p>Nevertheless, we shouldn’t be satisfied to have our TFS cmdlets live in their own little world.&#160; Luckily, all the info we could ever want about a TFS version controlled item – including its local state – comes packaged in the <a href="http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.extendeditem.aspx">ExtendedItem</a> object.&#160; Even more fortuitously, if you revisit the <a href="http://richardberg.net/blog/?p=30">exploration of QualifiedItemSpec</a> with an eye for detail, you’ll notice that one overload of ToQualifiedItem() is not like the others.*&#160; In the constructor where ExtendedItem decays into QualifiedItem, the properties saved into the resulting tuple include LocalItem and VersionLocal instead of more familiar ones like ServerItem.&#160; This is not a coincidence :)&#160; </p>
<p>Let’s sum up what we know so far.&#160; Native TFS objects are funneled down the pipeline by stripping them to bare essentials about the items they represent (QIs); these serve as a common interface between cmdlets.&#160; When an ExtendedItem is stripped down, the next cmdlet will use the <em>local</em> filename &amp; <em>local </em>version info as its parameters.&#160; Get-TfsItemProperty is the cmdlet that returns ExtendedItems.&#160; Capiche?</p>
<p>Time to put our newfound knowledge into action.&#160; If you’ve also been following the last several posts on file manipulation in powershell, these examples will hopefully inspire an “aha!” moment.</p>
<div style="border-bottom: black 1px solid; border-left: black 1px solid; padding-bottom: 5px; padding-left: 5px; width: 750px; padding-right: 5px; font-family: consolas,lucida console; font-size: 10pt; overflow: auto; border-top: black 1px solid; border-right: black 1px solid; padding-top: 5px">
<table border="0" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td valign="top">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #cecece; font-size: 10pt; padding-top: 5px">001             <br />002              <br />003              <br />004              <br />005              </div>
</td>
<td valign="top" nowrap="nowrap">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #fcfcfc; font-size: 10pt; padding-top: 5px"><span style="color: #006400"># find all C# makefiles with HintPath elements, check them out, and open them in my text editor</span>              <br /><span style="color: #0000ff">tfprop</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">$/project/*csproj</span><span style="color: #000000">&#160;</span><span style="color: #000080">-r</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">get-fullpath</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">ss</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">hintpath</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">tfedit</span><span style="color: #000000">&#160;</span><span style="color: #000080">-passthru</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">ue</span>              </p>
<p><span style="color: #006400"># find my shelvesets related to powershell, unshelve them, and open every file in the ISE</span>              <br /><span style="color: #0000ff">get-tfsshelveset</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">?</span><span style="color: #000000">&#160;</span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">name</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-like</span><span style="color: #000000">&#160;</span><span style="color: #8b0000">&quot;*powershell*&quot;</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">tfunshelve</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">tfprop</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">ise</span> </div>
</td>
</tr>
</tbody>
</table></div>
<p>[Note that I have get-tfsitemproperty aliased to ‘tfprop’ rather than ‘tfproperties’ as it appears in a default install of the Power Tools.]</p>
<p>Are we having fun yet?!</p>
<p>So far we’ve only really exercised the filename part of the QI.&#160; Equally interesting things happen when you take advantage of the special ability that Get-TfsItemProperty offers to manipulate the local version.</p>
<div style="border-bottom: black 1px solid; border-left: black 1px solid; padding-bottom: 5px; padding-left: 5px; width: 750px; padding-right: 5px; font-family: consolas,lucida console; font-size: 10pt; overflow: auto; border-top: black 1px solid; border-right: black 1px solid; padding-top: 5px">
<table border="0" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td valign="top">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #cecece; font-size: 10pt; padding-top: 5px">001             <br />002              <br />003              <br />004              <br />005              <br />006              <br />007              <br />008              <br />009              <br />010              <br />011              <br />012              <br />013              <br />014              <br />015              <br />016              <br />017              <br />018              <br />019              <br />020              <br />021              </div>
</td>
<td valign="top" nowrap="nowrap">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #fcfcfc; font-size: 10pt; padding-top: 5px"><span style="color: #006400"># Force unshelve to pend changes against your current workspace (&quot;have&quot;) version. Ordinarily,</span>              <br /><span style="color: #006400"># unshelve rolls the affected files back to the version you had at the time you shelved the </span>              <br /><span style="color: #006400"># changes.</span>              <br /><span style="color: #006400"># Pro: this ensures your workspace stays in a consistent, buildable state</span>              <br /><span style="color: #006400"># Con: you may need to resolve content and/or namespace conflicts</span>              <br /><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">unpack</span>              <br /><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">CmdletBinding</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">param</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">parameter</span><span style="color: #000000">(</span><span style="color: #000000">Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$True</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">0</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">ValueFromPipeline</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$True</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #008080">[Microsoft.TeamFoundation.PowerTools.Powershell.ShelvesetSpec]</span><span style="color: #ff4500">$ss</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">process</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$currentWorkspaceVersions</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">tfstatus</span><span style="color: #000000">&#160;</span><span style="color: #000080">-shelveset</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$ss</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">tfprop</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">restore-tfsshelveset</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$ss</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">out-null</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$currentWorkspaceVersions</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">tfget</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">tf</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">resolve</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">/prompt</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">}</span> </div>
</td>
</tr>
</tbody>
</table></div>
<p>[Microsofties: think bbpack / jjpack]</p>
<p>Opens up a whole new world of TFVC scripting mania, wouldn’t ya say?</p>
<p>*I’ll admit the one for GettingEventArgs is a little funky as well.&#160; Here, the choice of properties to expose came down to UX / gut feel.&#160; TargetLocalItem is usually what you want to see; it tends to be the “final result” of mainline operations, surviving things like Rename and Undo fairly well.&#160; But it’s not always the best choice.&#160; Obviously when it’s null we need a backup; good old ServerItem will do.&#160; It’s [almost always] guaranteed to be present, but it’s&#160; not always perfect either – now you have the occasional strange appearance of server paths in your list of local files being touched by the Update.&#160; Finding the right info gets really tricky really fast: was TargetLocalItem null because of a pending Delete, because it’s cloaked or otherwise excluded from our workspace, or because we’re undoing a pending Branch or Merge?&#160; That’s just one example.&#160; The logic behind which name tf.exe displays in which scenario is actually one of the more complex pieces of the app.&#160; With powershell we can accept “good enough” since the object model lets you manipulate things to your heart’s content.</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/27/get-tfsitemproperty-is-the-bridge-between-server-and-local-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powershell tidbit: hit F6 in the ISE to execute the current selection</title>
		<link>http://richardberg.net/blog/2009/03/27/powershell-tidbit-hit-f6-in-the-ise-to-execute-the-current-selection/</link>
		<comments>http://richardberg.net/blog/2009/03/27/powershell-tidbit-hit-f6-in-the-ise-to-execute-the-current-selection/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 00:33:06 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=63</guid>
		<description><![CDATA[For anyone who hasn’t discovered this feature yet, make sure to give it a whirl.&#160; It’s by far my favorite “little” thing about the new environment.&#160; /Berg tweet out]]></description>
			<content:encoded><![CDATA[<p>For anyone who hasn’t discovered this feature yet, make sure to give it a whirl.&#160; It’s by far my favorite “little” thing about the new environment.&#160; /Berg tweet out</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/27/powershell-tidbit-hit-f6-in-the-ise-to-execute-the-current-selection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powershell tidbit: hacky way to find the 32-bit Program Files directory</title>
		<link>http://richardberg.net/blog/2009/03/27/powershell-tidbit-hacky-way-to-find-the-32-bit-program-files-directory/</link>
		<comments>http://richardberg.net/blog/2009/03/27/powershell-tidbit-hacky-way-to-find-the-32-bit-program-files-directory/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 00:24:21 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=61</guid>
		<description><![CDATA[In the process of tidying up another function for posting, I found that there is no clean way to get a Powershell variable from the system that: Points to “C:\program files (x86)” regardless whether you’re in a 32-bit or 64-bit process. Exists on legacy 32-bit operating systems. Sounds like a common thing you’d need: to [...]]]></description>
			<content:encoded><![CDATA[<p>In the process of tidying up another function for posting, I found that there is no clean way to get a Powershell variable from the system that:</p>
<ol>
<li>Points to “C:\program files (x86)” regardless whether you’re in a 32-bit or 64-bit process. </li>
<li>Exists on legacy 32-bit operating systems. </li>
</ol>
<p>Sounds like a common thing you’d need: to find the location where 32-bit programs are installed regardless of any other factors.&#160; Powershell’s $env:ProgramFiles(x86) variable comes close, but even if it were present on 32-bit OSes -- honestly not sure about that -- the parentheses in the variable name present a nasty parse problem.&#160; No amount of quoting or backtick`ing or $()’ing got me the result I was looking for.&#160; If you have more patience than me, <a href="http://www.techotopia.com/index.php/Windows_PowerShell_1.0_String_Quoting_and_Escape_Sequences">have at it</a>.</p>
<p>And oh yeah, did I mention I was shopping for a better <a href="http://solutionizing.net/2008/12/20/powershell-coalesce-and-powershellasp-query-string-parameters/">null coalescing operator</a> than the one that comes with PSCX?&#160; <em>Note to PSCX folks: I hate wrapping stuff in scriptblocks when there’s no real need for them.&#160; Thanks, Richard’s pinky finger.</em></p>
<p>So anyway, I resorted to putting this abomination in my $profile:</p>
<div style="border-bottom: black 1px solid; border-left: black 1px solid; padding-bottom: 5px; padding-left: 5px; width: 887px; padding-right: 5px; font-family: consolas,lucida console; height: 118px; font-size: 10pt; overflow: auto; border-top: black 1px solid; border-right: black 1px solid; padding-top: 5px">
<table border="0" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td valign="top">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #cecece; font-size: 10pt; padding-top: 5px">001              <br />002               <br />003               <br />004               </div>
</td>
<td valign="top" nowrap="nowrap">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #fcfcfc; font-size: 10pt; padding-top: 5px"><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">??</span><span style="color: #000000">&#160;</span><span style="color: #000000">{</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">(</span><span style="color: #000000">@(</span><span style="color: #ff4500">$args</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">?</span><span style="color: #000000">{</span><span style="color: #ff4500">$_</span><span style="color: #000000">}</span><span style="color: #000000">)</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">+</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$null</span><span style="color: #000000">)</span><span style="color: #a9a9a9">[</span><span style="color: #800080">0</span><span style="color: #a9a9a9">]</span>               <br /><span style="color: #000000">}</span>               <br /><span style="color: #0000ff">set-variable</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">programFilesX86</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #0000ff">??</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #0000ff">cat</span><span style="color: #000000">&#160;</span><span style="color: #8b0000">'Env:\ProgramFiles(x86)'</span><span style="color: #000000">&#160;</span><span style="color: #000080">-ea</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">SilentlyContinue</span><span style="color: #000000">)</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$Env:ProgramFiles</span><span style="color: #000000">)</span><span style="color: #000000">&#160;</span><span style="color: #000080">-scope</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">global</span> </div>
</td>
</tr>
</tbody>
</table></div>
<p>Yes, it’s ugly and nonstandard (in the sense that I can’t rely on this being present in other people’s script environments)…suggestions welcome...</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/27/powershell-tidbit-hacky-way-to-find-the-32-bit-program-files-directory/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Invoke-UltraEdit.ps1: integrate your favorite text editor with the Powershell pipeline</title>
		<link>http://richardberg.net/blog/2009/03/27/invoke-ultraeditps1-integrate-your-favorite-text-editor-with-the-powershell-pipeline/</link>
		<comments>http://richardberg.net/blog/2009/03/27/invoke-ultraeditps1-integrate-your-favorite-text-editor-with-the-powershell-pipeline/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 00:19:18 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=60</guid>
		<description><![CDATA[Less talk, more code.&#160; As long as that code has ample inline comments, of course! 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 [...]]]></description>
			<content:encoded><![CDATA[<p>Less talk, more code.&#160; As long as that code has ample inline comments, of course!</p>
<div style="border-bottom: black 1px solid; border-left: black 1px solid; padding-bottom: 5px; padding-left: 5px; width: 852px; padding-right: 5px; font-family: consolas,lucida console; height: 1370px; font-size: 10pt; overflow: auto; border-top: black 1px solid; border-right: black 1px solid; padding-top: 5px">
<table border="0" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td valign="top">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #cecece; font-size: 10pt; padding-top: 5px">001              <br />002               <br />003               <br />004               <br />005               <br />006               <br />007               <br />008               <br />009               <br />010               <br />011               <br />012               <br />013               <br />014               <br />015               <br />016               <br />017               <br />018               <br />019               <br />020               <br />021               <br />022               <br />023               <br />024               <br />025               <br />026               <br />027               <br />028               <br />029               <br />030               <br />031               <br />032               <br />033               <br />034               <br />035               <br />036               <br />037               <br />038               <br />039               <br />040               <br />041               <br />042               <br />043               <br />044               <br />045               <br />046               <br />047               <br />048               <br />049               <br />050               <br />051               <br />052               <br />053               <br />054               <br />055               <br />056               <br />057               <br />058               <br />059               <br />060               <br />061               <br />062               <br />063               <br />064               <br />065               <br />066               <br />067               <br />068               <br />069               <br />070               <br />071               <br />072               <br />073               <br />074               <br />075               <br />076               <br />077               <br />078               <br />079               </div>
</td>
<td valign="top" nowrap="nowrap">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #fcfcfc; font-size: 10pt; padding-top: 5px"><span style="color: #006400">&lt;#                <br />.Synopsis                 <br />Opens the desired file(s) in UltraEdit.                 <br />&#160;&#160;&#160;&#160; <br />.Description                 <br />&#160;&#160;&#160; The file(s) you specify on the command line or the pipeline will be opened in UltraEdit. We'll launch a new                 <br />&#160;&#160;&#160; copy of the app, but only if necessary. The pipeline supports many varieties of objects via my Get-FullPath                 <br />&#160;&#160;&#160; script.                 <br />&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; Put this in your $profile:                 <br />&#160;&#160;&#160; PS&gt; . &quot;c:\path\to\invoke-ultraedit.ps1&quot;                 <br />&#160;&#160;&#160; PS&gt; set-alias ue invoke-ultraedit                 <br />&#160;&#160;&#160;&#160; <br />.Parameter File                 <br />&#160;&#160;&#160; Path to the file being opened. Any object that contains such a path as a property named FullName, Path, etc.                 <br />&#160;&#160;&#160; will do.                 <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />.Example                 <br />&#160;&#160;&#160; PS&gt; # open foo.txt in UltraEdit                 <br />&#160;&#160;&#160; PS&gt; ue foo.txt                 <br />&#160;&#160;&#160;&#160; <br />.Example                 <br />&#160;&#160;&#160; PS&gt; # open any project files that contain a HintPath element                 <br />&#160;&#160;&#160; PS&gt; dir -r -fil *csproj | ss hintpath | ue                 <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />.ReturnValue                 </p>
<p>.Link                 <br />&#160;&#160;&#160; <a href="http://richardberg.net/blog/?p=60">http://richardberg.net/blog/?p=60</a>                <br />&#160;&#160;&#160; http://richardberg.net/blog/?p=57                 <br />&#160;&#160;&#160;&#160; <br />.Notes                 <br />NAME: Invoke-UltraEdit.ps1                 <br />AUTHOR: COATUECAP\rberg                 <br />LASTEDIT: 03/27/2009 17:24:02                 </p>
<p>#Requires -Version 2.0                 <br />#&gt;</span>               <br /><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">Invoke-UltraEdit</span>               <br /><span style="color: #000000">{</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">CmdletBinding</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">Param</span><span style="color: #000000">(</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">0</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">ValueFromPipeline</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span><span style="color: #000000">&#160;</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #008080">[psobject]</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$file</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">)</span>               <br /><span style="color: #000000">&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">Begin</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># this path isn't stored anywhere in the registry - you may need to adjust it</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$ue</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">join-path</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$programFilesX86</span><span style="color: #000000">&#160;</span><span style="color: #8b0000">&quot;IDM Computer Solutions\UltraEdit\Uedit32.exe&quot;</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># If UltraEdit isn't running yet, launching it will hang the console until it exits</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># Same deal if there's an elevated UltraEdit process running but our shell is not elevated</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">Function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">HaveToStartNewEditor</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># If there is at least one process whose handle we have permission to grab, we're ok.</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$haveToStart</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$true</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">get-process</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #0000ff">dir</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$ue</span><span style="color: #000000">)</span><span style="color: #a9a9a9">.</span><span style="color: #000000">basename</span><span style="color: #000000">&#160;</span><span style="color: #000080">-ea</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">SilentlyContinue</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">%</span><span style="color: #000000">&#160;</span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Handle</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-ne</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$null</span><span style="color: #000000">)</span><span style="color: #000000">&#160;</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$haveToStart</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$false</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">}</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">return</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$haveToStart</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">}</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>               <br /><span style="color: #000000">&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">Process</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">while</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #0000ff">HaveToStartNewEditor</span><span style="color: #000000">)</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">invoke-item</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$ue</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">sleep</span><span style="color: #000000">&#160;</span><span style="color: #800080">2</span><span style="color: #000000">&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">}</span><span style="color: #000000">&#160;&#160;&#160; </span>              </p>
<p><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># launch with option to use existing window</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">&amp;</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$ue</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">/foi</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">get-fullpath</span><span style="color: #000000">)</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>               <br /><span style="color: #000000">}</span> </div>
</td>
</tr>
</tbody>
</table></div>
<p>As you can probably tell, you’ll need <a href="http://richardberg.net/blog/?p=57">some</a> other <a href="http://richardberg.net/blog/?p=61">code</a> for this to <strike>compile</strike>be interpreted successfully.</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/27/invoke-ultraeditps1-integrate-your-favorite-text-editor-with-the-powershell-pipeline/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Easily manage files in Powershell ISE CTP3</title>
		<link>http://richardberg.net/blog/2009/03/27/easily-manage-files-in-powershell-ise-ctp3/</link>
		<comments>http://richardberg.net/blog/2009/03/27/easily-manage-files-in-powershell-ise-ctp3/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 22:47:31 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=58</guid>
		<description><![CDATA[Since Win7 debuted, I’ve started forcing myself to use the ISE more often.&#160; It doesn’t have a ton of features – even the much awaited debugger lags some v1.0-era 3rd party IDEs – but it does show great potential.&#160; In particular, who doesn’t love an environment that’s scriptable using its native language? :)&#160; [and oh [...]]]></description>
			<content:encoded><![CDATA[<p>Since Win7 debuted, I’ve started forcing myself to use the ISE more often.&#160; It doesn’t have a ton of features – even the much awaited debugger lags some v1.0-era 3rd party IDEs – but it does show great potential.&#160; In particular, who doesn’t love an environment that’s scriptable using its native language? :)&#160; </p>
<p>[and oh yeah, we <strong>finally</strong> get to leave <a href="http://blogs.msdn.com/oldnewthing/archive/2007/12/31/6909007.aspx">the world of CSRSS.exe</a> behind.&#160; Ctrl+V!&#160; sweet blessed Ctrl+V!]</p>
<p>Naturally, I started the customization process by scouring the web.&#160; Keith’s &quot;<a href="http://keithhill.spaces.live.com/blog/cns!5A8D2641E0963A97!6937.entry">Yank Line</a>” function quickly joined my Custom menu.&#160; (though I map it to Ctrl+K, a vestige of muscle memory from <a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=2&amp;url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FPico_(text_editor)&amp;ei=YZrLSdvfMZzulQe1nfDMCQ&amp;usg=AFQjCNE4vLOiu3JKIM8PCbd_yVJWWtMBQA&amp;sig2=OqCRPpsrGXHF3eqqdGLUQQ">Pico</a>.&#160; thanks for the memories, crappy Solaris boxes at Duke!)&#160; Soon after came a <a href="http://get-powershell.com/2008/12/29/code-snippets-in-powershell-ise/">function templater from Andy Schneider</a>, handy especially since the new v2 syntax is pretty verbose.&#160; And of course <a href="http://www.leeholmes.com/blog/MorePowerShellSyntaxHighlighting.aspx">Lee’s syntax highlighter</a>, without which the pretty code you’re seeing would not be possible – though in full disclosure I’ve heavily modified it.&#160; (first to fit into a Module, then to remove the Apartment Threading overhead that’s thankfully not relevant in the ISE, and finally to take the currently selected text instead of the whole document)</p>
<p>Any other recommendations for $profile inclusion?&#160; Or know how to override a keyboard shortcut, for that matter?</p>
<p>Back to the point of this post.&#160; My work style tends to involve dozens of tabs, files scattered all over the place, saved &amp; not, until I clean things up hours later.&#160; So naturally the built-in file management features of ISE have got to go!&#160; With the help of the $psise object model, the <a href="http://richardberg.net/blog/?p=57">get-fullpath script</a> I introduced last time, and liberal additions to the ISE profile (Microsoft.PowerShellISE_profile.ps1), it’s not hard to greatly beef things up:</p>
<ul>
<li>quick Open from the interactive prompt, including rich pipeline support seen in previous posts</li>
<li>ditto for Close</li>
<li>Close All But This</li>
<li>Undo Close with a full FIFO stack of everything you’ve ever closed using my functions</li>
<li>Save All</li>
<li>Copy Full Path to clipboard</li>
</ul>
<div style="border-bottom: black 1px solid; border-left: black 1px solid; padding-bottom: 5px; padding-left: 5px; width: 870px; padding-right: 5px; font-family: consolas,lucida console; height: 1938px; font-size: 10pt; overflow: auto; border-top: black 1px solid; border-right: black 1px solid; padding-top: 5px">
<table border="0" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td valign="top">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #cecece; font-size: 10pt; padding-top: 5px">001             <br />002              <br />003              <br />004              <br />005              <br />006              <br />007              <br />008              <br />009              <br />010              <br />011              <br />012              <br />013              <br />014              <br />015              <br />016              <br />017              <br />018              <br />019              <br />020              <br />021              <br />022              <br />023              <br />024              <br />025              <br />026              <br />027              <br />028              <br />029              <br />030              <br />031              <br />032              <br />033              <br />034              <br />035              <br />036              <br />037              <br />038              <br />039              <br />040              <br />041              <br />042              <br />043              <br />044              <br />045              <br />046              <br />047              <br />048              <br />049              <br />050              <br />051              <br />052              <br />053              <br />054              <br />055              <br />056              <br />057              <br />058              <br />059              <br />060              <br />061              <br />062              <br />063              <br />064              <br />065              <br />066              <br />067              <br />068              <br />069              <br />070              <br />071              <br />072              <br />073              <br />074              <br />075              <br />076              <br />077              <br />078              <br />079              <br />080              <br />081              <br />082              <br />083              <br />084              <br />085              <br />086              <br />087              <br />088              <br />089              <br />090              <br />091              <br />092              <br />093              <br />094              <br />095              <br />096              <br />097              <br />098              <br />099              <br />100              <br />101              <br />102              <br />103              <br />104              <br />105              <br />106              <br />107              <br />108              <br />109              <br />110              <br />111              <br />112              <br />113              </div>
</td>
<td valign="top" nowrap="nowrap">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #fcfcfc; font-size: 10pt; padding-top: 5px"><span style="color: #006400"># quick open from the command prompt. Pipeline enabled :)</span>              <br /><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">ise</span><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">CmdletBinding</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">param</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">parameter</span><span style="color: #000000">(</span><span style="color: #000000">Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$True</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">0</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">ValueFromPipeline</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$True</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #008080">[psobject]</span><span style="color: #ff4500">$file</span><span style="color: #a9a9a9">,</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #008080">[switch]</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$PassThru</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$false</span><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">)</span><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">process</span><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #ff4500">$PassThru</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedRunspace</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OpenedFiles</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add</span><span style="color: #000000">(</span><span style="color: #000000">(</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">get-fullpath</span><span style="color: #000000">)</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">}</span>              </p>
<p><span style="color: #006400"># ditto for close, with my desired keyboard shortcuts</span>              <br /><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">close</span>              <br /><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">CmdletBinding</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">param</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">parameter</span><span style="color: #000000">(</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">0</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">ValueFromPipeline</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$True</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #008080">[psobject]</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #8b0000">&quot;&quot;</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">begin</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># getting desired behavior of &quot;no input = close current file&quot; is harder than it looks...</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$closedSomething</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$false</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># set up global undo buffer</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #ff4500">$RecentlyClosedTabs</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-eq</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$null</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">set-variable</span><span style="color: #000000">&#160;</span><span style="color: #000080">-name</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">RecentlyClosedTabs</span><span style="color: #000000">&#160;</span><span style="color: #000080">-value</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #0000ff">new-object</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">system.collections.stack</span><span style="color: #000000">)</span><span style="color: #000000">&#160;</span><span style="color: #000080">-scope</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">Global</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">process</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-ne</span><span style="color: #000000">&#160;</span><span style="color: #8b0000">&quot;&quot;</span><span style="color: #000000">)</span><span style="color: #000000">&#160; </span><span style="color: #006400"># thought I could use the 'continue' statement instead of a giant If block, but it exits the whole function</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$fullPath</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">get-fullpath</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #000000">@(</span><span style="color: #ff4500">$fullPath</span><span style="color: #000000">)</span><span style="color: #a9a9a9">.</span><span style="color: #000000">count</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-gt</span><span style="color: #000000">&#160;</span><span style="color: #800080">0</span><span style="color: #000000">)</span><span style="color: #000000">&#160; </span><span style="color: #006400"># can't simply check against null for some weird reason</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># because there is no constructor for System.Management.Automation.Host.OpenedFile, I have to do stupid iteration</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># that makes this routine n^2</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$fileToClose</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedRunspace</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OpenedFiles</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">?</span><span style="color: #000000">&#160;</span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">fullpath</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-eq</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$fullpath</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedRunspace</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OpenedFiles</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Remove</span><span style="color: #000000">(</span><span style="color: #ff4500">$fileToClose</span><span style="color: #000000">)</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">out-null</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$closedSomething</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$true</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$RecentlyClosedTabs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Push</span><span style="color: #000000">(</span><span style="color: #ff4500">$fullPath</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">end</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #a9a9a9">!</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$closedSomething</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$curFile</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedFile</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedRunspace</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OpenedFiles</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Remove</span><span style="color: #000000">(</span><span style="color: #ff4500">$curFile</span><span style="color: #000000">)</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">out-null</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$RecentlyClosedTabs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Push</span><span style="color: #000000">(</span><span style="color: #ff4500">$curFile</span><span style="color: #000000">)</span><span style="color: #000000">&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># after we've closed a file, chances are we don't want the cursor stuck in another random file</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedRunspace</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CommandPane</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Focus</span><span style="color: #000000">(</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">}</span>              <br /><span style="color: #006400"># $psISE.CustomMenu.Submenus.Add('_Close File', {close}, 'Ctrl+W') # can't overwrite keyboard shortcuts :(</span>              </p>
<p><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">CloseAllButThis</span>              <br /><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #006400"># need to clone the array of opened files since we'll be modifying it as we enumerate</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #ff4500">$temp</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #008080">[array]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">createinstance</span><span style="color: #000000">(</span><span style="color: #008080">[System.Management.Automation.Host.OpenedFile]</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedRunspace</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OpenedFiles</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Count</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedRunspace</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OpenedFiles</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CopyTo</span><span style="color: #000000">(</span><span style="color: #ff4500">$temp</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #800080">0</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #006400"># edge case: if there's only 1 file open, do nothing</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #ff4500">$temp</span><span style="color: #a9a9a9">.</span><span style="color: #000000">count</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-eq</span><span style="color: #000000">&#160;</span><span style="color: #800080">1</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #00008b">break</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span>              <br /><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #006400"># close the files</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #ff4500">$temp</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">?</span><span style="color: #000000">&#160;</span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$_</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-ne</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedFile</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">close</span>              <br /><span style="color: #000000">}</span>              <br /><span style="color: #ff4500">$psISE</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CustomMenu</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Submenus</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add</span><span style="color: #000000">(</span><span style="color: #8b0000">'Close All But _This'</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">{</span><span style="color: #0000ff">CloseAllButThis</span><span style="color: #000000">}</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #8b0000">'Ctrl+Shift+W'</span><span style="color: #000000">)</span>              </p>
<p><span style="color: #006400"># this will spew errors when there are Untitled files, but I kinda like that behavior</span>              <br /><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">SaveAll</span>              <br /><span style="color: #000000">{</span><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedRunspace</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OpenedFiles</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">%</span><span style="color: #000000">&#160;</span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$_</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Save</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span>              <br /><span style="color: #000000">}</span>              <br /><span style="color: #ff4500">$psISE</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CustomMenu</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Submenus</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add</span><span style="color: #000000">(</span><span style="color: #8b0000">'_Save All'</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">{</span><span style="color: #0000ff">CloseAllButThis</span><span style="color: #000000">}</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #8b0000">'Ctrl+Alt+S'</span><span style="color: #000000">)</span><span style="color: #000000">&#160; </span><span style="color: #006400"># really want Ctrl+Shift+S :(</span>              </p>
<p><span style="color: #006400"># undo close tab(s)</span>              <br /><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">UndoClose</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #008080">[int]</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$files</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #800080">1</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #ff4500">$RecentlyClosedTabs</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-eq</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$null</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-or</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$RecentlyClosedTabs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Count</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-le</span><span style="color: #000000">&#160;</span><span style="color: #800080">0</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-or</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$files</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-le</span><span style="color: #000000">&#160;</span><span style="color: #800080">0</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #00008b">break</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #006400"># if user tries to pop more items than we have on the stack, just let the error bubble up</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">while</span><span style="color: #000000">(</span><span style="color: #ff4500">$files</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">-gt</span><span style="color: #000000">&#160;</span><span style="color: #800080">0</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$RecentlyClosedTabs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Pop</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">ise</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">--</span><span style="color: #ff4500">$files</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">}</span>              <br /><span style="color: #ff4500">$psISE</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CustomMenu</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Submenus</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add</span><span style="color: #000000">(</span><span style="color: #8b0000">'_Undo Close'</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">{</span><span style="color: #0000ff">UndoClose</span><span style="color: #000000">}</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #8b0000">'Ctrl+Alt+U'</span><span style="color: #000000">)</span>              </p>
<p><span style="color: #006400"># copy full path of the open file to the clipboard</span>              <br /><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">Get-OpenedPath</span>              <br /><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedFile</span><span style="color: #a9a9a9">.</span><span style="color: #000000">FullPath</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">out-clipboard</span>              <br /><span style="color: #000000">}</span>              <br /><span style="color: #ff4500">$psISE</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CustomMenu</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Submenus</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add</span><span style="color: #000000">(</span><span style="color: #8b0000">'Copy Full _Path'</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">{</span><span style="color: #0000ff">Get-OpenedPath</span><span style="color: #000000">}</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #8b0000">'Ctrl+Alt+C'</span><span style="color: #000000">)</span> </div>
</td>
</tr>
</tbody>
</table></div>
<p>As you can see, the Close function ended up much uglier than expected.&#160; Powershell limitations/bugs or programmer ignorance?&#160; Suggestions welcome.&#160; <em>Powershell verb-noun Nazis need not apply.&#160; Functions which live only in the $profile for quick consumption at the interactive prompt and/or ISE shortcut key are not obligated to follow the rules for discoverability, IMO.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/27/easily-manage-files-in-powershell-ise-ctp3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fixing consistency issues with Powershell&#8217;s filename properties</title>
		<link>http://richardberg.net/blog/2009/03/27/fixing-consistency-issues-with-powershells-filename-properties/</link>
		<comments>http://richardberg.net/blog/2009/03/27/fixing-consistency-issues-with-powershells-filename-properties/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 21:06:55 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=57</guid>
		<description><![CDATA[When I decided to bitch about select-object, I used “dir” in my examples for a reason: passing filesystem objects around the pipeline is simultaneously one of the most common yet one of the most annoying things you can do in Powershell.&#160; Let’s review some built-in cmdlets from the POV of getting the full path to [...]]]></description>
			<content:encoded><![CDATA[<p>When I decided to <a href="http://richardberg.net/blog/?p=55">bitch about select-object</a>, I used “dir” in my examples for a reason: passing filesystem objects around the pipeline is simultaneously one of the most common yet one of the most annoying things you can do in Powershell.&#160; Let’s review some built-in cmdlets from the POV of getting the full path to a given file or folder:</p>
<table border="0" cellspacing="0" cellpadding="2" width="545">
<tbody>
<tr>
<td valign="top" width="247"><strong>Cmdlet</strong></td>
<td valign="top" width="129"><em>Input property name accepted on pipeline</em></td>
<td valign="top" width="167"><em>Output property name on object sent to pipeline</em></td>
</tr>
<tr>
<td valign="top" width="247">Get-Item, Get-ChildItem, Set-Item</td>
<td valign="top" width="129">Path</td>
<td valign="top" width="167">FullName</td>
</tr>
<tr>
<td valign="top" width="247">Join-Path, Split-Path, Test-Path</td>
<td valign="top" width="129">Path</td>
<td valign="top" width="167">n/a</td>
</tr>
<tr>
<td valign="top" width="247">Resolve-Path, Select-String</td>
<td valign="top" width="129">Path</td>
<td valign="top" width="167">Path*</td>
</tr>
<tr>
<td valign="top" width="247">New-Item</td>
<td valign="top" width="129">Name</td>
<td valign="top" width="167">FullName</td>
</tr>
</tbody>
</table>
<p><em>* note that the built-in documentation for Resolve-Path is wrong!&#160; as of CTP3, it’s claiming the output is a string</em></p>
<p>Plus, you may be working with 3rd party tools that obey <em>none </em>of the above conventions.&#160; </p>
<p>For example, with the TFS Power Tools, Hyung had the foresight to add string[] to the list of types we can <a href="http://richardberg.net/blog/?p=30">convert to <strong>QualifiedItems</strong> behind the scenes</a> using extra constructors, but we still don’t support the <a href="http://msdn.microsoft.com/en-us/library/system.management.automation.parameterattribute.valuefrompipelinebypropertyname(VS.85).aspx">ValueFromPipelineByPropertyName</a> idiom that’s needed to make non-trivial filesystem objects flow.&#160; Furthermore, the objects we output are native TFS types, which were never designed with Powershell in mind.&#160; Most of the time there’s little overlap between these objects and non-TFS cmdlets, but a big exception is the LocalItem property of the <strong>ExtendedItem </strong>object returned by “tfprop.”&#160; In hindsight, we should have added a NoteProperty that aliased it to Path.&#160; (…or FullName, or Name, depending on whether the PS guys make up their mind :) )</p>
<p>Then there are tools that have nothing at all to do with Powershell.&#160; Some sort of wrapper script is going to be required regardless, but without consistency in the kind of input your wrapper can expect, it can get needlessly complex.</p>
<p>My solution to all of the above is outlined below.&#160; Time to let the code do the talking:</p>
<div style="border-bottom: black 1px solid; border-left: black 1px solid; padding-bottom: 5px; padding-left: 5px; width: 886px; padding-right: 5px; font-family: consolas,lucida console; height: 468px; font-size: 10pt; overflow: auto; border-top: black 1px solid; border-right: black 1px solid; padding-top: 5px">
<table border="0" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td valign="top">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #cecece; font-size: 10pt; padding-top: 5px">001              <br />002               <br />003               <br />004               <br />005               <br />006               <br />007               <br />008               <br />009               <br />010               <br />011               <br />012               <br />013               <br />014               <br />015               <br />016               <br />017               <br />018               <br />019               <br />020               <br />021               <br />022               <br />023               <br />024               <br />025               </div>
</td>
<td valign="top" nowrap="nowrap">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #fcfcfc; font-size: 10pt; padding-top: 5px"><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">get-fullpath</span>               <br /><span style="color: #000000">{</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">CmdletBinding</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">Param</span><span style="color: #000000">(</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span><span style="color: #000000">ParameterSetName</span><span style="color: #a9a9a9">=</span><span style="color: #8b0000">&quot;ByPropertyName&quot;</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">0</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">ValueFromPipelineByPropertyName</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">ValueFromPipeline</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">Alias</span><span style="color: #000000">(</span><span style="color: #8b0000">&quot;FullName&quot;</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">Alias</span><span style="color: #000000">(</span><span style="color: #8b0000">&quot;FullPath&quot;</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># [Alias(&quot;Name&quot;)] - too many false positives</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">Alias</span><span style="color: #000000">(</span><span style="color: #8b0000">&quot;Path&quot;</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">Alias</span><span style="color: #000000">(</span><span style="color: #8b0000">&quot;LocalItem&quot;</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #008080">[string]</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$file</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">)</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">Process</span>               <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># eliminate nonexistent files, obviously, but also random objects that were coerced from the pipeline by calling their ToString() method</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #a9a9a9">!</span><span style="color: #000000">(</span><span style="color: #0000ff">test-path</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$file</span><span style="color: #000000">)</span><span style="color: #000000">)</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #00008b">break</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># expand relative paths (in case the immediate window's workingdir != the workingdir of powershell_ise.exe) </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">resolve-path</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #006400"># and also make sure UNC paths are in normal format, not Powershell format</span>               <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">convert-path</span><span style="color: #000000">&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>               <br /><span style="color: #000000">}</span> </div>
</td>
</tr>
</tbody>
</table></div>
<p>Who knew that ValueFromPipelineByPropertyName worked on aliases?&#160; I didn’t.&#160; I thought it would be nice, but since I didn’t see it documented anywhere, my initial sketch for this function used a ton of ugly ParameterSets as a workaround.&#160; Somewhere in there I decided to try Aliases; lo and behold, it works!&#160; Yay.</p>
<p>This function is useful on its own – if nothing else I use it as a wholesale replacement for resolve-path, whose behavior on UNC paths is bizarre in my opinion – but its real value is as a helper.&#160; For example, a couple snippets from my $profile:</p>
<div style="border-bottom: black 1px solid; border-left: black 1px solid; padding-bottom: 5px; padding-left: 5px; width: 750px; padding-right: 5px; font-family: consolas,lucida console; font-size: 10pt; overflow: auto; border-top: black 1px solid; border-right: black 1px solid; padding-top: 5px">
<table border="0" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td valign="top">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #cecece; font-size: 10pt; padding-top: 5px">001             <br />002              <br />003              <br />004              <br />005              <br />006              <br />007              <br />008              <br />009              <br />010              <br />011              <br />012              <br />013              <br />014              <br />015              <br />016              <br />017              </div>
</td>
<td valign="top" nowrap="nowrap">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #fcfcfc; font-size: 10pt; padding-top: 5px"><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">tfedit</span><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">{</span>              <br /><span style="color: #000000"></span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">CmdletBinding</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">Param</span><span style="color: #000000">(</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">0</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">ValueFromPipeline</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #008080">[psobject]</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$file</span><span style="color: #a9a9a9">,</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #008080">[switch]</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$PassThru</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$false</span><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">Process</span><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #ff4500">$PassThru</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">tfpend</span><span style="color: #000000">&#160;</span><span style="color: #000080">-edit</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">get-fullpath</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">}</span> </div>
</td>
</tr>
</tbody>
</table></div>
<p>&#160;</p>
<div style="border-bottom: black 1px solid; border-left: black 1px solid; padding-bottom: 5px; padding-left: 5px; width: 750px; padding-right: 5px; font-family: consolas,lucida console; font-size: 10pt; overflow: auto; border-top: black 1px solid; border-right: black 1px solid; padding-top: 5px">
<table border="0" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td valign="top">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #cecece; font-size: 10pt; padding-top: 5px">001             <br />002              <br />003              <br />004              <br />005              <br />006              <br />007              <br />008              <br />009              <br />010              <br />011              <br />012              <br />013              <br />014              <br />015              <br />016              </div>
</td>
<td valign="top" nowrap="nowrap">
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas,lucida console; background: #fcfcfc; font-size: 10pt; padding-top: 5px"><span style="color: #00008b">function</span><span style="color: #000000">&#160;</span><span style="color: #8a2be2">ise</span><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">CmdletBinding</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">param</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">parameter</span><span style="color: #000000">(</span><span style="color: #000000">Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$True</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">0</span><span style="color: #a9a9a9">,</span><span style="color: #000000">&#160;</span><span style="color: #000000">ValueFromPipeline</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$True</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #008080">[psobject]</span><span style="color: #ff4500">$file</span><span style="color: #a9a9a9">,</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #008080">[switch]</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$PassThru</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">=</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$false</span><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">)</span><span style="color: #000000">&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #00008b">process</span><span style="color: #000000">&#160;</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">{</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #00008b">if</span><span style="color: #000000">&#160;</span><span style="color: #000000">(</span><span style="color: #ff4500">$PassThru</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #000000">{</span><span style="color: #000000">&#160;</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #000000">}</span><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>              <br /><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #ff4500">$psise</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentOpenedRunspace</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OpenedFiles</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add</span><span style="color: #000000">(</span><span style="color: #000000">(</span><span style="color: #ff4500">$file</span><span style="color: #000000">&#160;</span><span style="color: #a9a9a9">|</span><span style="color: #000000">&#160;</span><span style="color: #0000ff">get-fullpath</span><span style="color: #000000">)</span><span style="color: #000000">)</span>              <br /><span style="color: #000000">&#160;&#160;&#160; </span><span style="color: #000000">}</span>              <br /><span style="color: #000000">}</span> </div>
</td>
</tr>
</tbody>
</table></div>
<p>I think the PS parser should be smart enough that double-parens are not required in the second example, but oh well.&#160; Pretty simple overall, and super convenient.&#160; Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/27/fixing-consistency-issues-with-powershells-filename-properties/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Select-Object is annoying</title>
		<link>http://richardberg.net/blog/2009/03/26/select-object-is-annoying/</link>
		<comments>http://richardberg.net/blog/2009/03/26/select-object-is-annoying/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 16:23:59 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=55</guid>
		<description><![CDATA[Oh how I long for a real Select command.&#160; I’m not a SQL-head by any stretch, but I recognize the need for basic set operations like projection.&#160; The language geeks in DevDiv surely do too: witness LINQ, and to some degree, Powershell itself.&#160; However, I argue PS is falling short on this front. dir &#124; [...]]]></description>
			<content:encoded><![CDATA[<p>Oh how I long for a real Select command.&#160; I’m not a SQL-head by any stretch, but I recognize the need for basic set operations like projection.&#160; The language geeks in DevDiv surely do too: witness LINQ, and to some degree, Powershell itself.&#160; However, I argue PS is falling short on this front.</p>
<p><font face="Courier New">dir | select fullname, lastwritetime</font></p>
<p><font face="Courier New">FullName&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LastWriteTime&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />--------&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; -------------&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />C:\Users\rberg\Contacts&#160;&#160;&#160; 2/19/2009 12:34:40 PM       <br />C:\Users\rberg\Desktop&#160;&#160;&#160;&#160; 3/24/2009 12:49:31 PM       <br />C:\Users\rberg\Documents&#160;&#160; 3/23/2009 4:34:23 PM       <br />C:\Users\rberg\Downloads&#160;&#160; 3/25/2009 6:38:20 PM       <br />C:\Users\rberg\Favorites&#160;&#160; 2/19/2009 12:34:43 PM       <br />C:\Users\rberg\Links&#160;&#160;&#160;&#160;&#160;&#160; 3/10/2009 3:36:02 PM       <br />C:\Users\rberg\Music&#160;&#160;&#160;&#160;&#160;&#160; 2/19/2009 1:26:36 PM       <br />C:\Users\rberg\Pictures&#160;&#160;&#160; 2/19/2009 1:26:38 PM       <br />C:\Users\rberg\Saved Games 2/19/2009 12:34:40 PM       <br />C:\Users\rberg\Searches&#160;&#160;&#160; 2/19/2009 12:34:49 PM       <br />C:\Users\rberg\Videos&#160;&#160;&#160;&#160;&#160; 2/19/2009 1:26:39 PM       <br />C:\Users\rberg\.kdiff3rc&#160;&#160; 3/25/2009 5:23:33 PM       <br />C:\Users\rberg\_lesshst&#160;&#160;&#160; 3/4/2009 3:01:33 PM</font>&#160; </p>
<p>It looks like it’s doing something useful, right?&#160; But the more I use Powershell, the more it seems like it’s violating its own guidelines like “input &amp; output should be useful objects, not text-based hacks” and “design for the middle of the pipeline.”&#160; Let’s examine what Select-Object really returns.&#160; </p>
<p><font face="Courier New">PS &gt;dir .\foo.txt | select name | gm </font></p>
<p><font face="Courier New">&#160;&#160; TypeName: Selected.System.IO.FileInfo </font></p>
<p><font face="Courier New">Name&#160;&#160;&#160;&#160;&#160;&#160;&#160; MemberType&#160;&#160; Definition&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />----&#160;&#160;&#160;&#160;&#160;&#160;&#160; ----------&#160;&#160; ----------&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />Equals&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160; System.Boolean Equals(Object obj)       <br />GetHashCode Method&#160;&#160;&#160;&#160;&#160;&#160; System.Int32 GetHashCode()&#160;&#160;&#160;&#160;&#160;&#160; <br />GetType&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160; System.Type GetType()&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />ToString&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160; System.String ToString()&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />Name&#160;&#160;&#160;&#160;&#160;&#160;&#160; NoteProperty System.String Name=foo.txt</font>&#160; </p>
<p>That’s not a Name, that’s something else entirely.&#160; Besides, I get the feeling it’s not being completely honest with me…doesn’t a FileInfo object have more methods?…</p>
<p><font face="Courier New">PS &gt;(dir .\foo.txt | select name).gettype() </font></p>
<p><font face="Courier New">IsPublic IsSerial Name&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; BaseType      <br />-------- -------- ----&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; --------       <br />True&#160;&#160;&#160;&#160; False&#160;&#160;&#160; PSCustomObject&#160;&#160;&#160;&#160; System.Object&#160; </font></p>
<p>Caught ya!&#160; Liar!&#160; </p>
<p>I wouldn’t mind a little custom magic going on under the hood if it meant more power in the user’s hands.&#160; But in reality, these <strong>PSCustomObjects</strong> being tossed around seem to be of very little utility.&#160; In almost every case, simply returning the native type (e.g. a <strong>System.String</strong> in the case of “select name”) would play nicer with the rest of the pipeline.&#160; I understand there’s a tough barrier when you start selecting multiple objects, or when you want lazy evaluation -- but sorry guys, the current solution ain’t it.</p>
<p>To be clear, I want to be able to do stuff like:</p>
<p><font face="Courier New">$a = dir foo.txt | select lastwritetime      <br /># oops, we don’t have a real DateTime       <br />$b = $a.adddays(1)&#160;&#160; </p>
<p># oops, neither a string nor a ‘name’ property       <br />dir *.exe | select basename | get-process&#160; </font></p>
<p><font face="Courier New"># not even the NoteProperties work in a useful manner      <br />dir | select psparentpath | convert-path       </p>
<p># wouldn’t this be cool?&#160; PS already has </font><a href="http://einsteintech.spaces.live.com/blog/cns!89E05724AF67A39E!780.entry"><font face="Courier New">quasi tuple syntax</font></a><font face="Courier New">, after all      <br />$x, $y = dir | select attributes, length       </p>
<p># or this?&#160; assume do-something is a cmdlet that takes 3 strongly typed parameters by position      <br /># and/or by property name      <br />dir | select fullname –as path, versioninfo, isreadonly –as force | do-something</font></p>
<p>Am I crazy to want these to work?&#160; Anyone know of ongoing work in this area before I waste some hobby time? :)</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/26/select-object-is-annoying/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Brilliant Powershell posts</title>
		<link>http://richardberg.net/blog/2009/03/26/brilliant-powershell-posts/</link>
		<comments>http://richardberg.net/blog/2009/03/26/brilliant-powershell-posts/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 14:43:45 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=54</guid>
		<description><![CDATA[Working at Microsoft, it’s almost impossible to not stay plugged into the technology zeitgeist.&#160; Until you get your email filters set up properly – inevitably running into the Exchange limits – your inbox is literally a news ticker.&#160; Needless to say, establishing that kind of community doesn’t happen automatically in the “real world.”&#160; So in [...]]]></description>
			<content:encoded><![CDATA[<p>Working at Microsoft, it’s almost impossible to <em>not</em> stay plugged into the technology zeitgeist.&#160; Until you get your email filters set up properly – inevitably running into <a href="http://support.microsoft.com/default.aspx/kb/886616">the Exchange limits</a> – your inbox is literally a news ticker.&#160; Needless to say, establishing that kind of community doesn’t happen automatically in the “real world.”&#160; So in the last week or two I’ve been fleshing out my RSS feed subscriptions. </p>
<p>In the process, I’ve come across some people doing seriously amazing things with Powershell.&#160; Some of these efforts I hope I can find time to contribute and extend; others I’ll just sit back in awe.&#160; (I’m not saying which is which…you too will have to subscribe!)</p>
<ul>
<li>Bart de Smet</li>
<ul>
<li><a title="http://community.bartdesmet.net/blogs/bart/archive/2008/06/07/linq-through-powershell.aspx" href="http://community.bartdesmet.net/blogs/bart/archive/2008/06/07/linq-through-powershell.aspx">Real LINQ cmdlets for Powershell</a> – based on “lazy” expression tree builders, with the full range of operators, not just the few “greedy” *-Object functions PS comes with</li>
<li><a title="http://community.bartdesmet.net/blogs/bart/archive/2008/02/03/method-invocation-cmdlets-in-windows-powershell.aspx" href="http://community.bartdesmet.net/blogs/bart/archive/2008/02/03/method-invocation-cmdlets-in-windows-powershell.aspx">Autogenerating cmdlets that mirror an object's method calls</a></li>
<li><a title="http://bartdesmet.net/blogs/bart/archive/2007/09/06/extension-methods-in-windows-powershell.aspx" href="http://bartdesmet.net/blogs/bart/archive/2007/09/06/extension-methods-in-windows-powershell.aspx">Using Powershell's ETS to surface extension methods</a> – reminds me of my <a href="http://blogs.msdn.com/richardb/archive/2007/02/21/add-types-ps1-poor-man-s-using-for-powershell.aspx">add-types.ps1</a>, but more broadly useful since it incorporates the design intent embedded in the extension methods’ type info rather than importing blindly</li>
</ul>
<li>Lance</li>
<ul>
<li><a title="http://geekswithblogs.net/Lance/archive/2008/12/22/how-to-execute-sql-powershell-commands-anywhere.aspx" href="http://geekswithblogs.net/Lance/archive/2008/12/22/how-to-execute-sql-powershell-commands-anywhere.aspx">Executing SQL / Powershell statements from your iPhone</a> – are you kidding me?!!</li>
</ul>
<li>James Brundage</li>
<ul>
<li><a title="http://blogs.msdn.com/mediaandmicrocode/archive/2008/10/20/microcode-scripting-tricks-exploring-wpf-routed-events-with-powershell-and-get-member-where-object-and-group-object.aspx" href="http://blogs.msdn.com/mediaandmicrocode/archive/2008/10/20/microcode-scripting-tricks-exploring-wpf-routed-events-with-powershell-and-get-member-where-object-and-group-object.aspx">Exploring WPF routed events</a></li>
<li><a title="http://blogs.msdn.com/mediaandmicrocode/archive/2008/07/21/microcode-cleaning-up-dvr-with-get-recordedtv.aspx" href="http://blogs.msdn.com/mediaandmicrocode/archive/2008/07/21/microcode-cleaning-up-dvr-with-get-recordedtv.aspx">Cmdlets for maintaining your Recorded TV folder</a></li>
</ul>
<li>Josh Einstein</li>
<ul>
<li><a href="http://einsteintech.spaces.live.com/Blog/cns!89E05724AF67A39E!735.entry">Quick &amp; dirty progress bars</a></li>
<li><a href="http://einsteintech.spaces.live.com/Blog/cns!89E05724AF67A39E!688.entry?sa=922002289">Quick &amp; dirty menus</a></li>
</ul>
</ul>
<p>&#160;</p>
<p>Happy scripting!</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/26/brilliant-powershell-posts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TFS Powershell cmdlets default to -noprompt</title>
		<link>http://richardberg.net/blog/2009/03/16/tfs-powershell-cmdlets-default-to-noprompt-2/</link>
		<comments>http://richardberg.net/blog/2009/03/16/tfs-powershell-cmdlets-default-to-noprompt-2/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 15:35:12 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=53</guid>
		<description><![CDATA[The title kinda says it all.&#160; But as usual, there’s a backstory to tell and some ramifications to warn you about. First, let’s look back at the legacy tf.exe command line.&#160; In the effort to be both user friendly and flexible, its behavior has actually become quite complicated.&#160; As of TFS 2008, the logic appears [...]]]></description>
			<content:encoded><![CDATA[<p>The title kinda says it all.&#160; But as usual, there’s a backstory to tell and some ramifications to warn you about.</p>
<p>First, let’s look back at the legacy tf.exe command line.&#160; In the effort to be both user friendly and flexible, its behavior has actually become quite complicated.&#160; As of TFS 2008, the logic appears to be evaluated in this order of precedence:</p>
<ol>
<li>If the <font face="Courier New">/prompt</font> flag is present for this command, always use Prompt mode, otherwise</li>
<li>If the <font face="Courier New">/noprompt</font> flag is present for this command, always use Noprompt mode, otherwise</li>
<li>If the tf.exe process’ stdout stream is redirected, use Noprompt mode (unless the environment variable TFS_IGNORESTDOUTREDIRECT is set), otherwise</li>
<li>If executing in <a href="http://msdn.microsoft.com/en-us/library/56f7w6be.aspx">script mode</a> with a @command file, use Noprompt mode (unless the most recent invocation of the setnoprompt command was “setnoprompt false”), otherwise</li>
<li>Default to Prompt mode</li>
</ol>
<p>Yikes.&#160; I’d actually forgotten just how many variables there were until I started running tests for this blog post.&#160; Suffice to say, the Powershell cmdlets approach things in a much simpler way:</p>
<ol>
<li>If the <font face="Courier New">–prompt</font> switch is present for this cmdlet, always use Prompt mode, otherwise</li>
<li>Default to Noprompt mode</li>
</ol>
<p>Simple enough.&#160; I know a lot of power users will rejoice at this, having long since resigned themselves to <font face="Courier New">/i</font> muscle memory lest random WinForms interrupt their console workflow.&#160; However, there are ramifications to this behavior that you should be aware of.&#160; “Prompt mode” means more than simply popping up dialogs.&#160; First of all, there are some UI features that are still not accessible in Prompt mode without additional parameters, such as <font face="Courier New">tf diff /configure</font>.&#160; More importantly, leaving Prompt mode turns off a number of safeguards:</p>
<ul>
<li>Undo will <strong>permanently</strong> discard your local changes.&#160; (I think TFS should use the Recycle Bin, but that’s another show…)</li>
<li>Shelve /delete will <strong>permanently</strong> delete shelvesets.&#160; (The server used to keep them around until a cleanup job ran, but again that’s the way things work now.)</li>
<li>Destroy, well, destroys.</li>
</ul>
<p>These aren’t the only examples; you get the idea.&#160; None of this behavior is new to TFS in general, but with the default settings of the Powershell tool, it’s a lot easier to shoot yourself in the foot.&#160; Even good old Checkin is likely to surprise you the first time you see it simply <strong><em>go</em> </strong>without any further interaction.&#160; <em>[a “no blank comments” checkin policy might help here, nudge nudge]</em>&#160; </p>
<p>So have fun, just be careful.&#160; If you’re using the power tools then you are ready to be a power user, right? :)</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/16/tfs-powershell-cmdlets-default-to-noprompt-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why is the TFS Powershell snapin marked 32-bit only?</title>
		<link>http://richardberg.net/blog/2009/03/13/why-is-the-tfs-powershell-snapin-marked-32-bit-only/</link>
		<comments>http://richardberg.net/blog/2009/03/13/why-is-the-tfs-powershell-snapin-marked-32-bit-only/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 17:46:27 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=51</guid>
		<description><![CDATA[Short answer: because the TFS core assemblies are marked 32-bit only. Like everyone else, I wish the TFS team had supported x64 much earlier on.&#160; You can see in Microsoft.TeamFoundation.Common.dll that while there are a decent number of routines under the NativeMethods static class that need to be ported, it’s not an enormous task.&#160; Turns [...]]]></description>
			<content:encoded><![CDATA[<p>Short answer: because the TFS core assemblies are marked 32-bit only.</p>
<p>Like everyone else, I wish the TFS team had supported x64 much earlier on.&#160; You can see in Microsoft.TeamFoundation.Common.dll that while there are a decent number of routines under the NativeMethods static class that need to be ported, it’s not an enormous task.&#160; Turns out that supporting setup and deployment on x64 servers (with all the requisite expansion of the test matrix, etc.) is by far the higher cost.&#160; Good news is that x64 is supposed to be on the Rosario feature list.</p>
<p>In the meantime, I can’t have <a href="http://www.wintellect.com/CS/blogs/jrobbins/archive/2008/12/31/powershell-one-year-later.aspx">John Robbins’ impression of our power tool</a> be negative!&#160; I consider my trip to attend his “Native Windows Debugging” class one of the highlights of my MS career.&#160; As a TFS power user I frequently live in x86 shells, so here’s a tidbit from my $profile that helps keep me sane:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:41cfae52-9136-4e9f-91bd-498b946f9c19" class="wlWriterEditableSmartContent">
<pre style="background-color:White;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">$isX86Process </span><span style="color: #000000;">=</span><span style="color: #000000;"> ( $env:Processor_Architecture </span><span style="color: #000000;">-</span><span style="color: #000000;">eq </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">x86</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> )

...

$Global:PscxHostTitlePreference </span><span style="color: #000000;">=</span><span style="color: #000000;"> { $(</span><span style="color: #0000FF;">if</span><span style="color: #000000;"> ($IsAdmin) { </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Admin: </span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> }) </span><span style="color: #000000;">+</span><span style="color: #000000;">
                                    $PscxWindowTitlePrefix </span><span style="color: #000000;">+</span><span style="color: #000000;">
                                    $(get</span><span style="color: #000000;">-</span><span style="color: #000000;">location).Path </span><span style="color: #000000;">+</span><span style="color: #000000;">
                                    $(</span><span style="color: #0000FF;">if</span><span style="color: #000000;"> ($IsX86Process) {</span><span style="color: #800000;">&quot;</span><span style="color: #800000;"> (x86)</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">})
                                  }</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>Naturally, I like Vivek’s auto-Fork example too – may need to incorporate somewhere into my library of stuff…</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/13/why-is-the-tfs-powershell-snapin-marked-32-bit-only/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to diff a file that&#8217;s not in your workspace?</title>
		<link>http://richardberg.net/blog/2009/03/11/how-to-diff-a-file-thats-not-in-your-workspace/</link>
		<comments>http://richardberg.net/blog/2009/03/11/how-to-diff-a-file-thats-not-in-your-workspace/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 19:05:53 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=49</guid>
		<description><![CDATA[The documentation for “tf diff” indicates that it should be possible to do things like tf diff /server:myserver.com c:\file.txt $/project/file.txt Unfortunately, this syntax is not supported.&#160; (Neither is the /workspace parameter, in case you were wondering.)&#160; It’s an oversight I hope will be corrected in the future.&#160; Until then, here’s a quick fix: tf view [...]]]></description>
			<content:encoded><![CDATA[<p>The documentation for “tf diff” indicates that it should be possible to do things like    <br /><font face="Courier New">tf diff /server:myserver.com c:\file.txt $/project/file.txt</font></p>
<p><a href="http://social.msdn.microsoft.com/Forums/en-US/tfsversioncontrol/thread/369b1a36-9126-4627-be42-bf60a59604fe/">Unfortunately, this syntax is not supported</a>.&#160; (Neither is the /workspace parameter, in case you were wondering.)&#160; It’s an oversight I hope will be corrected in the future.&#160; Until then, here’s a quick fix:</p>
<p><font face="Courier New">tf view $/project/file.txt &gt; temp.txt      <br />tf diff c:\file.txt temp.txt       <br />del temp.txt</font></p>
<p>This technique should be easy to put into your scripting language of choice.</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/03/11/how-to-diff-a-file-thats-not-in-your-workspace/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More on ConvertTo-FixedByte vs Powershell Community Extensions</title>
		<link>http://richardberg.net/blog/2009/02/25/more-on-convertto-fixedbyte-vs-powershell-community-extensions/</link>
		<comments>http://richardberg.net/blog/2009/02/25/more-on-convertto-fixedbyte-vs-powershell-community-extensions/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 02:00:42 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=47</guid>
		<description><![CDATA[Last time we introduced two undocumented cmdlets that shipped with the TFS Fall ‘08 power tools.&#160; The idea behind ConvertTo-FixedByte is probably familiar to anyone who’s used Format-Byte from PSCX.&#160; Take a number and make it pretty.&#160; That’s it -- even the dirt simple conversion from “0” to “&#60;DIR&#62;” is handled in the formatter XML, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://richardberg.net/blog/?p=46">Last time</a> we introduced two undocumented cmdlets that shipped with the TFS Fall ‘08 power tools.&#160; The idea behind ConvertTo-FixedByte is probably familiar to anyone who’s used Format-Byte from <a href="www.codeplex.com/PowerShellCX">PSCX</a>.&#160; Take a number and make it pretty.&#160; That’s it -- even the dirt simple conversion from “0” to “&lt;DIR&gt;” is handled in the formatter XML, not the cmdlet.</p>
<p>However, there are some key differences: </p>
<ul>
<li>ConvertTo-FixedByte lets you specify any width between 6 and 22, while Format-Byte is fixed at 10 characters.</li>
<li>ConvertTo-FixedByte allows the entire UInt64 range (~10^20), while Format-Byte only goes up to TB (~10^15).</li>
<li>ConvertTo-FixedByte does not allow pipeline input, while Format-Byte does.</li>
<li>ConvertTo-FixedByte uses the <a href="http://en.wikipedia.org/wiki/SI_prefix">SI standard prefixes</a>, as <a href="http://en.wikipedia.org/wiki/Megabyte#Definition">recommended by IEC, IEEE, EU, and NIST</a>.&#160; Format-Byte uses binary-based prefixes (although it does not display them as KiB, MiB, etc).       <br /><font face="Courier New">PS&gt; convertto-fixedbyte 2000 -width 10        <br />&#160;&#160;&#160;&#160;&#160; 2 KB         <br />PS&gt; format-byte 2000         <br />&#160; 1.953 KB</font> </li>
<li>ConvertTo-FixedByte uses the biggest possible unit so long as the value is at least one unit.&#160; Format-Byte waits until you’ve exceeded 2^n to use the next biggest unit.     <br /><font face="Courier New">PS&gt; convertto-fixedbyte 1000 -width 10       <br />&#160;&#160;&#160;&#160;&#160; 1 KB        <br />PS&gt; format-byte 1024        <br />&#160;&#160; 1024 B</font></li>
<li>Both cmdlets attempt to output a fixed width by rounding, but Format-Byte’s approach fails to handle some edge cases correctly:      <br /><font face="Courier New">PS&gt; convertto-fixedbyte (1000*999) -width 10       <br />&#160;&#160;&#160; 999 KB        <br />PS&gt; convertto-fixedbyte (1000*999+1) -width 10        <br />999.001 KB        <br /></font><font face="Courier New">PS&gt; convertto-fixedbyte (1000*999+499) -width 10       <br />999.499 KB        <br /></font><font face="Courier New">PS&gt; convertto-fixedbyte (1000*999+500) -width 10       <br />&#160;&#160;&#160;&#160;&#160; 1 MB        <br /></font><font face="Courier New">PS&gt; convertto-fixedbyte (1000*999+501) -width 10       <br />&#160;&#160;&#160;&#160;&#160; 1 MB        <br /></font><font face="Courier New">PS&gt; convertto-fixedbyte (1000*1000-1) -width 10       <br />&#160;&#160;&#160;&#160;&#160; 1 MB        <br /></font><font face="Courier New">PS&gt; convertto-fixedbyte (1000*1000) -width 10       <br />&#160;&#160;&#160;&#160;&#160; 1 MB        <br /></font><font face="Courier New">PS&gt; convertto-fixedbyte (1000*1000+1) -width 10       <br />&#160;&#160;&#160;&#160;&#160; 1 MB        <br /></font><font face="Courier New">PS&gt; format-byte (1024*1023)       <br />&#160;&#160; 1023 KB        <br />PS&gt; format-byte (1024*1023+1)        <br />1023.001 KB        <br />PS&gt; format-byte (1024*1023+511)        <br />1023.499 KB        <br />PS&gt; format-byte (1024*1023+512)        <br /> 1023.5 KB        <br />PS&gt; format-byte (1024*1023+513)        <br />1023.501 KB        <br />PS&gt; format-byte (1024*1024-1)        <br />1023.999 KB        <br />PS&gt; format-byte (1024*1024)        <br />&#160;&#160; 1024 KB        <br />PS&gt; format-byte (1024*1024+1)        <br />&#160;&#160;&#160;&#160;&#160; 1 MB</font></li>
<li>Both cmdlets omit trailing 0’s, instead padding the front with extra spaces.&#160; [thought there was a slight difference here, but now I can’t repro it!]</li>
<li>And of course: PSCX is open-source, while the Power Tools are not.&#160; So I can’t read the PSCX source and Keith can’t read mine.&#160; Even so, I hope some of the ideas can cross-pollinate :)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/02/25/more-on-convertto-fixedbyte-vs-powershell-community-extensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How does the TFS snap-in handle formatting?</title>
		<link>http://richardberg.net/blog/2009/02/25/how-does-the-tfs-snap-in-handle-formatting/</link>
		<comments>http://richardberg.net/blog/2009/02/25/how-does-the-tfs-snap-in-handle-formatting/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 01:31:42 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=46</guid>
		<description><![CDATA[Powershell formatting is pretty flexible, as long as you know how it works.&#160; So how do the version control cmdlets work?&#160; Open up %programfiles(x86)%\Microsoft Team Foundation Server 2008 Power Tools\PowerShell\Microsoft.TeamFoundation.PowerTools.PowerShell.format.ps1xml and have a look for yourself.&#160; Let’s consider the ubiquitous Item class for now: &#60;View&#62; &#60;Name&#62;Item&#60;/Name&#62; &#60;ViewSelectedBy&#62; &#60;TypeName&#62;Microsoft.TeamFoundation.VersionControl.Client.Item&#60;/TypeName&#62; &#60;/ViewSelectedBy&#62; &#60;TableControl&#62; &#60;TableHeaders&#62; &#60;TableColumnHeader&#62; &#60;Width&#62;7&#60;/Width&#62; &#60;Alignment&#62;Right&#60;/Alignment&#62; &#60;/TableColumnHeader&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>Powershell formatting is pretty flexible, as long as <a href="http://blogs.msdn.com/powershell/archive/2006/06/21/more-how-does-powershell-formatting-really-work.aspx">you know how it works</a>.&#160; So how do the version control cmdlets work?&#160; Open up <strong>%programfiles(x86)%\Microsoft Team Foundation Server 2008 Power Tools\PowerShell\Microsoft.TeamFoundation.PowerTools.PowerShell.format.ps1xml</strong> and have a look for yourself.&#160; Let’s consider the ubiquitous Item class for now:</p>
<p> <!-- code formatted by http://manoli.net/csharpformat/ -->
</p>
</p>
<p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:43f46727-777b-4b16-bb8a-88028d0b7507" class="wlWriterEditableSmartContent">
<pre style="background-color:White;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">&lt;</span><span style="color: #000000;">View</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Name</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Item</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Name</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ViewSelectedBy</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TypeName</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Microsoft.TeamFoundation.VersionControl.Client.Item</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TypeName</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">ViewSelectedBy</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableControl</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableHeaders</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableColumnHeader</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Width</span><span style="color: #000000;">&gt;</span><span style="color: #800080;">7</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Width</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Alignment</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Right</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Alignment</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableColumnHeader</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableColumnHeader</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Label</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">CheckinDate</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Label</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Width</span><span style="color: #000000;">&gt;</span><span style="color: #800080;">10</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Width</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Alignment</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Right</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Alignment</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableColumnHeader</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableColumnHeader</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Label</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">ContentLength</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Label</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Width</span><span style="color: #000000;">&gt;</span><span style="color: #800080;">7</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Width</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Alignment</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Right</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Alignment</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableColumnHeader</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableColumnHeader</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Label</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">ServerItem</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Label</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Alignment</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Left</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">Alignment</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableColumnHeader</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableHeaders</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableRowEntries</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableRowEntry</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableColumnItems</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableColumnItem</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">PropertyName</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">ChangesetId</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">PropertyName</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableColumnItem</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableColumnItem</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ScriptBlock</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">$_.CheckinDate.ToString(</span><span style="color: #800000;">'</span><span style="color: #800000;">d</span><span style="color: #800000;">'</span><span style="color: #000000;">)</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">ScriptBlock</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableColumnItem</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableColumnItem</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ScriptBlock</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
              </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> ($_.ItemType </span><span style="color: #000000;">-</span><span style="color: #000000;">eq [Microsoft.TeamFoundation.VersionControl.Client.ItemType]::Folder)
              { </span><span style="color: #800000;">'</span><span style="color: #800000;">&amp;lt;DIR&amp;gt;</span><span style="color: #800000;">'</span><span style="color: #000000;"> }
              </span><span style="color: #0000FF;">else</span><span style="color: #000000;">
              { ConvertTo</span><span style="color: #000000;">-</span><span style="color: #000000;">FixedByte $_.ContentLength </span><span style="color: #800080;">7</span><span style="color: #000000;"> }
            </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">ScriptBlock</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableColumnItem</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TableColumnItem</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ScriptBlock</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
              ConvertTo</span><span style="color: #000000;">-</span><span style="color: #000000;">FixedPath $_.ServerItem </span><span style="color: #800080;">7</span><span style="color: #000000;">,</span><span style="color: #800080;">10</span><span style="color: #000000;">,</span><span style="color: #800080;">6</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">ScriptBlock</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableColumnItem</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableColumnItems</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableRowEntry</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableRowEntries</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TableControl</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">View</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>And a few examples of what it looks like, taken from an 80- and a 112-character-wide console: </p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:8d8a7402-0dbc-4775-b1e9-084356bb8873" class="wlWriterEditableSmartContent">
<pre style="background-color:White;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">PS</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> tfdir 

Changes CheckinDat Content ServerItem
   etId          e  Length
</span><span style="color: #000000;">-------</span><span style="color: #000000;"> </span><span style="color: #000000;">----------</span><span style="color: #000000;"> </span><span style="color: #000000;">-------</span><span style="color: #000000;"> </span><span style="color: #000000;">----------</span><span style="color: #000000;">
   </span><span style="color: #800080;">8224</span><span style="color: #000000;">  </span><span style="color: #800080;">2</span><span style="color: #000000;">/</span><span style="color: #800080;">25</span><span style="color: #000000;">/</span><span style="color: #800080;">2009</span><span style="color: #000000;">   </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">DIR</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> $</span><span style="color: #000000;">/</span><span style="color: #000000;">Test</span><span style="color: #000000;">-</span><span style="color: #000000;">ConchangoV2</span><span style="color: #000000;">/</span><span style="color: #000000;">super</span><span style="color: #000000;">/</span><span style="color: #000000;">u...g</span><span style="color: #000000;">/</span><span style="color: #000000;">directorynamefromhell
   </span><span style="color: #800080;">8224</span><span style="color: #000000;">  </span><span style="color: #800080;">2</span><span style="color: #000000;">/</span><span style="color: #800080;">25</span><span style="color: #000000;">/</span><span style="color: #800080;">2009</span><span style="color: #000000;">   </span><span style="color: #800080;">11</span><span style="color: #000000;"> KB $</span><span style="color: #000000;">/</span><span style="color: #000000;">Test</span><span style="color: #000000;">-</span><span style="color: #000000;">ConchangoV2</span><span style="color: #000000;">/</span><span style="color: #000000;">super</span><span style="color: #000000;">/</span><span style="color: #000000;">u...efromhell</span><span style="color: #000000;">/</span><span style="color: #000000;">devilsurf.jpg
   </span><span style="color: #800080;">8224</span><span style="color: #000000;">  </span><span style="color: #800080;">2</span><span style="color: #000000;">/</span><span style="color: #800080;">25</span><span style="color: #000000;">/</span><span style="color: #800080;">2009</span><span style="color: #000000;">   </span><span style="color: #800080;">12</span><span style="color: #000000;"> B  $</span><span style="color: #000000;">/</span><span style="color: #000000;">Test</span><span style="color: #000000;">-</span><span style="color: #000000;">ConchangoV2</span><span style="color: #000000;">/</span><span style="color: #000000;">super</span><span style="color: #000000;">/</span><span style="color: #000000;">u...orynamefromhell</span><span style="color: #000000;">/</span><span style="color: #000000;">foo.txt
   </span><span style="color: #800080;">8224</span><span style="color: #000000;">  </span><span style="color: #800080;">2</span><span style="color: #000000;">/</span><span style="color: #800080;">25</span><span style="color: #000000;">/</span><span style="color: #800080;">2009</span><span style="color: #000000;">    </span><span style="color: #800080;">5</span><span style="color: #000000;"> MB $</span><span style="color: #000000;">/</span><span style="color: #000000;">Test</span><span style="color: #000000;">-</span><span style="color: #000000;">ConchangoV2</span><span style="color: #000000;">/</span><span style="color: #000000;">super</span><span style="color: #000000;">/</span><span style="color: #000000;">u...</span><span style="color: #000000;">/</span><span style="color: #000000;">PowerGUI.</span><span style="color: #800080;">1.6</span><span style="color: #000000;">.</span><span style="color: #800080;">1.639</span><span style="color: #000000;">.msi

PS</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> tfdir 

Changes CheckinDat Content ServerItem
   etId          e  Length
</span><span style="color: #000000;">-------</span><span style="color: #000000;"> </span><span style="color: #000000;">----------</span><span style="color: #000000;"> </span><span style="color: #000000;">-------</span><span style="color: #000000;"> </span><span style="color: #000000;">----------</span><span style="color: #000000;">
   </span><span style="color: #800080;">8224</span><span style="color: #000000;">  </span><span style="color: #800080;">2</span><span style="color: #000000;">/</span><span style="color: #800080;">25</span><span style="color: #000000;">/</span><span style="color: #800080;">2009</span><span style="color: #000000;">   </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">DIR</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> $</span><span style="color: #000000;">/</span><span style="color: #000000;">Test</span><span style="color: #000000;">-</span><span style="color: #000000;">ConchangoV2</span><span style="color: #000000;">/</span><span style="color: #000000;">super</span><span style="color: #000000;">/</span><span style="color: #000000;">ultra</span><span style="color: #000000;">/</span><span style="color: #000000;">very</span><span style="color: #000000;">/</span><span style="color: #000000;">very</span><span style="color: #000000;">/</span><span style="color: #000000;">mega</span><span style="color: #000000;">/</span><span style="color: #0000FF;">long</span><span style="color: #000000;">/</span><span style="color: #000000;">directorynamefromhell
   </span><span style="color: #800080;">8224</span><span style="color: #000000;">  </span><span style="color: #800080;">2</span><span style="color: #000000;">/</span><span style="color: #800080;">25</span><span style="color: #000000;">/</span><span style="color: #800080;">2009</span><span style="color: #000000;">   </span><span style="color: #800080;">11</span><span style="color: #000000;"> KB $</span><span style="color: #000000;">/</span><span style="color: #000000;">Test</span><span style="color: #000000;">-</span><span style="color: #000000;">ConchangoV2</span><span style="color: #000000;">/</span><span style="color: #000000;">super</span><span style="color: #000000;">/</span><span style="color: #000000;">ultra</span><span style="color: #000000;">/</span><span style="color: #000000;">very</span><span style="color: #000000;">/</span><span style="color: #000000;">very</span><span style="color: #000000;">/</span><span style="color: #000000;">m...ong</span><span style="color: #000000;">/</span><span style="color: #000000;">directorynamefromhell</span><span style="color: #000000;">/</span><span style="color: #000000;">devilsurf.jpg
   </span><span style="color: #800080;">8224</span><span style="color: #000000;">  </span><span style="color: #800080;">2</span><span style="color: #000000;">/</span><span style="color: #800080;">25</span><span style="color: #000000;">/</span><span style="color: #800080;">2009</span><span style="color: #000000;">   </span><span style="color: #800080;">12</span><span style="color: #000000;"> B  $</span><span style="color: #000000;">/</span><span style="color: #000000;">Test</span><span style="color: #000000;">-</span><span style="color: #000000;">ConchangoV2</span><span style="color: #000000;">/</span><span style="color: #000000;">super</span><span style="color: #000000;">/</span><span style="color: #000000;">ultra</span><span style="color: #000000;">/</span><span style="color: #000000;">very</span><span style="color: #000000;">/</span><span style="color: #000000;">very</span><span style="color: #000000;">/</span><span style="color: #000000;">mega</span><span style="color: #000000;">/</span><span style="color: #0000FF;">long</span><span style="color: #000000;">/</span><span style="color: #000000;">directorynamefromhell</span><span style="color: #000000;">/</span><span style="color: #000000;">foo.txt
   </span><span style="color: #800080;">8224</span><span style="color: #000000;">  </span><span style="color: #800080;">2</span><span style="color: #000000;">/</span><span style="color: #800080;">25</span><span style="color: #000000;">/</span><span style="color: #800080;">2009</span><span style="color: #000000;">    </span><span style="color: #800080;">5</span><span style="color: #000000;"> MB $</span><span style="color: #000000;">/</span><span style="color: #000000;">Test</span><span style="color: #000000;">-</span><span style="color: #000000;">ConchangoV2</span><span style="color: #000000;">/</span><span style="color: #000000;">super</span><span style="color: #000000;">/</span><span style="color: #000000;">ultra</span><span style="color: #000000;">/</span><span style="color: #000000;">very</span><span style="color: #000000;">/</span><span style="color: #000000;">very</span><span style="color: #000000;">/</span><span style="color: #000000;">m...torynamefromhell</span><span style="color: #000000;">/</span><span style="color: #000000;">PowerGUI.</span><span style="color: #800080;">1.6</span><span style="color: #000000;">.</span><span style="color: #800080;">1.639</span><span style="color: #000000;">.msi
</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>You can see that the Powershell team’s “expand toward the right to minimize visual variance” concept is used to great effect.&#160; However, we violated their “never provide a label” maxim in 3 out of 4 columns.&#160; Oops!&#160; Seriously though, I don’t think anyone would want to use a ScriptProperty with the exact parameters found in the formatter XML.&#160; What we provided instead is far more useful: a couple of fully generic cmdlets named <strong>ConvertTo-FixedByte</strong> and <strong>ConvertTo-FixedPath</strong>.&#160; I’ll cover the former in another post; there’s a fair amount of detail to dig into, but its use here is rather mundane.&#160; </p>
<p>ConvertTo-FixedPath is what really makes this example shine.&#160; If you’re like me, you <em>hate </em>managing long paths in shell environments.&#160; Wrapping onto multiple lines, truncating the front, and (especially) truncating the end of the path are all unacceptable.&#160; Cmdlets to the rescue!&#160; This one has two modes (“parameter sets” in PS-speak).&#160; The first is obvious enough:</p>
<p><font face="Courier New">PS&gt; convertto-fixedpath 12345678901234567890 -width 16<br />
    <br />12345678...67890</font></p>
<p>The 20-character input string is truncated to 16, but only by omitting things <em>in the middle</em>.&#160; (Note that this mode has an off-by-one bug.&#160; Hint: odd numbers.)&#160; This allows you to answer the important questions: what is the file name? what branch/workspace are they located in?&#160; Usually we don’t care as much about the intermediate directories.&#160; Maybe the same is true for other kinds of strings too – let me know if you find it useful!</p>
<p>The other mode is designed explicitly for use in a ps1xml formatter.&#160; Consider:</p>
<p><font face="Courier New">PS&gt; convertto-fixedpath 12345678901234567890 -otherwidths 30, 20, 10<br />
    <br />12345678...67890</font></p>
<p>Same output, but what the heck are the “other widths”?&#160; Imagine this string were going into a variable-length field.&#160; We want the string to expand dynamically, showing us as much of the filename as possible.&#160; Yet if it does need to be cropped, we want it done intelligently, as if we’d known the width in advance and passed it as a –width parameter.</p>
<p>As it turns out, we <em>can </em>know the final width, given a little hackery.&#160; The Powershell API lets you access the raw console host details, <a href="http://msdn.microsoft.com/en-us/library/system.management.automation.host.pshostrawuserinterface.buffersize(VS.85).aspx">including its BufferSize</a>.&#160; All you need to do is subtract the widths of the other columns, plus room for the separator character PS places between each column.&#160; So imagine the code above is used in a four-column formatter: 80 - 30 - 20 - 10 - (4*1) = 16.&#160; Sure enough, if you scroll back up to the XML, you’ll see the values passed to –otherwidths are no coincidence.&#160; We hand-tweaked every column width so it fit the data type as closely as possible without wrapping*, then plugged in those widths to the convertto-fixedpath cmdlet driving the final variable-length column.</p>
<p>This hack may not always work as Powershell migrates away from the ancient CSRSS hosting environment.&#160; But in theory, anyone who implements <a href="http://msdn.microsoft.com/en-us/library/system.management.automation.host.pshostrawuserinterface(VS.85).aspx">PSHostRawUserInterface</a> should be compatible.&#160; It works in the Powershell v2 ISE environment that ships with Win7, for instance.&#160; Custom-PS-tool-lovers, let me know how it goes. </p>
<p>*Except for column titles, obviously.&#160; They were a necessary casualty of two higher-priority design considerations (a) keeping labels identical to the underlying property name (b) supporting the default 80-character console width without squishing average-sized paths.</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/02/25/how-does-the-tfs-snap-in-handle-formatting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powershell: find SQL files orphaned from SSMS projects</title>
		<link>http://richardberg.net/blog/2009/02/23/powershell-find-sql-files-orphaned-from-ssms-projects/</link>
		<comments>http://richardberg.net/blog/2009/02/23/powershell-find-sql-files-orphaned-from-ssms-projects/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 17:43:40 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=45</guid>
		<description><![CDATA[We’re using SQL Management Studio to manage our database scripts.&#160; (Yes, VS “Data Dude” is under evaluation, but it has lots of quirks we haven’t had time to get a grasp on yet.)&#160; Since making DB development a collaborative, source-controlled process is new itself, we needed some extra checks &#38; balances.&#160; I remembered that James [...]]]></description>
			<content:encoded><![CDATA[<p>We’re using SQL Management Studio to manage our database scripts.&#160; (Yes, VS “Data Dude” is under evaluation, but it has lots of quirks we haven’t had time to get a grasp on yet.)&#160; Since making DB development a collaborative, source-controlled process is new itself, we needed some extra checks &amp; balances.&#160; I remembered that <a href="http://blogs.msdn.com/jmanning/archive/2008/07/20/powershell-script-find-orphaned-c-files.aspx">James had a script</a> for reconciling project files with what’s actually on disk.&#160; Although SSMS doesn’t use msbuild for its project structure, it was still fairly easy to adapt.</p>
<pre><span style="color: #0000ff">function</span><span style="color: #000000"> </span><span style="color: #5f9ea0">find-orphan</span><span style="color: #000000"> {
  </span><span style="color: #0000ff">param</span><span style="color: #000000">([</span><span style="color: #008080">string</span><span style="color: #000000">]</span><span style="color: #800080">$proj</span><span style="color: #000000"> </span><span style="color: #ff0000">=</span><span style="color: #000000"> $(</span><span style="color: #0000ff">throw</span><span style="color: #000000"> </span><span style="color: #800000">'</span><span style="color: #800000">ssmssqlproj file is required</span><span style="color: #800000">'</span><span style="color: #000000">))

  </span><span style="color: #800080">$proj</span><span style="color: #000000"> </span><span style="color: #ff0000">=</span><span style="color: #000000"> </span><span style="color: #5f9ea0; font-weight: bold">resolve-path</span><span style="color: #000000"> </span><span style="color: #800080">$proj</span><span style="color: #000000">
  </span><span style="color: #800080">$dir</span><span style="color: #000000"> </span><span style="color: #ff0000">=</span><span style="color: #000000"> </span><span style="color: #5f9ea0; font-weight: bold">split-path</span><span style="color: #000000"> </span><span style="color: #800080">$proj</span><span style="color: #000000">

  </span><span style="color: #800080">$xml</span><span style="color: #000000"> </span><span style="color: #ff0000">=</span><span style="color: #000000"> [</span><span style="color: #008080">xml</span><span style="color: #000000">](</span><span style="color: #5f9ea0; font-weight: bold">cat</span><span style="color: #000000"> </span><span style="color: #800080">$proj</span><span style="color: #000000">)
  </span><span style="color: #800080">$files_from_proj</span><span style="color: #000000"> </span><span style="color: #ff0000">=</span><span style="color: #000000"> (</span><span style="color: #800080">$xml</span><span style="color: #000000">.SqlWorkbenchSqlProject.Items.LogicalFolder |
    </span><span style="color: #0000ff">where</span><span style="color: #000000"> { </span><span style="color: #000080">$_</span><span style="color: #000000">.name </span><span style="color: #ff0000">-eq</span><span style="color: #000000"> </span><span style="color: #800000">&quot;</span><span style="color: #800000">Queries</span><span style="color: #800000">&quot;</span><span style="color: #000000"> }).items.filenode |
    </span><span style="color: #5f9ea0; font-weight: bold">foreach</span><span style="color: #000000"> { </span><span style="color: #5f9ea0; font-weight: bold">join-path</span><span style="color: #000000"> </span><span style="color: #800080">$dir</span><span style="color: #000000"> </span><span style="color: #000080">$_</span><span style="color: #000000">.name } |
    </span><span style="color: #5f9ea0; font-weight: bold">sort</span><span style="color: #000000">

  </span><span style="color: #800080">$files_from_dir</span><span style="color: #000000"> </span><span style="color: #ff0000">=</span><span style="color: #000000"> </span><span style="color: #5f9ea0; font-weight: bold">ls</span><span style="color: #000000"> </span><span style="color: #800080">$dir</span><span style="color: #000000"> -r </span><span style="font-style: italic; color: #5f9ea0">-filter</span><span style="color: #000000"> *.sql |
    </span><span style="color: #5f9ea0; font-weight: bold">foreach</span><span style="color: #000000"> { </span><span style="color: #000080">$_</span><span style="color: #000000">.fullname } |
    </span><span style="color: #5f9ea0; font-weight: bold">sort</span><span style="color: #000000">

  compare </span><span style="color: #800080">$files_from_proj</span><span style="color: #000000"> </span><span style="color: #800080">$files_from_dir</span><span style="color: #000000">
}
</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/02/23/powershell-find-sql-files-orphaned-from-ssms-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to enforce a rule on Area/Iteration Path</title>
		<link>http://richardberg.net/blog/2009/02/17/how-to-enforce-a-rule-on-areaiteration-path/</link>
		<comments>http://richardberg.net/blog/2009/02/17/how-to-enforce-a-rule-on-areaiteration-path/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 16:59:46 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Work Item Tracking]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=39</guid>
		<description><![CDATA[Another pitfall I encountered while setting up our new team project was how to make sure people didn’t cop out and leave them at the default (root, aka useless) value.  With Areas I may have been able to set up some weird non-inheriting permission scheme, but I needed to solve this problem for Iterations anyway, [...]]]></description>
			<content:encoded><![CDATA[<p>Another pitfall I encountered while setting up our new team project was how to make sure people didn’t cop out and leave them at the default (root, aka useless) value.  With Areas I may have been able to set up some weird non-inheriting permission scheme, but I needed to solve this problem for Iterations anyway, so I turned to the web. </p>
<p>Unfortunately, the <a href="http://blogs.msdn.com/teams_wit_tools/archive/2008/01/30/faq-2-how-do-i-enforce-a-rule-on-area-path-or-iteration-path.aspx">standard answer from the product team</a> didn’t work for me. </p>
<div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:44a893be-96ad-4c62-96b9-d3f7de71b4f2" class="wlWriterEditableSmartContent" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px">
<pre style="background-color:White;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">&lt;</span><span style="color: #000000;">FIELD type</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Integer</span><span style="color: #800000;">"</span><span style="color: #000000;"> name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">AreaID</span><span style="color: #800000;">"</span><span style="color: #000000;"> refname</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">System.AreaId</span><span style="color: #800000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">HELPTEXT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">AreaID</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">HELPTEXT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">FIELD</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">FIELD type</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Integer</span><span style="color: #800000;">"</span><span style="color: #000000;"> name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">IterationID</span><span style="color: #800000;">"</span><span style="color: #000000;"> refname</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">System.IterationId</span><span style="color: #800000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">HELPTEXT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">IterationID</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">HELPTEXT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">FIELD</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">FIELD type</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">String</span><span style="color: #800000;">"</span><span style="color: #000000;"> name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Product Area - Validation</span><span style="color: #800000;">"</span><span style="color: #000000;"> refname</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Coatue.ProductAreaValidation</span><span style="color: #800000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">HELPTEXT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Hidden field used to validate Product Area</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">HELPTEXT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">WHEN field</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">System.AreaId</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">84</span><span style="color: #800000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">COPY from</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">value</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Restricted</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">WHEN</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">PROHIBITEDVALUES</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">LISTITEM value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Restricted</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">PROHIBITEDVALUES</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">FIELD</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">FIELD type</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">String</span><span style="color: #800000;">"</span><span style="color: #000000;"> name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Sprint or Release - Validation</span><span style="color: #800000;">"</span><span style="color: #000000;"> refname</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Coatue.SprintPathValidation</span><span style="color: #800000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">HELPTEXT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Hidden field used to validate Sprint or Release</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">HELPTEXT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">WHEN field</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">System.IterationId</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">84</span><span style="color: #800000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">COPY from</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">value</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Restricted</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">WHEN</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">PROHIBITEDVALUES</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">LISTITEM value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Restricted</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">PROHIBITEDVALUES</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">FIELD</span><span style="color: #000000;">&gt;</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>It successfully blocked work items that had Area/Iteration paths I didn’t want, but I’d continue to get validation errors after I changed the paths in the form to something else.</p>
<p>At this point I started to wonder whether the AreaId and AreaPath fields were as intricately tied as I thought they were.  After all, I didn’t have any rules saying to update one when the other changed.  (<a href="http://msdn.microsoft.com/en-us/library/ms194971.aspx">The documentation</a> kinda implies this but doesn’t spell out the mechanism.)  So I decided to test at the object model level: <a href="http://richardberg.net/blog/?p=38">Get-TfsServer OM wrapper</a> to the rescue!</p>
<p><span style="FONT-FAMILY: Courier New">PS C:\Users\rberg&gt; $tfs = get-tfsserver njtfs –all<br />
</span><span style="FONT-FAMILY: Courier New">PS C:\Users\rberg&gt; $bug = $tfs.wit.GetWorkItem(1333)<br />
</span><span style="FONT-FAMILY: Courier New">PS C:\Users\rberg&gt; $bug.AreaId; $bug.IterationId<br />
84<br />
</span><span style="FONT-FAMILY: Courier New">84 </span> </p>
<p> </p>
<p><span style="FONT-FAMILY: Courier New">PS C:\workspaces\ws1&gt; $bug.AreaPath; $bug.IterationPath<br />
Test-ConchangoV2\test<br />
</span><span style="FONT-FAMILY: Courier New">Test-ConchangoV2\Release 1\Sprint 4</p>
<p></span><span style="FONT-FAMILY: Courier New">PS C:\Users\rberg&gt; $bug.fields | where { $_.name.contains("Validation") } | select value<br />
Value<br />
-----<br />
</span><span style="FONT-FAMILY: Courier New">Restricted Restricted                                                                                                                      </span> </p>
<p><span style="FONT-FAMILY: Courier New">PS C:\Users\rberg&gt; $bug.AreaId = 104; $bug.IterationId = 91<br />
</span><span style="FONT-FAMILY: Courier New">PS C:\workspaces\ws1&gt; $bug.AreaPath; $bug.IterationPath<br />
Test-ConchangoV2\test<br />
</span><span style="FONT-FAMILY: Courier New">Test-ConchangoV2\Release 1\Sprint 4</span> </p>
<p><span style="FONT-FAMILY: Courier New">PS C:\Users\rberg&gt; $bug.fields | where { $_.name.contains("Validation") } | select value<br />
</span><span style="FONT-FAMILY: Courier New">Value<br />
-----<br />
</span><span style="FONT-FAMILY: Courier New">Restricted<br />
Restricted</span></p>
<p>Nope, not a synchronization issue between path on the form &lt;–&gt; underlying ID.  Looks like I really do need to tweak Gregg’s advice.  All you need is a corresponding WHENNOT rule to cancel out each WHEN rule as it’s no longer needed.  Here’s what the hidden validator for Area looks like now:</p>
<div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:d8046de1-8093-4b80-9d4e-3fd32f093d17" class="wlWriterEditableSmartContent" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px">
<pre style="background-color:White;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">&lt;</span><span style="color: #000000;">FIELD type</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">String</span><span style="color: #800000;">"</span><span style="color: #000000;"> name</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Product Area - Validation</span><span style="color: #800000;">"</span><span style="color: #000000;"> refname</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Coatue.ProductAreaValidation</span><span style="color: #800000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">HELPTEXT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Hidden field used to validate Product Area</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">HELPTEXT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">WHEN field</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">System.AreaId</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">84</span><span style="color: #800000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">COPY from</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">value</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Restricted</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">WHEN</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">WHENNOT field</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">System.AreaId</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">84</span><span style="color: #800000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">COPY from</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">value</span><span style="color: #800000;">"</span><span style="color: #000000;"> value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Ok</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">WHENNOT</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">PROHIBITEDVALUES</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">LISTITEM value</span><span style="color: #000000;">=</span><span style="color: #800000;">"</span><span style="color: #800000;">Restricted</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">PROHIBITEDVALUES</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">FIELD</span><span style="color: #000000;">&gt;</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></p>
<p>Make the same change for Iteration and you’re golden.</p></div>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/02/17/how-to-enforce-a-rule-on-areaiteration-path/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What does Get-TfsServer –All do, exactly?</title>
		<link>http://richardberg.net/blog/2009/02/17/what-does-get-tfsserver-all-do-exactly/</link>
		<comments>http://richardberg.net/blog/2009/02/17/what-does-get-tfsserver-all-do-exactly/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 16:59:32 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=38</guid>
		<description><![CDATA[PS C:\workspaces\ws1&#62; help tfserver –full SYNTAX     Get-TfsServer [-Name] &#60;String&#62; [-Credential &#60;PSCredential&#62;] [-All] [&#60;Common     Parameters&#62;]        Get-TfsServer -Path &#60;String&#62; [-Credential &#60;PSCredential&#62;] [-All] [&#60;CommonPa     rameters&#62;] ...   -All     Get Team Foundation Server object with the extended properties   Required?                    false     Position?                    named     Default value     Accept pipeline input?       false     Accept wildcard [...]]]></description>
			<content:encoded><![CDATA[<p><span style="FONT-FAMILY: Courier New">PS C:\workspaces\ws1&gt; help tfserver –full</p>
<p><span style="font-family: Courier New;">SYNTAX<br />
    Get-TfsServer [-Name] &lt;String&gt; [-Credential &lt;PSCredential&gt;] [-All] [&lt;Common<br />
    Parameters&gt;] </span></span>  </p>
<p><span style="FONT-FAMILY: Courier New">    Get-TfsServer -Path &lt;String&gt; [-Credential &lt;PSCredential&gt;] [-All] [&lt;CommonPa<br />
    rameters&gt;]</p>
<p><span style="font-family: Courier New;">...</p>
<p></span></span>  <span style="FONT-FAMILY: Courier New">-All<br />
    Get Team Foundation Server object with the extended properties</p>
<p></span><span style="FONT-FAMILY: Courier New">  Required?                    false<br />
    Position?                    named<br />
    Default value<br />
    Accept pipeline input?       false<br />
    Accept wildcard characters?  false</p>
<p><span style="font-family: Courier New;">...</span></span> </p>
<p>Not the greatest help text ever written, I know.  Oh well, there’s a lot more room on this blog anyway :)</p>
<p>First the basics: Get-TfsServer and Get-TfsWorkspace (aliases: tfserver, tfworkspace) are intended to be “official” versions of James Manning’s <a href="http://blogs.msdn.com/jmanning/archive/2006/09/28/776141.aspx">get-tfs.ps1</a> and <a href="http://blogs.msdn.com/jmanning/archive/2006/09/30/777938.aspx">get-workspace.ps1</a> cmdlets.  To incorporate them into the main snap-in, Hyung ported them to C# and standardized the parameters.  Both will now accept either –Path or –Name (but not both).  For tfserver, –Name is the default [position = 1] and all others are named, while the reverse is true for tfworkspace, reflecting what we felt was the most common use of each.  Bottom line, these will all work:</p>
<p><span style="FONT-FAMILY: Courier New">&gt; $tfs = get-tfsserver njtfs<br />
&gt; $tfs = get-tfsserver –path .<br />
&gt; $ws = get-tfsworkspace .<br />
&gt; $ws = get-tfsworkspace –name njtfs<br />
&gt; $ws = get-tfsworkspace –servername .</span></p>
<p>There are also new parameters like –Credential on tfserver, and –Computer and –Owner on tfworkspace, which behave more or less how you’d expect.  In short, you can use tfserver to interface TFS with Powershell’s built-in credential management features, as well as tfworkspace to query for the Workspace object that represents remote workspaces you may not even own.</p>
<p>So back to the original topic.  The –All switch turns on the special script-friendly behavior that James pioneered and <a href="http://blogs.msdn.com/richardb/archive/2007/02/21/add-types-ps1-poor-man-s-using-for-powershell.aspx">I later extended</a>.</p>
<p><a href="http://richardberg.net/blog/wp-content/uploads/2009/02/addtypeextensions.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="AddTypeExtensions" src="http://richardberg.net/blog/wp-content/uploads/2009/02/addtypeextensions-thumb.png" border="0" alt="AddTypeExtensions" width="674" height="426" /></a></p>
<p>As you can see there are a few differences between the final shipping behavior and the various get-tfs.ps1 scripts floating on the web:</p>
<ul>
<li>Once you choose –All, every TFS assembly is loaded immediately, rather than on-demand as you use the ScriptProperties.  The idea here is to “fail early” rather than introduce a ticking bomb into downstream scripts that may depend on these objects.</li>
<li>The types that we import as NoteProperties are prefixed with the same shorthand as the ScriptProperties, plus an underscore.  Even though we continue to weed out types that aren’t useful (anything private, an exception, or an event) there are still a ton to sort thru; this tweak helps segregate the huge list into “namespaces” that are still marginally navigable with Tab completion.</li>
<li>C# is a much uglier language to do this work than Powershell!</li>
</ul>
<p>All in all, you can now do cool things like:</p>
<p><span style="FONT-FAMILY: Courier New">PS C:\workspaces\ws1&gt; $tfs = get-tfsserver njtfs -all<br />
<span style="font-family: Courier New;">PS C:\workspaces\ws1&gt; $tfs.vcs.GetChangeset(1234) </span></span> </p>
<p><span style="FONT-FAMILY: Courier New">Changes Owner                  CreationDa Comment<br />
   etId                                te<br />
------- -----                  ---------- -------<br />
   1234 COATUECAP\LDeGrazia    10/27/2007</span></p>
<p><span style="FONT-FAMILY: Courier New">PS C:\workspaces\ws1&gt; new-object $tfs.VCS_ChangesetVersionSpec 1234 </span></p>
<p><span style="FONT-FAMILY: Courier New">                            ChangesetId DisplayString<br />
                            ----------- -------------<br />
                                   1234 C1234</span></p>
<p><span style="FONT-FAMILY: verd">So why not have this option switched on permanently?  The vanilla <strong>TeamFoundationServer</strong> object isn’t very useful on its own; the entire point of James’ original wrapper was to quickly access the <strong>VersionControlServer </strong>and similar objects.  Well first of all, it’s noticeably slower – on my machine, testing a “cold” Powershell console, the cmdlet takes 3 seconds with the default parameters and 6 seconds with –All.  We’re loading more assemblies than ever, not to mention deep reflection on each one (in order to test an upcast and a string comparison, not exactly speedy operations in themselves).  More importantly, the extra properties add enormous clutter to the objects when not needed.  And I think you’ll be more likely to use those TFS objects in vanilla form in your future scripts.  For example, most of the version control cmdlets in the Fall 2008 suite take a TeamFoundationServer as either pipeline input or a named parameter.  I’m sure whatever Microsoft is cooking up for the next batch will include even more interactivity and flow between cmdlets.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/02/17/what-does-get-tfsserver-all-do-exactly/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to prevent people from opening new bugs</title>
		<link>http://richardberg.net/blog/2009/02/17/how-to-prevent-people-from-opening-new-bugs/</link>
		<comments>http://richardberg.net/blog/2009/02/17/how-to-prevent-people-from-opening-new-bugs/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 15:12:29 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Work Item Tracking]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=35</guid>
		<description><![CDATA[We’re in the middle of transitioning to a new team project.&#160; On the source control side, Microsoft has made a huge investment to support arbitrary renames throughout the tree.&#160; No reason to mess with TFS-&#62;TFS migration when I can move the native items!&#160; On the other hand, migrating work items across team projects is notoriously [...]]]></description>
			<content:encoded><![CDATA[<p>We’re in the middle of transitioning to a new team project.&#160; On the source control side, Microsoft has made a huge investment to support arbitrary renames throughout the tree.&#160; No reason to mess with <a href="http://www.codeplex.com/tfstotfsmigration">TFS-&gt;TFS migration</a> when I can move the native items!&#160; On the other hand, migrating work items across team projects is notoriously tricky.&#160; I decided it would be easiest to steadily phase out the work items remaining in the old project while forcing people to open new issues in the new project.</p>
<p>Being relatively new to WIT customization, the answer wasn’t immediately obvious.&#160; TFS doesn’t let you stick an ALLOWEDVALUES rule on fields like <strong>System.CreatedDate</strong> that the system populates on creation.&#160; And anything you stick on a user-editable field will inevitably block users from navigating an existing work item through the rest of its legitimate workflow.&#160; The path I took was modifying the initial transition from “”.&#160; XML excerpt:</p>
<p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:91642765-bf45-46ed-90d9-05f9f2fe557a" class="wlWriterEditableSmartContent">
<pre style="background-color:White;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">TRANSITION from</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;&quot;</span><span style="color: #000000;"> to</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Active</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">REASONS</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">REASON value</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Build Failure</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">DEFAULTREASON value</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">New</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">REASONS</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">FIELDS</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">FIELD refname</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.VSTS.Common.ActivatedBy</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
              </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">COPY from</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">currentuser</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
              </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">VALIDUSER </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
              </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">REQUIRED </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">FIELD</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">FIELD refname</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Microsoft.VSTS.Common.ActivatedDate</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
              </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">SERVERDEFAULT from</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">clock</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">FIELD</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">FIELD refname</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">System.AssignedTo</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
              </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">DEFAULT from</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">currentuser</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">FIELD</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">FIELD refname</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">System.Title</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
              </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ALLOWEDVALUES</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
                </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">LISTITEM value</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Before 2009-02-12</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
              </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">ALLOWEDVALUES</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">FIELD</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">FIELDS</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">TRANSITION</span><span style="color: #000000;">&gt;</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
</p>
<p>Most of this comes from the stock MSF Agile v4.2 template; the <strong>System.Title</strong> field with the strange rule toward the end is my addition.&#160; Doesn’t really matter what you put in the value, so long as you don’t tell your users what it is :)</p>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/02/17/how-to-prevent-people-from-opening-new-bugs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unlocking other people’s files. Yes, again.</title>
		<link>http://richardberg.net/blog/2009/02/14/unlocking-other-peoples-files-yes-again/</link>
		<comments>http://richardberg.net/blog/2009/02/14/unlocking-other-peoples-files-yes-again/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 05:51:33 +0000</pubDate>
		<dc:creator>RichardB</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://richardberg.net/blog/?p=16</guid>
		<description><![CDATA[You’re going about your business, trying to refactor some code, when suddenly things come to a crashing halt.  “The item foo.cs is locked for check-out by DOMAIN\user in workspace ws1.”  Since Microsoft shipped the first public betas of TFS in 2005, there have probably been more blog posts on this pitfall than any other -- [...]]]></description>
			<content:encoded><![CDATA[<p>You’re going about your business, trying to refactor some code, when suddenly things come to a crashing halt.  “The item foo.cs is locked for check-out by DOMAIN\user in workspace ws1.”  Since Microsoft shipped the first public betas of TFS in 2005, there have probably been more blog posts on this pitfall than any other -- I’ll pick on <a href="http://blogs.msdn.com/jmanning/archive/2006/01/26/518175.aspx">James</a> for an example.  The frustration also spawned Status Sidekick (now part of <a href="http://www.attrice.info/cm/tfs/index.htm">TFS Sidekicks</a>), the first 3rd-party TFS tool to my knowledge. </p>
<p>The arrival of the <a href="http://blogs.msdn.com/bharry/archive/2008/10/01/preview-of-the-next-tfs-power-tools-release.aspx">Fall 2008 Powertools</a> hinted at yet another possibility based on Powershell.  Script-friendly unlocking is particularly enticing for scenarios like the one I found myself in last week: transitioning a team from exclusive checkouts to an edit-merge-commit workflow.  Turning off the exclusive settings on the Team Project is the obvious first step, but what to do about the hundreds of existing pending changes?  I can’t ask everyone to suddenly checkin their work (which may be far from ready to share, or even build), but I also can’t reorganize the tree unless every lock is removed.  Thus:</p>
<div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:7f2b063a-6582-4bc3-822b-3b7b4900218b" class="wlWriterEditableSmartContent" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px">
<pre style="background-color:White;;overflow: auto;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">del temp.hat </span><span style="color: #800080;">2</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> $</span><span style="color: #0000FF;">null</span><span style="color: #000000;">
</span><span style="color: #0000FF;">foreach</span><span style="color: #000000;"> ($pendingSet </span><span style="color: #0000FF;">in</span><span style="color: #000000;"> </span><span style="color: #0000FF;">get</span><span style="color: #000000;">-</span><span style="color: #000000;">tfspendingchange </span><span style="color: #000000;">-</span><span style="color: #000000;">user </span><span style="color: #000000;">*</span><span style="color: #000000;">)
{
    $workspace </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">'</span><span style="color: #800000;">"</span><span style="color: #800000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> $pendingSet.Name </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">'</span><span style="color: #800000;">";</span><span style="color: #800000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> $pendingSet.OwnerName
    $pendingSet.PendingChanges </span><span style="color: #000000;">|</span><span style="color: #000000;"> </span><span style="color: #0000FF;">where</span><span style="color: #000000;"> {$_.IsLock} </span><span style="color: #000000;">|</span><span style="color: #000000;"> </span><span style="color: #0000FF;">foreach</span><span style="color: #000000;"> {
      $item </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">'</span><span style="color: #800000;">"</span><span style="color: #800000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> $_.ServerItem </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">'</span><span style="color: #800000;">"</span><span style="color: #800000;">'</span><span style="color: #000000;">
      </span><span style="color: #800000;">"</span><span style="color: #800000;">lock /lock:none /workspace:$workspace $item</span><span style="color: #800000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">|</span><span style="color: #000000;"> </span><span style="color: #0000FF;">out</span><span style="color: #000000;">-</span><span style="color: #000000;">file temp.hat </span><span style="color: #000000;">-</span><span style="color: #000000;">append
    }
}
tf </span><span style="color: #800000;">"</span><span style="color: #800000;">@temp.hat</span><span style="color: #800000;">"</span><span style="color: #000000;">
del temp.hat
</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>This isn’t the cleanest solution in the world.  You couldn’t just wire up the “find all locks in the system” example I provided for Brian’s post to a Remove-TfsLock cmdlet -- even if the Power Tools provided one (which they don’t yet).  By convention, <a href="http://richardberg.net/blog/?p=30">a pipeline of TFS cmdlets transmits QualifiedItems</a><em></em>, but to unlock an arbitrary item we need two additional pieces of information from the <em>PendingSet</em> object.  So we fall back on good old procedural loops around <a href="http://blogs.msdn.com/phkelley/archive/2008/11/12/everything-you-ever-wanted-to-know-about-locks.aspx">tf lock</a>.</p>
<p>Could we improve the script?  Sure.  We could batch ~12 items at a time* for a better performance, though the gain is not nearly as big as using a @hatfile in the first place.  We could also be a little more robust.  Get-TfsPendingChange returns a full PendingSet in the general case, but <a href="http://richardberg.net/blog/?p=19">sometimes the return type decays to a simple PendingChange[]</a>.  If our query returns exactly 1 workspace, then our logic for populating $workspace won’t work. </p>
<p>Of course, we could also do a lot worse!  I originally tried to add the wrapper quotes in-place, but quickly got into syntax trouble.  After consulting <a href="http://blogs.msdn.com/powershell/archive/2006/07/15/Variable-expansion-in-strings-and-herestrings.aspx">the relevant Powershell blog post</a> I <em>eventually</em> got it right, but it was an unreadable mess.  For example, line 4 read:</p>
<p><span style="font-family: Courier New;">$workspace = "`"$($pendingSet.Name)`";$($pendingSet.OwnerName)"</span></p>
<p>Yuck.</p>
<p>*<a href="http://social.msdn.microsoft.com/Forums/en-US/tfsversioncontrol/thread/f4c283ef-8b94-4103-ac09-3e1d819906e2/">3200 character limit</a> on each line of a tf.exe script file; TFS paths are 260 chars max</p>
<ul></ul>
]]></content:encoded>
			<wfw:commentRss>http://richardberg.net/blog/2009/02/14/unlocking-other-peoples-files-yes-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

