Archive

Archive for September, 2013

WLW Post Fails With Error “The underlying connection was closed: An unexpected error occurred on a receive.”

September 27th, 2013 1 comment

When trying to upload my last blog post from Windows Live Writer (WLW) to WordPress (WP) I received the following error:

————————————————————————-

Network Connection Error

Error attempting to connect to blog at:

http://blog.danskingdom.com/xmlrpc.php

The underlying connection was closed. An unexpected error occurred on a receive.

————————————————————————-

WLWNetworkConnectionError

 

I had no problem uploading to my blog a couple weeks earlier and hadn’t done any updates or changed anything, so I thought this was strange.  After waiting a day, thinking maybe GoDaddy (my WP host) was having issues, I was still getting the error.  After Googling I found many others reporting this error with varying degrees of success fixing it.  So after trying some suggestions that worked for others (change WLW blog URL from http to https, edit the WP xmlrpc.php file, delete and recreate blog account in WLW, reboot, etc.) I was still getting this same error.

So I decided to try posting a new “test” post, and low and behold it worked.  So it appeared the problem was something with the content of my article.  So I started removing chunks of content from the article and trying to post.  Eventually I found that the problem was being caused by the string “In that post” in the first paragraph of the post.  I thought that maybe some weird hidden characters maybe got in there somehow, but after reviewing the article’s Source I could see that it was just plain old text.  I deleted the sentence and retyped it, but it still didn’t work.  If I just removed “In that post” from the sentence then everything worked fine; very strange  After more playing around, I found that if I just added a comma to the end and made it “In that post,”, that also fixed the problem.  So that’s how I’ve left it.

I don’t know what is special about the string “In that post”;  I created another test article with that string in it and was able to post it without any problems.  Just a weird one-off WLW-WP problem I guess.

 

Moral of the story

If you run into this same error, before you go muddling with config files and recreating your blog account, just try posting a quick “test” article.  If it works, then the problem is somewhere in your article’s content, so start stripping pieces away until you are able to get it to post successfully and narrow down the culprit.  Also, if you don’t want to publish a half-baked article while you are tracking down the problem, you can do a Save Post Draft To Blog instead of a full Publish to see if you are still getting the error

Happy coding!

 

— Update —

I’ve ran into this problem again when trying to post this article.  3 different spots in the article were causing the problem.  Here is the source of the article with what broke it, and what worked:

1. This broke:

<li>Click Yes when prompted to < strong > Run With UI Access < / strong > . </li>

(I had to add spaces around all of the 3 characters <, >, and / in the strong tags to get it to post here)

This worked:

<li>Click Yes when prompted to Run With UI Access.</li>

 

2. This broke:

<p>Today I stumbled across <a href="http://www.autohotkey.com/board/topic/70449-enable-interaction-with-administrative-programs/">this post on the AHK community forums < / a > .&#160;

(I had to add spaces around the each character of the closing </a> tag to get it to post here)

This worked:

<p>Today I stumbled across <a href="http://www.autohotkey.com/board/topic/70449-enable-interaction-with-administrative-programs/">this post</a> on the AHK community forums.&#160;

 

3. This broke:

the <a href="http://www.autohotkey.com/docs/commands/RunAs.htm">RunAs command < / a > .</p>

(Again, I had to add spaces around each character in the closing </a> tag to get it to post here)

This worked:

the <a href="http://www.autohotkey.com/docs/commands/RunAs.htm">RunAs</a> command.</p>

 

I can reproduce this issue every time on that article, and also on this one (which is why I had to change the problem code slightly so I could get it to post here).  So unlike my first encounter with this problem, these ones all seem to be problems parsing html markup tags; specifically the </> characters.  I’m not sure if this is a problem with Windows Live Writer or WordPress, but it is definitely a frustrating bug.  I’m running Windows 8 x64 and the latest versions of WLW and WP.

If you have any thoughts please comment below.

Launch Visual Studio Checkin Window With A Keystroke

September 27th, 2013 No comments

