Run PowerShell in Version 2 While PowerShell V3 RC Is Installed

Many of you have downloaded the latest build of PowerShell V3 (currently in RC). While PowerShell V3 is amazing, you might have wondered how you can run some scripts or other things with PowerShell V2 that are just not working the way you want them to in V3. Given that V3 loads side by side with V2, there must be a way to get this to work without having to uninstall V3 and re-install V2…

Well, you are in luck because there is a simple switch that you can add with PowerShell.exe. The switch is: –Version 2.

Simple, isn’t it?

Don’t believe that it works yet? Here are some examples to make a believer out of you.

Version 3 using $psversiontable

$psversiontable

image

Version 2 using $psversiontable

powershell.exe -Version 2
$psversiontable

image

Notice that the PSVersions are in fact different and match what the version should be. Also notice that the CLR versions are completely different (V3 uses .Net 4.0 while V2 uses 2.0).

Once last example. You know some of the great new commands with V3 or even some commands such as Invoke-RestMethod or old commands you know and love such as with great new parameters such as –Tail on Get-Content. Well, take a look at the number of cmdlets available in V3 and V2 and you will see that all of the new commands in V3 are not available in V2.

Invoke-RestMethod with V3

Invoke-RestMethod -Uri http://blogs.msdn.com/b/powershell/rss.aspx |
Select Title

image

Invoke-RestMethod with V2

powershell.exe -Version 2
Invoke-RestMethod -Uri http://blogs.msdn.com/b/powershell/rss.aspx |
Select Title

image

Just like I expected, Invoke-RestMethod is not even recognized while Powershell is running with the –Version 2 switch.

Now for the number of cmdlets visible between the two versions.

V3 – Number of cmdlets

Get-Command -type cmdlet | measure-object

image

V2 – Number of cmdlets with –Version 2 switch

powershell.exe -Version 2
Get-Command -type cmdlet | measure-object

image

Definitely a difference in what is available between the versions. So keep that in mind if you happen to use the –Version switch to go V2, otherwise you could be left wondering why some of the V3 commands are not working like you think they should. So a script or module isn’t working just yet under V3, in the same console you can just run powershell.exe –Version 2 and have that script working for you.

Posted in powershell, V3 | Tagged , , | 4 Comments

Quick-Hits: How Long Did That Last Command Take?

Have you ever ran a command or script and wanted to know how long it takes to complete but forgot to wrap the code or script with Measure-Command? Well, you are in luck because you can take a look at the history using Get-History and check out the StartExecutionTime and EndExecutionTime to determine how long it took the command to run!

Lets run a simple command such as Get-ChildItem on my C:\Windows\System32 directory.

Get-ChildItem C:\Windows\System32

Ok, now that we have done that, we need to use Get-History to get the time it took to complete the command by subtracting StartExecutionTime from EndExecutionTime to get that answer.

(Get-History)[-1].EndExecutionTime - (Get-History)[-1].StartExecutionTime

image

As you can see, the command took just over 9 seconds to run. Now this isn’t a replacement for Measure-Command, but it does provide a decent way to find out how long a command took to run. The [-1] that I used means that I am getting the last member of the collection.

Pretty cool stuff, but I wanted an easier way to get this information without having to type out that command. So naturally, I made this into a simple function that you can use below.

Code

With this function, you can simply run it after a command to find out how long the last command took to run.

Function Get-LastCommandExecutionTime {
    <#
        .SYNOPSIS
            Gets the execution time of the last command used.
        .EXAMPLE
            Get-LastCommandExecutionTime

            Description
            -----------
            Gets the last execution time of the last command run.
    #>
    Process {
        (Get-History)[-1].EndExecutionTime - (Get-History)[-1].StartExecutionTime
    }
}
Get-Command
Get-LastCommandExecutionTime

image

Nothing revolutionary, but still something that you might find useful in your scripting journeys.

Enjoy!

Posted in powershell | Tagged , , | 1 Comment

Filter Using Parameters Instead of Where-Object When Possible

This was a post I intended on writing during/after the 2012 Scripting Games, but just never got around to finishing it up. While it is great to know for the games itself, it also applies to everyday scenarios for folks just coming up into PowerShell and for those that have been doing this for a while.

When writing a one-liner or a script in PowerShell, the recommended practice is to filter as far left as possible before doing anything else to bring down the amount of data to be as small as possible. Typically we use the following process:

Filter | Select/Sort | Format

When writing a script or a function it is important to know the capabilities of existing cmdlets, in this case whether it has the ability to filter for a specific item. And I don’t mean that it has just a –Filter parameter, but other types of parameters that can be used to filter the data being returned. A lot of times the old standby is to take the results of a cmdlet and pipe it into Where-Object to filter for the data that we want.

