Custom PowerShell Objects and Performance Revisited

Way back in my earlier days of blogging (Sept 2010), I wrote an article (I recommend you check this one out for more information regarded some of the older styles of custom object creation) that talked about the performance differences between a few different ways that you can create a custom PowerShell object.

At that time we were rocking PowerShell V2 and enjoying all of the great benefits that were being brought to us. Fast forward to now and we are sitting at V4 and have a new way to create a custom PowerShell object in [pscustomobject]. What this brings us is a way to finally have the speed benefits of doing PSObject…

New-Object PSObject -Property @{
Name = 'Boe'
Number = 1
ID = 007
}

…with the ability of keeping everything in the order we specify like when we use the Select-Object method:

$Object = '' | Select-Object Name, Number, ID
$Object.Name = 'Boe'
$Object.Number = 1
$Object.ID = 007

Another method which was discussed was the use of Add-Member to create objects:

$Object = New-Object PSObject
$Object | Add-Member -MemberType NoteProperty -Name Name -Value Boe -PassThru |
Add-Member -MemberType NoteProperty -Name Number -Value 1 -PassThru |
Add-Member -MemberType NoteProperty -Name ID -Value 007 -PassThru

The New Stuff

I won’t really dive any deeper into these as you can view that old blog post to catch up on the rest of that stuff, but what I will do is show off [pscustomobject] as well as take all of these for a spin again and show off the performance differences between these 4 contenders.

[pscustomobject] is pretty simple to use:

[pscustomobject]@{
    Name= 'Boe'
    Number = 1
    ID = 007
}

The best part is that it keeps its order and is pretty quick as well. Just how quick is it? Well, sit back and check out the stats when compared to the other methods. If you have read the previous blog entry, you will see that Add-Member was by far the slowest method while Select-Object and New-Object PSObject were neck and neck in speed with PSObject pulling ahead slightly for the win.