A few weeks ago I blogged about how you can get custom TFS checkin policies to work when committing from the command line. In that post, I had a quick aside about how you can launch the checkin window (i.e. pending changes) with a quick keystroke using AutoHotkey.  I realize that many people don’t use AutoHotkey (although you really should; it can save you a lot of time), so I thought I would show how you can accomplish this task without AutoHotkey.  It’s quite simple really, and it allows you to launch the VS Checkin window from anywhere, even if you don’t have Visual Studio open.

 

Steps To Launch VS Checkin Window From The Visual Studio Command Prompt

  1. Open the Visual Studio Command Prompt.  To do this, just hit the windows key and type Developer Command Prompt For VS2012 if using VS 2012, or Visual Studio Command Prompt (2010) if using VS 2010.
  2. In the VS Command Prompt, change to a directory that is in your TFS workspace mapping. e.g. cd C:\Dev\TFS
  3. Type tf checkin and hit enter.

    Steps To Launch VS Checkin Window With A Shortcut Key

    1. Right click on your desktop and choose New –> Shortcut to create a new shortcut file.
      CreateShortcutOnDesktop
    2. Have the shortcut point to the TF executable. This can be found at "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\TF.exe".
      PathToTfExeForShortcut

    3. Enter the name for your shortcut file, such as VS Checkin.
      NameShortcut

    4. Now that the shortcut has been created on your desktop, right-click on it and go the the properties (or use alt+enter). You will want to:
    • add checkin to the very end of the Target,
    • change the Start In directory to a directory you have mapped in your TFS workspace,
    • and assign it a Shortcut Key. 
      CheckinShortcutPropertiesToChange

     

    Results

    That’s it.  Go ahead and try your shortcut key.  I’ll wait.  You should see something like this:

    VsCheckinWindow

    Notice that it pops both a command prompt window and the actual checkin window.  If you don’t have any pending changes, then the command prompt window will simply open and close.

     

    More Information and Caveats

    Old Style Checkin Window

    You probably noticed in the screenshot above that even though I’m using Visual Studio 2012, it still pops the old VS 2010 style of checkin window.  I actually prefer this popped out window to the VS 2012 pending changes pane, and I know a lot of people agree.

     

    Getting The Shortcut Off Your Desktop

    Above I had you create the shortcut on your desktop, but you might not want to have it clutter up your desktop. Unfortunately if you move it to some other folder you will find that the shortcut key no longer works.  For some reason I have found that for the shortcut key to work the shortcut file must either be on your desktop, or in the Start Menu. If you are using Windows 7 you can simply drag and drop the shortcut into the Programs section of the Start Menu.  For us Windows 8.0 folks the Start Menu is gone, so just manually move the shortcut to “C:\ProgramData\Microsoft\Windows\Start Menu\Programs”.

    You may find that after moving the shortcut file the shortcut key no longer works. You just have to go back into the Shortcut file properties, assign it a new Shortcut Key, hit Apply, and then assign the original Shortcut Key back.

     

    Shelving Changes In TFS Using The Old Style Shelve Window

    If you are using TFS and want to shelve your changes instead of checking them in, you can access the old Shelve Pending Changes window in the same way.  In step 4 above, instead of adding checkin as the TF.exe argument, add shelve.  To launch it from the Visual Studio Command Prompt, type tf shelve instead of tf checkin.

     

    Getting Custom TFS Checkin Policies To Work

    As you may have guessed from the very start of the article, custom TFS checkin policies don’t run in this checkin window by default; they will throw errors.  Fortunately for you I have already created a registry file that you can run after each checkin policy update that you do which will rectify this problem.

     

    I hope this helps you be more productive.  Happy coding!

    Have Your NuGet Package Install Itself As A Development Dependency

    September 18th, 2013 3 comments

    The Problem

    I recently blogged about a NuGet package I made that allows you to easily turn your own projects into a NuGet package, making it easy to share your work with the world.  One problem I ran into with this was that if somebody used my NuGet package to create their package, their NuGet package listed my NuGet package as a dependency.  This meant that when they distributed their package to others, it would install both their package and mine.  Obviously this is undesirable, since their library has no dependency on my package; my package was meant purely to help them with the development process.

    Unfortunately there wasn’t much I could do about this; that is, until the release of NuGet 2.7 which came out a few weeks ago.  You can see from the release notes that they added a new developmentDependency attribute that can be used.  This made things a bit better because it allowed users who installed my package to go into their project’s packages.config file, find the element corresponding to my package, and add the developmentDependency=”true” attribute to it.

    So this was better, but still kinda sucked because it required users to do this step manually, and most of them likely aren’t even aware of the problem or that there was a fix for it.  When users (and myself) install a package they want it to just work; which is why I created a fix for this.

     

    The Fix

    Update – As of NuGet 2.8 there is a built-in way to do the fix below. See this post for more info.

    The nice thing about NuGet packages is that you can define PowerShell scripts that can run when users install and uninstall your packages, as is documented near the bottom of this page.  I’ve created a PowerShell script that will automatically go in and adjust the project’s packages.config file to mark your package as a development dependency.  This means there is no extra work for the user to do.

    The first thing you need to do (if you haven’t already) is include an Install.ps1 script in your NuGet package’s .nuspec file.  If you don’t currently use a .nuspec file, check out this page for more information.  I also include a sample .nuspec file at the end of this post for reference.  The line to add to your .nuspec file will look something like this:

    <file src=”NuGetFiles\Install.ps1″ target=”tools\Install.ps1″ />

    and then the contents of Install.ps1 should look like this:

    param($installPath, $toolsPath, $package, $project)
    
    # Edits the project's packages.config file to make sure the reference to the given package uses the developmentDependency="true" attribute.
    function Set-PackageToBeDevelopmentDependency($PackageId, $ProjectDirectoryPath)
    {
        function Get-XmlNamespaceManager($XmlDocument, [string]$NamespaceURI = "")
        {
            # If a Namespace URI was not given, use the Xml document's default namespace.
    	    if ([string]::IsNullOrEmpty($NamespaceURI)) { $NamespaceURI = $XmlDocument.DocumentElement.NamespaceURI }	
    
    	    # In order for SelectSingleNode() to actually work, we need to use the fully qualified node path along with an Xml Namespace Manager, so set them up.
    	    [System.Xml.XmlNamespaceManager]$xmlNsManager = New-Object System.Xml.XmlNamespaceManager($XmlDocument.NameTable)
    	    $xmlNsManager.AddNamespace("ns", $NamespaceURI)
            return ,$xmlNsManager		# Need to put the comma before the variable name so that PowerShell doesn't convert it into an Object[].
        }
    
        function Get-FullyQualifiedXmlNodePath([string]$NodePath, [string]$NodeSeparatorCharacter = '.')
        {
            return "/ns:$($NodePath.Replace($($NodeSeparatorCharacter), '/ns:'))"
        }
    
        function Get-XmlNodes($XmlDocument, [string]$NodePath, [string]$NamespaceURI = "", [string]$NodeSeparatorCharacter = '.')
        {
    	    $xmlNsManager = Get-XmlNamespaceManager -XmlDocument $XmlDocument -NamespaceURI $NamespaceURI
    	    [string]$fullyQualifiedNodePath = Get-FullyQualifiedXmlNodePath -NodePath $NodePath -NodeSeparatorCharacter $NodeSeparatorCharacter
    
    	    # Try and get the nodes, then return them. Returns $null if no nodes were found.
    	    $nodes = $XmlDocument.SelectNodes($fullyQualifiedNodePath, $xmlNsManager)
    	    return $nodes
        }
    
        # Get the path to the project's packages.config file.
        Write-Debug "Project directory is '$ProjectDirectoryPath'."
        $packagesConfigFilePath = Join-Path $ProjectDirectoryPath "packages.config"
    
        # If we found the packages.config file, try and update it.
        if (Test-Path -Path $packagesConfigFilePath)
        {
            Write-Debug "Found packages.config file at '$packagesConfigFilePath'."
    
            # Load the packages.config xml document and grab all of the <package> elements.
            $xmlFile = New-Object System.Xml.XmlDocument
            $xmlFile.Load($packagesConfigFilePath)
            $packageElements = Get-XmlNodes -XmlDocument $xmlFile -NodePath "packages.package"
    
            Write-Debug "Packages.config contents before modification are:`n$($xmlFile.InnerXml)"
    
            if (!($packageElements))
            {
                Write-Debug "Could not find any <package> elements in the packages.config xml file '$packagesConfigFilePath'."
                return
            }
    
            # Add the developmentDependency attribute to the NuGet package's entry.
            $packageElements | Where-Object { $_.id -eq $PackageId } | ForEach-Object { $_.SetAttribute("developmentDependency", "true") }
    
            # Save the packages.config file back now that we've changed it.
            $xmlFile.Save($packagesConfigFilePath)
        }
        # Else we coudn't find the packages.config file for some reason, so error out.
        else
        {
            Write-Debug "Could not find packages.config file at '$packagesConfigFilePath'."
        }
    }
    
    # Set this NuGet Package to be installed as a Development Dependency.
    Set-PackageToBeDevelopmentDependency -PackageId $package.Id -ProjectDirectoryPath ([System.IO.Directory]::GetParent($project.FullName))
    

    And that’s it.  Basically this script will be ran after your package is installed, and it will parse the project’s packages.config xml file looking for the element with your package’s ID, and then it will add the developmentDependency=”true” attribute to that element.  And of course, if you want to add more code to the end of the file to do additional work, go ahead.

    So now your users won’t have to manually edit their packages.config file, and your user’s users won’t have additional, unnecessary dependencies installed.

     

    More Info

    As promised, here is a sample .nuspec file for those of you that are not familiar with them and what they should look like.  This is actually the .nuspec file I use for my package mentioned at the start of this post.  You can see that I include the Install.ps1 file near the bottom of the file.

    <?xml version="1.0" encoding="utf-8"?>
    <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
      <metadata>
        <id>CreateNewNuGetPackageFromProjectAfterEachBuild</id>
        <version>1.4.2</version>
        <title>Create New NuGet Package From Project After Each Build</title>
        <authors>Daniel Schroeder,iQmetrix</authors>
        <owners>Daniel Schroeder,iQmetrix</owners>
        <licenseUrl>https://newnugetpackage.codeplex.com/license</licenseUrl>
        <projectUrl>https://newnugetpackage.codeplex.com/wikipage?title=NuGet%20Package%20To%20Create%20A%20NuGet%20Package%20From%20Your%20Project%20After%20Every%20Build</projectUrl>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>Automatically creates a NuGet package from your project each time it builds. The NuGet package is placed in the project's output directory.
    	If you want to use a .nuspec file, place it in the same directory as the project's project file (e.g. .csproj, .vbproj, .fsproj).
    	This adds a PostBuildScripts folder to your project to house the PowerShell script that is called from the project's Post-Build event to create the NuGet package.
    	If it does not seem to be working, check the Output window for any errors that may have occurred.</description>
        <summary>Automatically creates a NuGet package from your project each time it builds.</summary>
        <releaseNotes>Updated to use latest version of New-NuGetPackage.ps1.</releaseNotes>
        <copyright>Daniel Schroeder 2013</copyright>
        <tags>Auto Automatic Automatically Build Pack Create New NuGet Package From Project After Each Build On PowerShell Power Shell .nupkg new nuget package NewNuGetPackage New-NuGetPackage</tags>
      </metadata>
      <files>
        <file src="..\New-NuGetPackage.ps1" target="content\PostBuildScripts\New-NuGetPackage.ps1" />
        <file src="Content\NuGet.exe" target="content\PostBuildScripts\NuGet.exe" />
        <file src="Content\BuildNewPackage-RanAutomatically.ps1" target="content\PostBuildScripts\BuildNewPackage-RanAutomatically.ps1" />
        <file src="Content\UploadPackage-RunManually.ps1" target="content\PostBuildScripts\UploadPackage-RunManually.ps1" />
        <file src="Content\UploadPackage-RunManually.bat" target="content\PostBuildScripts\UploadPackage-RunManually.bat" />
        <file src="tools\Install.ps1" target="tools\Install.ps1" />
        <file src="tools\Uninstall.ps1" target="tools\Uninstall.ps1" />
      </files>
    </package>
    

     

    Happy coding!

    PowerShell Needs A Centralized Package Management Solution

    September 9th, 2013 4 comments

    TL;DR – PowerShell needs centralized package management.  Please go up-vote this request to have it added to PowerShell.


    I love PowerShell, and I love writing reusable PowerShell modules.  They work great when I am writing scripts for myself.  The problem comes in when I write a script that depends on some modules, and I then want to share that script with others.  I basically have 2 options:

    1. Track down all of the module files that the script depends on, zip them all up, and send them to the recipient along with instructions such as, “Navigate to this folder on your PC, create a new folder with this name, copy file X to this location, rinse, repeat…”.
    2. Track down all of the module files that the script depends on and copy-paste their contents directly into the top of the script file, so I just send the user one very large file.

    Neither of these solutions are ideal.  Maybe I’m missing something?  In my opinion, PowerShell really needs centralized package management; something similar to Ruby Gems would be great.  Basically a website where users can upload their scripts with a unique ID, and then in their PowerShell script at the top of the file just list the modules that the script depends on.  If the modules are not installed on that PC yet, then they would automatically be downloaded and installed.  This would make PowerShell so much more convenient, and I believe it would help drive more users to write reusable modules and avoid duplicating modules that have already been written (likely better) by others.

    In order for this to work though, it has to be baked directly into the PowerShell architecture by the PowerShell team; it’s not something that a 3rd party could do.  So to try and bring this feature request to Microsoft’s attention, I have create a Suggestion on the MS Connect site.  Please go up-vote it.

    Before thinking to create a feature request for this (duh), I spammed some of my favourite PowerShell Twitter accounts (@JamesBru @ShayLevy @dfinke @PowerShellMag @StevenMurawski @JeffHicks @ScriptingGuys) to bring it to their attention and get their thoughts; sorry about that guys!  This blog’s comments are a better forum than Twitter for discussing these types of things.

    If you have thoughts on centralized package management for PowerShell, or have a better solution for dealing with distributing scripts that depend on modules, please leave a comment below. Thanks.

    Happy coding!

    [Update]

    While PowerShell does not provide a native module management solution, Joel “Jaykul” Bennett has written one and all of the modules are hosted at http://poshcode.org/, although I believe it can download modules from other sources as well (e.g. GitHub or any other URL).  One place that it cannot download files from is CodePlex since CodePlex does not provide direct download links to the latest versions of files or to their download links (it is done through Javascript).  Please go up-vote this issue and this issue to try and get this restriction removed.

    Getting Custom TFS Checkin Policies To Work When Committing From The Command Line (i.e. tf checkin)

    September 6th, 2013 1 comment

    Update – I show how to have your checkin policies automatically update the registry keys shown in this blog post on this newer blog post. If you are not the person creating the checkin policies though, then you will still need to use the technique shown in this post.

    I frequently check code into TFS from the command line, instead of from Visual Studio (VS), for a number of reasons:

    1. I prefer the VS 2010 style of checkin window over the VS 2012 one, and the 2010 style window is still displayed when checking in from the command line.
    2. I use AutoHotkey to pop the checkin window via a keyboard shortcut, so I don’t need to have VS open to check files in (or navigate to the pending changes window within VS).
      – Aside: Just add this one line to your AutoHotkey script for this functionality. This sets the hotkey to Ctrl+Windows+C to pop the checkin window, but feel free to change it to something else.
      ^#C UP::Run, tf checkin
      
    3. Other programs, such as Git-Tf and the Windows Explorer shell extension, call the TFS checkin window via the command line, so you don’t have the option to use the VS checkin pending changes window.

            The Problem

          The problem is that if you are using a VSIX package to deploy your custom checkin policies, the custom checkin policies will only work when checking code in via the VS GUI, and not when doing it via the command line.  If you try and do it via the command line, the checkin window spits an “Internal error” for each custom checkin policy that you have, so your policies don’t run and you have to override them.

          InternalErrorInCheckinPolicies
          P. Kelly mentions this problem on his blog post, and has some other great information around custom checkin policies in TFS.
          The old TFS 2010 Power Tools had a feature for automatically distributing the checkin policies to your team, but unfortunately this feature was removed from the TFS 2012 Power Tools.  Instead, the Microsoft recommended way to distribute your custom checkin policies is now through a VSIX package, which is nice because it can use the Extension And Updates functionality built into VS and automatically notify users of updates (without requiring users to install the TFS Power Tools).  The problem is that VSIX packages are sandboxed and are not able to update the necessary registry key to make custom checkin policies work from the command line.  I originally posted this question on the MSDN forums, then I logged a bug about this on the Connect site, but MS closed it as “By Design” Sad smile. Maybe if it gets enough up-votes though they will re-open it (so please go up-vote it).

         

        The Workaround

        The good news though is that there is a work around.  You simply need to copy your custom checkin policy entry from the key:

        "HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0_Config\TeamFoundation\SourceControl\Checkin Policies"

        to:

        "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\11.0\TeamFoundation\SourceControl\Checkin Policies" (omit the Wow6432Node on 32-bit Windows).

         

        Not Perfect, but Better

        The bad news is that every developer (who uses the command line checkin window) will need to copy this registry value on their local machine.  Furthermore, they will need to do it every time they update their checkin policies to a new version.

        While this sucks, I’ve made it a bit better by creating a little powershell script to automate this task for you; here it is:

        # This script copies the required registry value so that the checkin policies will work when doing a TFS checkin from the command line.
        
        # Turn on Strict Mode to help catch syntax-related errors.
        # 	This must come after a script's/function's param section.
        # 	Forces a function to be the first non-comment code to appear in a PowerShell Module.
        Set-StrictMode -Version Latest
        
        $ScriptBlock = {
            # The name of the Custom Checkin Policy Entry in the Registry Key.
            $CustomCheckinPolicyEntryName = 'YourCustomCheckinPolicyEntryNameGoesHere'
        
            # Get the Registry Key Entry that holds the path to the Custom Checkin Policy Assembly.
            $CustomCheckinPolicyRegistryEntry = Get-ItemProperty -Path 'HKCU:\Software\Microsoft\VisualStudio\11.0_Config\TeamFoundation\SourceControl\Checkin Policies' -Name $CustomCheckinPolicyEntryName
            $CustomCheckinPolicyEntryValue = $CustomCheckinPolicyRegistryEntry.($CustomCheckinPolicyEntryName)
        
            # Create a new Registry Key Entry for the iQ Checkin Policy Assembly so they will work from the command line (as well as from Visual Studio).
            if ([Environment]::Is64BitOperatingSystem)
            { $HKLMKey = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\11.0\TeamFoundation\SourceControl\Checkin Policies' }
            else
            { $HKLMKey = 'HKLM:\SOFTWARE\Microsoft\VisualStudio\11.0\TeamFoundation\SourceControl\Checkin Policies' }
            Set-ItemProperty -Path $HKLMKey -Name $CustomCheckinPolicyEntryName -Value $CustomCheckinPolicyEntryValue
        }
        
        # Run the script block as admin so it has permissions to modify the registry.
        Start-Process -FilePath PowerShell -Verb RunAs -ArgumentList "-Command $ScriptBlock"
        

        Note that you will need to update the script to change YourCustomCheckinPolicyEntryNameGoesHere to your specific entry’s name.  Also, the “[Environment]::Is64BitOperatingSystem” check requires PowerShell V3; if you have lower than PS V3 there are other ways to check if it is a 64-bit machine or not.

        If you have developers that aren’t familiar with how to run a PowerShell script, then you can include the following batch script (.cmd/.bat file extension) in the same directory as the PowerShell script, and they can run this instead by simply double-clicking it to call the PowerShell script:

        SET ThisScriptsDirectory=%~dp0
        SET PowerShellScriptPath=%ThisScriptsDirectory%UpdateCheckinPolicyInRegistry.ps1
        
        :: Run the powershell script to copy the registry key into other areas of the registry so that the custom checkin policies will work when checking in from the command line.
        PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%PowerShellScriptPath%'"
        

        Note that this batch script assumes you named the PowerShell script “UpdateCheckinPolicyInRegistry.ps1”, so if you use a different file name be sure to update it here too.

        Your developers will still need to run this script every time after they update their checkin policies, but it’s easier and less error prone than manually editing the registry.  If they want to take it a step further they could even setup a Scheduled Task to run the script once a day or something, or even implement it as a Group Policy so it automatically happens for everyone, depending on how often your company updates their checkin policies and how many developers you have.

        Ideally I would like to simply be able to run this script during/after the VSIX installer.  I have posted a question on Stack Overflow to see if this is possible, but from everything I’ve read so far it doesn’t look like it; maybe in the next generation of VSIX though.  If you have any other ideas on how to automate this, I would love to hear them.

        Happy coding!

        Accessing PowerShell Properties and Variables with Periods (and other special characters) in their Name

        September 5th, 2013 No comments

        TL;DR

        If your PowerShell variable name contains special characters, wrap it in curly braces to get/set its value.  If your PowerShell property name contains special characters, wrap it in double quotes:

        # Variable name with special characters
        $VariableName.That.Contains.Periods			# This will NOT work.
        ${VariableName.That.Contains.Periods}		# This will work.
        
        $env:ProgramFiles(x86)			# This will NOT work, because parentheses are special characters.
        ${env:ProgramFiles(x86)}		# This will work.
        
        # Property name with special characters
        $SomeObject.APropertyName.That.ContainsPeriods		# This will NOT work.
        $SomeObject.{APropertyName.That.ContainsPeriods}	# This will work.
        $SomeObject.'APropertyName.That.ContainsPeriods'	# This will also work.
        $SomeObject."APropertyName.That.ContainsPeriods"	# This will work too.
        
        # Property name with special characters stored in a variable
        $APropertyNameWithSpecialCharacters = 'APropertyName.That.ContainsPeriods'
        $SomeObject.$APropertyNameWithSpecialCharacters		# This will NOT work.
        $SomeObject.{$APropertyNameWithSpecialCharacters}	# This will NOT work.
        $SomeObject.($APropertynameWithSpecialCharacters)	# This will work.
        $SomeObject."$APropertynameWithSpecialCharacters"	# This will also work.
        $SomeObject.'$APropertynameWithSpecialCharacters'	# This will NOT work.
        

         

        More Information

        I was recently working on a powershell script to get the values of some entries in the registry.  This is simple enough:

        Get-ItemProperty -Path 'HKCU:\Software\Microsoft\VisualStudio\11.0_Config\TeamFoundation\SourceControl\Checkin Policies' -Name 'TF.iQmetrix.CheckinPolicies'
        

        If we run this command, this is what we get back:

        TF.iQmetrix.CheckinPolicies : C:\Users\Dan Schroeder\AppData\Local\Microsoft\VisualStudio\11.0\Extensions\mwlu1noz.4t5\TF.iQmetrix.CheckinPolicies.dll
        PSPath                      : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0_Config\TeamFoundation\SourceControl\Checkin Policies
        PSParentPath                : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0_Config\TeamFoundation\SourceControl
        PSChildName                 : Checkin Policies
        PSDrive                     : HKCU
        PSProvider                  : Microsoft.PowerShell.Core\Registry
        

        So the actual value I’m after is stored in the “TF.iQmetrix.CheckinPolicies” property of the object returned by Get-ItemProperty; notice that this property name has periods in it.  So let’s store this object in a variable to make it easier to access it’s properties, and do a quick Get-Member on it just to show some more details:

        $RegistryEntry = Get-ItemProperty -Path 'HKCU:\Software\Microsoft\VisualStudio\11.0_Config\TeamFoundation\SourceControl\Checkin Policies' -Name 'TF.iQmetrix.CheckinPolicies'
        $RegistryEntry | Get-Member
        

        And this is what Get-Member shows us:

           TypeName: System.Management.Automation.PSCustomObject
        
        Name                        MemberType   Definition                                                                                                                                                          
        ----                        ----------   ----------                                                                                                                                                          
        Equals                      Method       bool Equals(System.Object obj)                                                                                                                                      
        GetHashCode                 Method       int GetHashCode()                                                                                                                                                   
        GetType                     Method       type GetType()                                                                                                                                                      
        ToString                    Method       string ToString()                                                                                                                                                   
        PSChildName                 NoteProperty System.String PSChildName=Checkin Policies                                                                                                                          
        PSDrive                     NoteProperty System.Management.Automation.PSDriveInfo PSDrive=HKCU                                                                                                               
        PSParentPath                NoteProperty System.String PSParentPath=Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0_Config\TeamFoundation\SourceControl           
        PSPath                      NoteProperty System.String PSPath=Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0_Config\TeamFoundation\SourceControl\Checkin Policies
        PSProvider                  NoteProperty System.Management.Automation.ProviderInfo PSProvider=Microsoft.PowerShell.Core\Registry                                                                             
        TF.iQmetrix.CheckinPolicies NoteProperty System.String TF.iQmetrix.CheckinPolicies=C:\Users\Dan Schroeder\AppData\Local\Microsoft\VisualStudio\11.0\Extensions\mwlu1noz.4t5\TF.iQmetrix.CheckinPolicies.dll 
        

         

        So in PowerShell ISE I type “$RegistryEntry.” and intellisense pops up showing me that TF.iQmetrix.CheckinPolicies is indeed a property on this object that I can access.

        PowerShell ISE Intellisense

        So I try and display the value of that property to the console using:

        $RegistryEntry = Get-ItemProperty -Path 'HKCU:\Software\Microsoft\VisualStudio\11.0_Config\TeamFoundation\SourceControl\Checkin Policies' -Name 'TF.iQmetrix.CheckinPolicies'
        $RegistryEntry.TF.iQmetrix.CheckinPolicies
        

        But nothing is displayed Sad smile

        While PowerShell ISE does color-code the line “$RegistryEntry.TF.iQmetrix.CheckinPolicies” to have the object color different than the property color, if you just look at it in plain text, something clearly looks off about it.  How does PowerShell know that the property name is “TF.iQmetrix.CheckinPolicies”, and not that “TF” is a property with an “iQmetrix” property on it, with a “CheckinPolicies” property on that.  Well, it doesn’t.

        I did some Googling and looked on StackOverflow, but couldn’t a solution to this problem.  I found slightly related posts involving environmental variables with periods in their name, but that solution did not work in this case.  So after some random trial-and-error I stumbled onto the solution.  You have to wrap the property name in curly braces:

        $RegistryEntry.TF.iQmetrix.CheckinPolicies		# This is WRONG. Nothing will be returned.
        $RegistryEntry.{TF.iQmetrix.CheckinPolicies}	# This is RIGHT. The property's value will returned.
        

         

        I later refactored my script to store the “TF.iQmetrix.CheckinPolicies” name in a variable and found that I couldn’t use the curly braces anymore.  After more trial-and-error I discovered that using parentheses instead works:

        $EntryName = 'TF.iQmetrix.CheckinPolicies'
        
        $RegistryEntry.$EntryName		# This is WRONG. Nothing will be returned.
        $RegistryEntry.{$EntryName}		# This is WRONG. Nothing will be returned.
        $RegistryEntry.($EntryName)		# This is RIGHT. The property's value will be returned.
        $RegistryEntry."$EntryName"		# This is RIGHT too. The property's value will be returned.
        

         

        So there you have it.  If for some reason you have a variable or property name that contains periods, wrap it in curly braces, or parenthesis if you are storing it in a variable.

        Hopefully this makes it’s way to the top of the Google search results so you don’t waste as much time on it as I did.

        Happy coding!