Most of the time, this is the way to get what you need, but it is also very beneficial to you to spend a short time looking at the parameters on a specific cmdlet just to see if there is something that will help you to get the data you need. While the time difference may not always be that great, it does help the code by taking out the un-needed Where-Object filter. Also it is important to note that times will vary on your system based on resources, bandwidth, etc… as well as what it is you are trying to filter. In other words, you may not see astronomical differences in some commands that you might see in others. Regardless, it still a good practice to get into using what the cmdlet has to offer as it is using the OS APIs to handle the filtering which is especially useful when run against remote systems as all of the filtering is happening on the remote end rather than having to bring all of the data back. On top of bringing all of that data back, you are then using the local system resources for filtering.

Examples

For instance, lets look at using Get-WMIObject with both a Where-Object filter and then using the same command but instead using the builtin –Filter parameter against a simulated 25 remote systems (by simulated, I mean the same remote system 25 times).

For the sake of getting command times, every command will be wrapped in Measure-Command {}.

 Measure-Command {
    1..25 | ForEach {
         Get-WmiObject -Class Win32_Service -ComputerName DC1 | Where {
            $_.State -eq 'running'
         }
    }
}

 

image

13 seconds against 25 systems…not too bad, but lets see what happens with the –Filter parameter.

Measure-Command {
    1..25 | ForEach {
        Get-WmiObject -Class Win32_Service -ComputerName DC1 -Filter "State='running'"
    }
}

image

Now that is better. It went from 13 seconds down to 6 seconds by using the built-in –Filter parameter.

What is happening here is that where the Where-Object will take each complete collection of objects from the remote system and then does the filtering, which is time consuming and a waste of resources. The –Filter will actually perform all of the filtering that is provided on the remote system before bringing the data across the network to the console. Much more efficient which saves on time and resources.

Let’s take a look at another example, this time using Get-ChildItem to show why you might want to check out the parameters prior to filtering with Where-Object for specific files or extensions.

Measure-Command {
    Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue | Where {
        $_.Extension -eq "txt"
    }
}

image

Ok, not too bad with using Where-Object to filter for only .TXT files, but again, lets apply the –Filter parameter to see how much of a jump in performance we can get.

Measure-Command {
    Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue -Filter "*.txt"
}

image

Wow, over a minute difference between between the –Filter parameter being used and using Where-Object to filter the objects for .TXT files. So in this case, we can easily see how much better using a parameter filter is better than piping the objects to Where-Object for filtering.

The last example of this article is looking at Get-WinEvent and using the built-in filter parameters are quicker than using Where-Object.

Measure-Command -Expression {
    Get-WinEvent -LogName application -ErrorAction SilentlyContinue | Where-Object { 
        $_.providername -Like '*msi*' -AND 
        $_.TimeCreated -gt (Get-Date).AddDays(-15) 
    }
}

image

Now for the same cmdlet with some filtering.

Measure-Command {
     Get-WinEvent -ea SilentlyContinue -FilterHashtable @{
        ProviderName= "MsiInstaller"
        LogName = "application"
        StartTime = (Get-Date).AddDays(-15)
    }
}

image

And once again we can see that the built-in filtering with parameters out performs using Where-Object.

As we have seen, sometimes the time difference may not be that great, but other times it is more than enough to show why you want to spend a little time to find out what types of parameters that a cmdlet has. By doing this, you can potentially find a more efficient way of gathering data, especially when you start stacking multiple commands against multiple remote systems. If you remember earlier I mentioned about Filter | Select/Sort | Format, you could probably break it up a little more to be Parameter Filter | Where-Object Filter | Select/Sort | Format.

Posted in powershell | Tagged , , , | 7 Comments

PowerShell Magazine Article Live Today

My first ever article on the PowerShell Magazine is now live today! This article talks about my favorite 3 tips for PowerShell. This is a great opportunity that I could not pass up on! Check it out and let me know what you think!

Boe Prox’ Favorite PowerShell Tips & Tricks

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

Tech-Ed 2012 Bound

In a few more days I will be heading out to Tech-Ed 2012 to check out some great sessions and meet up with some amazing people. I last went to Tech-Ed back in 2010 when it was in New Orleans and had a blast. Did I mention I won a pass from the Scripting Games by placing 2nd? Well, that time was amazing and my brain was pretty full by the time it was all said and done.

This year the conference is being held in Orlando,FL and promises to be just as good as the one I went to a couple years ago. My schedule is packed with sessions dealing with mostly PowerShell (of course) as well as other sessions dealing with DNS and Active Directory as well as checking out the Tech Expo and visiting various vendors and Microsoft experts. I will of course be checking out the PowerShell and Scripting Guy booth as well. There is also a post Tech-Ed PowerShell workshop that deals with a base Windows Server 2012 image and works with the following items:

  • Writing a PowerShell script workflow to perform Server deployments
  • Creating a constrained endpoint that hosts only the deployment workflow
  • Delegate a set of credentials for the workflow to use
  • Exposing the workflow and it’s results through a RESTful webservice
  • Using Windows PowerShell Web Access to manage the workflow

Yes, it is going to be that awesome!

For those of you attending, I will see you there!

Posted in News, Tech-Ed | Tagged , | Leave a comment