After I initially published this article, I had some suggestions on other items to include in my testing. The are New-Object PSObject –Property ([ordered@{}) and $prop=[ordered]@{};[pscustomobject]$prop (labeled [pscustomobject][ordered]). Both of these output the same type of ordered object, meaning that the order that you supply the data in the hash table is the same order that it will display on the console.

Keep in mind that this produces the exact same output as if you would use [pscustomobject] by itself.

image

So how will these newcomers compare with everything else? Let’s find out!

The Approach

If you saw the previous blog where I talk about performance, you noticed that I had a script that helped to make the determination as to what was the fastest approach. Well, this script was not exactly the best written script and had a lot of manual things going on. I’ve updated my script to make it easier to add the number of cycles (basically the number of “systems” to run against), the number of properties to have in the custom object and finally the number of times to repeat each operation. The script is available to download from the link at the end of this article if you are interested in running it yourself.

The Results

I started out at running against 10 “systems” (cycles) while creating the following sets of objects (1,5,10,25,50,100) and repeated this 5 times. I then upped the cycles to the following values and ran against each one to record the time it took each type to complete: 50,100,500,1000,5000,10000. The first list of graphs will show you everything at its own scale, meaning that the highest time for each cycle will be the max on the graph. Because this doesn’t always tell the whole store, I also included a second set of graphs that show the highest value recorded during the entire time spent running the scans (the 10000 cycle scan had the highest time taken). At the beginning, you really won’t see much of anything but as the cycles go on, you can see which approach becomes slower and slower.

So with all of that out of the way, let me show the first set of graphs that show the results of my tests.

image

image

image

image

image

image

 

Both [pscustomobject] and the [pscustomobject][ordered] approach were the fastest ones in PowerShell and for the most part are interchangeable (assuming that you are running V3/4, of course). Add-Member is definitely the slowest approach, much like it was when I first ran this test. The rest of the bunch were back and forth as far as which ones were faster at any given moment in time.  As I said previously, these numbers are all scaled to their respected highest time. The graphs below will show the scale from the 10000 Cycle run which had the highest time returned.

image

image

image

 

image

image

image

This shows that in the same scale as 10000 cycles, the level of difference in performance doesn’t really come into play until you are running against 500 systems. Of course, various outside conditions such as network latency and system performance come into play as well, but you get the idea.

Much like the tests I ran back in 2010, Select-Object and New-Object PSObject are practically neck and neck and really come down to your preference of having your properties come out in the order that they were coded (Select-Object) or having a very slight and much better looking (from a coding style) approach (PSObject).

I hope you enjoyed this article and found the information useful when it comes time to make a decision what method you wish to take. My personal take is that if you are running V3/4, then you really should be using [pscustomobject] unless you have a need to add to an existing object or add some other levels of properties to an object in which Add-Member should be used at the cost of performance. While the [pscustomobject][ordered] was on par with [pscustomobject], they are the same thing and if you want to save an extra line of code, you should look at just using [pscustomobject]@{} by itself. But in the end, it is up to you to decide what you feel may be the right choice based on your requirements.

Download Script

Technet Script Repository

Posted in powershell | Tagged , , | 4 Comments

A PowerShell Module for Managing Internet Explorer Favorites

As promised, here is my module that I put together to make managing Internet Explorer favorites. The module is called IEFavorites and has 3 functions available:

  • Get-IEFavorite
  • Add-IEFavorite
  • Set-IEFavorite

There are also 4 aliases associated with this module:

  • gief (Get-IEFavorite)
  • aief (Add-IEFavorite)
  • sief (Set-IEFavorite)
  • rief (Remove-Item)

Simply import the module file and you are off and running!

Import-Module .\IEFavorites.psm1 -Verbose

image

Viewing the favorites can be done like this:

Get-IEFavorite

image

Adding a new Favorite is handled like so:

Add-IEFavorite -Name Twitter -Folder SocialNetwork `
-Url http://twitter.com -Verbose

image

If I want to remove a favorite, I just pipe my results of Get-IEFavorite into Remove-Item.

Get-IEFavorite -Name Drudge* -File | 
Remove-Item -Verbose

image

Lastly, editing a favorite is done using Set-IEFavorite:

Get-IEFavorite -Name Twitter* | 
Set-IEFavorite -NewName Facebook -NewUrl http://Facebook.com -Verbose

image

That is all to the module. Check it out and let me know what you think!

Download IEFavorites

http://gallery.technet.microsoft.com/scriptcenter/Internet-Explorer-f689cb89

Posted in Modules, powershell | Tagged , , , , | Leave a comment

Editing an Internet Explorer Favorite Using PowerShell

Closing out my little series on working with Internet Explorer favorites, I will show you how to edit an existing favorite using PowerShell.

We’ve already added a favorite, but what happens if I want to change the URL or the name of the favorite (or even both for that matter)? Well, we can use PowerShell with a little bit of parsing and make this happen in an easy amount of time.

I will be using the same technique as before to get the favorites path and then use that to locate a favorite which should be changed.

$IEFav =  [Environment]::GetFolderPath('Favorites')

I am going to update the CNN favorite to change it to Drudge Report instead. But before I do that, I need to get that CNN favorite. This is a dramatic edit as I might as well delete CNN and just add the Drudge Report favorite, but this will show both editing the URL as well as the Name in one shot.

$Favorite = Get-ChildItem $IEFav -Recurse -Filter "*CNN*"

I also need to figure out what my new name and url will be.

$NewUrl = 'http://drudgereport.com'
$Newname = 'DrudgeReport'

Now I need to get the contents of the current favorite.

$lines = Get-Content $Favorite.FullName
$lines

image

Depending on the favorite (such as this one), there may be a lot of noise here that work through.  As long as you follow the steps below, the favorite will be modified and when used will take you to the new site specified.

I am now going to step through each line and if it starts with BASEURL=, URL= or IconFile=, I will replace the current URL with the new one.

$i=0
ForEach ($line in $lines) {
    If ($line.StartsWith("BASEURL")) {
        $lines[$i] = "BASEURL=$NewUrl"
    }
    If ($line.StartsWith("URL")) {
        $lines[$i] = "URL=$NewUrl"
    }            
    If ($line.StartsWith("IconFile")) {
        $lines[$i] = "IconFile=$NewUrl/favicon.ico"
    }            
    $i++  
}
Set-Content -Value $lines -Path $Favorite.FullName

Now that we have accomplished updating the URL on this favorite, it is time to rename the favorite so it matches the new URL.

Rename-Item -Path $Favorite.FullName -NewName "$NewName.url"

Perfect! The favorite has now been renamed and a matching URL was given to it. We can verify and test the favorite by doing the following:

Get-ChildItem $IEFav -Filter 'Drudge*' -Recurse | Invoke-Item

The next article will cover a module that I wrote to make managing your Internet Explorer favorites a little easier. Check it out!

Posted in powershell | Tagged , , | 3 Comments

Creating and Removing an Internet Explorer Favorite Using PowerShell

In a previous article, I showed you how you can view the Internet Explorer favorites as well as the URL for those favorites. Continuing on from that article, I will now walk through creating a new favorite for Internet Explorer using PowerShell.

Using the same approach as before, I need to get the folder path to the Favorites.

$IEFav =  [Environment]::GetFolderPath('Favorites','None') 

Because I am creating an Internet Shortcut, I need to create a COM object that will be used later on.

$Shell = New-Object -ComObject WScript.Shell

I am going to create a favorite of my site and place it in my already existing PowerShell folder. Because I am not using the root of Favorites, I need to add the PowerShell folder to my current $IEFav path.

$IEFav = Join-Path -Path $IEFav -ChildPath PowerShell

I need to figure out a name for the favorite, something that I want to show up when I click on the Favorites toolbar on Internet Explorer.

$Name = 'My Blog'

Next up is to build the fully qualified path to the favorite. I have to make sure that I add a .url so it is properly recognized as a favorite.

$FullPath = Join-Path -Path $IEFav -ChildPath "$($Name).url"

image

Now I just need the URL.

$url = 'http://learn-powershell.net'

Ok, while we have the file ready for creation, we still need to add the URL which will be referenced when clicked on. This is where our Shell.Application COM object comes into play.

$shortcut = $Shell.CreateShortcut($FullPath)
$shortcut.TargetPath = $Url
$shortcut.Save()

And just like that, the new Internet Explorer favorite has been created! We can quickly verify using the same techniques from the previous article and see the information is there.

image

I can even use Invoke-Item on this to bring up my site.

Invoke-Item $FullPath

Removing a favorite is very simply. Just use Get-ChildItem to get the file and use Remove-Item to delete it.

Get-ChildItem $IEFav -Recurse -Filter Bing* | 
Remove-Item -Verbose

image

That’s all there is to creating a favorite. Up next will be showing you how to edit an existing favorite. Stay tuned!

Posted in powershell | Tagged , , | Leave a comment

Viewing Internet Explorer Favorites Using PowerShell

I wanted a quick way to look at all of my favorites and see what urls they are referencing. Of course, PowerShell comes to the rescue and I found a fairly easy way to accomplish this without having to dirty my hands with a COM object (using Shell.Application to hook into the Favorites folder).

Instead, I am using the [Environment] type accelerator to locate where the Favorites folder is at.

$IEFav = [Environment]::GetFolderPath('Favorites')
$IEFav

image

Now that I have this information, I can then begin to find all of the *.url files which are the Internet Explorer favorites. This is as simple as using Get-ChildItem to get all of the files; I can even get all of the folders in the favorites as well with no effort at all.

Get-ChildItem -Recurse $IEFav

image

Full Disclosure: I don’t really use Internet Explorer a lot. So these bookmarks were built on the fly for this article as well as a few more forthcoming articles.

Now that I know what and where all of my favorites are, lets take a look at one of the *.url files to see what it has in it.

Get-Content 'C:\Users\Administrator\Favorites\PowerShell\PowerShell Code Repository.url'

image

Quite a bit of information here, but all I really care about is the URL= line as this is the URL of the site that will pop open when you click on the favorite. I can pull this out of the file like so:

(Select-String -Path `
'C:\Users\Administrator\Favorites\PowerShell\PowerShell Code Repository.url' `
-Pattern "^URL").Line.Trim("URL=")

image

And there is the URL that I wanted! I can put this all together with a small amount of code:

Get-ChildItem ([Environment]::GetFolderPath('Favorites')) -File -Recurse | ForEach {
    [pscustomobject]@{
        Name = $_.Name
        URL = ($_ | Select-String "^URL").Line.Trim("URL=")
    }
}

image

Now you might be thinking that I have a great function or something lined up to make this even easier and you would be right! However, I am holding onto this for a little while longer and will show it at the end of this little series. Until then, I hope you enjoyed this article and I will follow up with an article on adding a new favorite for Internet Explorer.

Posted in powershell | Tagged , , | 4 Comments