Over the last few articles I've been sharing some shortcuts to get most recently used or edited files. For today's Friday Fun I thought I'd share something that I use in my PowerShell ISE profile. Whenever I start the ISE, I automatically open the last file I was working on. Instead of launching the ISE and then finding the most recent file in list under File, this happens automatically.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
I found some information on this topic at PowerShell.com and revised it to meet my needs. The most recently used files are stored in an XML configuration file, which is good because I can use PowerShell to parse out the information I need. Unfortunately, the path to this file is pretty unwieldy:
$env:LocalAppData\microsoft_corporation\powershell_ise.exe_StrongName_lw2v2vm3wmtzzpebq33gybmeoxukb04w\3.0.0.0
Which translates to something like this:
C:\Users\Jeff\AppData\Local\microsoft_corporation\powershell_ise.exe_StrongName_lw2v2vm3wmtzzpebq33gybmeoxukb04w\3.0.0.0
The XML file is called user.config. With that, let's get some PowerShell in here to get the XML.
$path = "C:\Users\Jeff\AppData\Local\microsoft_corporation\powershell_ise.exe_StrongName_lw2v2vm3wmtzzpebq33gybmeoxukb04w\3.0.0.0"
$configpath = Join-path -path $path -ChildPath user.config
[xml]$config = Get-Content $configpath
The recent used list is stored under user settings.
The value should have what I need.
Looks like it is an array of strings.
Getting closer. It seems the last step I need is that string property.
This should be the same list as I see under File. But while this works, it assumes that the setting I want will always be at position 5 and that I know how to get there in the first place. The smarter way is to use an XPATH filter to find the data. I can use the SelectNodes() method.
$config.SelectNodes('//setting[@name="MRU"]')
The query essentially says find any node that is a <setting> and that has a name attribute of "MRU". XML is case-sensitive so I have to match what is in the XML file.
With this it is just as easy to get the most recent file.
$n = $config.SelectNodes('//setting[@name="MRU"]')
$n.value.ArrayOfString.string | select -first 1
Once I know the file name it is trivial to load it into the ISE.
psedit $n.value.ArrayOfString.string[0]
The other way I could have selected the node is with Select-XML.
Select-Xml -Xml $config -XPath '//setting[@name="MRU"]'
The node property has the setting I need. I can simply keep drilling until I get the value I want.
(Select-Xml -Xml $config -XPath '//setting[@name="MRU"]').node.Value.ArrayOfString.String[0]
In this case I'm only selecting the first item. I could have used these code snippets in my profile, but I decided to create a function to retrieve the MRU list.
Function Get-ISEMRU { [cmdletbinding()] Param() <# Path will be something like: C:\Users\Jeff\AppData\Local\microsoft_corporation\powershell_ise.exe_StrongName_lw2v2vm3wmtzzpebq33gybmeoxukb04w #> $ISEPath = "$env:localappdata\microsoft_corporation\powershell_ise*\3.0.0.0" Try { $folder = (Resolve-Path -Path $ISEPath -ErrorAction Stop).Path } Catch { Write-Warning "Failed to get ISE folder from $ISEPath" Write-Warning $_.exception.message #Bail out Return } If ($folder) { #construct the path to user.config $path = Join-Path -Path $folder -ChildPath "user.config" #verify the file exists just in case if (Test-Path -path $path) { #using -Raw sends everything at once as a huge string #and boosts performance a bit. [xml]$xml = Get-Content -Path $path -Raw #get the MRU setting as a string using an XPath filter $xml.SelectNodes('//setting[@name="MRU"]').Value.ArrayOfString.string } else { Write-Warning "Can't find $path" } } #if $folder } #end Get-ISEMRU
The function encapsulates everything I've shown you. Although I set a default path using a wildcard.
$ISEPath = "$env:localappdata\microsoft_corporation\powershell_ise*\3.0.0.0"
I did this to keep things easier to read and on the off chance that the strong name value might change at some point. By the way I am running this on PowerShell 4.0. I have not tested with v5.
To get the full path, I can resolve this path with a wildcard.
$folder = (Resolve-Path -Path $ISEPath -ErrorAction Stop).Path
Most everthing else is the same. This function is in my PowerShell ISE profile script and at the end I open the most recent file.
#open the most recently edited file
psedit (Get-ISEMRU)[0]
It's that easy. And because the function is in my profile, I can run it anytime. Although note that the XML file won't get updated until you close the ISE. Personally, all these little things add up over the course of a day and make my work a bit more fun. Enjoy.