Wednesday, August 04, 2010

PSHSCripts.Blogspot.Com – 2 years On!

Just over 2 years ago, I created a new blog, The PowerShell Scripts blog over at http://pshscripts.blogspot.com. The idea was simple – a blog with single function PowerShell scripts. Scripts that demonstrated one (or at least a very small number) of things to do with PowerShell. I had in mind that since the blog was hosted by Google, they’d do a good job of indexing it, and providing links to it. Which is exactly what happened.

In the two years, I’ve had over 65,000 visitors to the blog. At present, I’m getting around 170 hits per day and just under 300 page hits per day on average over a week. However, this is very much a week day blog with Monday-Friday tending to be closer to 200+ hits/day during the week.

But the interesting, and gratifying, thing is the percentage of hits coming from the key search engines (Google and more recently Bing) and the search terms they are using. I’ve used a free traffic counter from sitemeter to measure the traffic, but I only see the last 1000 visitors and had not added a more permanent tracking system – but I’ve recently added Google Analytics the site. So far, the results from both sites show the same tends.

Looking at the Analytic's output for the past month. around 70% of all the traffic to the blog comes from Google and Bing with a bit more from PowerShell.com, TechNet and this blog. There are a few other search engines that send traffic, but Google and Bing are dominant.  Also, around 13% of the traffic comes from direct hits on http://pshscripts.blogspot.com

Looking at the search terms used is also interesting. PowerShell Scripts (and PowerShell script) make up 18% or all hits. Below those two, there’s a very long tail of relatively low numbers of hits over the past month. There were just around 1000 separate search terms used – and all but a handful more than once or twice. That shows that the narrow focus of each post has proven useful – you can search with a fairly narrow term, such as “PowerShell ipaddress wmi” or “powershell send udp” and see the blog at the top or near the top of the 1st page.

There were two discoveries that were curious. First, looking at the referring sites, I noticed one site had a relatively high number of pages per visit and a long time too on average time on site. The bounce rate for this traffic was also very very low. It turns out that an IT professor in Viet Nam has put a link to my blog and all the slides from the upcoming PowerShell V2 class. Not sure about the legality of putting the slides up – but see for yourself at http://hoanguyen40.ecoles.officelive.com/OSScripting.aspx.

The other amusing thing I found is that, when looking at the networks that send you traffic (think ISP). The top network listed was Microsoft!

All in all, a good first two years for this blog – getting several hundred hits a day is more than I expected.

Tuesday, August 03, 2010

Using Later Versions of the .NET Framework Remotely

I’ve posted a couple of articles recently regarding using later versions of the .NET Framework. Through the magic of .NET, you can just create a simple .CONFIG file to tell the relevant executable to use a later version of the framework by default. A .CONFIG file is just a very simple bit of XML as I demonstrated here, where I show how to create the XML and save it as PowerShell.Exe.CONFIG. This worked fine to enable the PowerShell console to use later versions of the framework. And I showed some of those results in a separate post here.

To enable this work work with PowerShell Plus, I just went and found the executable for PowerShell Plus, created the relevant .CONFIG file (PowerShellPlus.Exe.CONFIG). Now PowerShell Plus brings up .NET 4 too! Yeah! Or so I thought.

After posting these articles I saw on Twitter that @qa_warrior was having trouble doing this remotely. The upshot of his problem was that even though he’d configured PowerShell to use .NET 4.0 on both client and server, when he remoted, his remote session was based on 2.0. It turns out that this too was simple to fix – if you understand how PowerShell remoting is implemented on the remote host

.

When you create a new PSSession with a remote server, what you are doing is instantiating a PowerShell runspace and sending it commands to execute (and returning the results, albeit serialised). In order for the remote machine to create (and later use) the runspace, Windows needs to house that runspace inside a process. Powershell 2.0 creates that runspace inside an executable wsmprovhost.exe.  You can see this in action here:

SNAGHTML57421abb

In this screenshot, I created two remote sessions (admittedly to my self – but ‘remote’ nonetheless). You can see the two occurrences of wsmprovhost.exe and the two remote sessions. After removing these remote session, you can see that there are no occurrences of either wsmprovhost or the remote sessions. Then after you create a new PSSession, you can see the new session and the new occurrence of wsmprovhost.

Technorati Tags: ,

Monday, August 02, 2010

More on Using Different Versions of the .NET Framework

In yesterday’s blog post, I wrote about being able to use later versions of the .NET Framework with PowerShell. The trick was simple: create a config file, a small file of XML, to enable the use of, in my case, the .NET Framework Version 4 and the new namespace System.Numerics. That XML file tells PowerShell what version of the .NET Framework to load. You can see this if you display $psversiontable variable. By default, you’ll see something like this:

PSH [C:\foo]: $PSVersionTable

Name                           Value
----                           -----
CLRVersion                     2.0.50727.4200
BuildVersion                   6.0.6002.18111
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions           {1.0, 2.0}
SerializationVersion           1.1.0.1
PSRemotingProtocolVersion      2.1

But with the .Config file in place, you’d now see this:

PSH [C:\foo]: $PSVersionTable

Name                           Value
----                           -----
PSVersion                      2.0
PSCompatibleVersions           {1.0, 2.0}
BuildVersion                   6.0.6002.18111
PSRemotingProtocolVersion      2.1
WSManStackVersion              2.0
CLRVersion                     4.0.30319.1
SerializationVersion           1.1.0.1

Another key difference is that when you now load additional .NET namespaces using LoadWithPartialName, you will get later version of the dll (the exact version number loaded depends on what you put into the config file. So loading Windows Forms now looks like this:

 

PSH [C:\foo]: [system.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

GAC    Version        Location
---    -------        --------
True   v4.0.30319    C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c…

By default, you got this:

PSH [C:\foo]: [system.Reflection.Assembly]::LoadWithPartialName("system.windows.forms")

GAC    Version        Location
---    -------        --------
True   v2.0.50727     C:\Windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c…

It’s pretty easy to use later versions of the .NET Framework. These later versions provide new classes you may find useful.

PSH [C:\foo]: [system.Reflection.Assembly]::LoadWithPartialName("system.windows.forms")

GAC    Version        Location
---    -------        --------
True   v2.0.50727     C:\Windows\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll

But beware of doing this in a data centre without testing that your existing scripts are fully compatible with the later versions of the Framework. You shouldn’t have any problems as MS is pretty good about forward compatibility, but it never hurts to be careful.  Just ensure you do thorough testing before rolling this out across the board.

Technorati Tags: ,

Sunday, August 01, 2010

Using Newer Version(s) of .NET with PowerShell

I’ve been playing around a bit with the latest version of the .NET Framework. There are some pretty cool new classes and namespaces but one that caught my eye was System.Numerics. This namespace has two neat classes: System.Numerics.BigInteger and Sytem.Numerics.Complex – these represent big integers and complex numbers respectively. To demonstrate the BigIngteger class, I’ve written two small scripts: New-BigInteger.ps1 and Get-BigIntegerProperties.ps1 (with more to come!). You can get these and several hundred more PowerShell scripts from my Powershell Scripts blog. When I first started to develop these scripts, starting first to translate an MSDN sample from C# into  PowerShell, I came across some curious errors. In the end learned how to call updated versions of the .NET Framework.

By default, PowerShell uses .NET version 2.0. But if you want to use classes implemented in later versions of the Framework (in namespaces that are not loaded by default of course), you first need to load the relevant dll. You can do this as follows:

Add-Type -Path "C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Numerics.dll"

But there’s only one problem (by default!) – when you do this you get the following run time error:

Add-Type : Could not load file or assembly 'file:///C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Numerics.dll' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.
At line:1 char:9
+ Add-Type <<<<  -Path "C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Numerics.dll"
    + CategoryInfo          : NotSpecified: (:) [Add-Type], BadImageFormatException
    + FullyQualifiedErrorId : System.BadImageFormatException,Microsoft.PowerShell.Commands.AddTypeCommand

The solution is pretty simple – just tell PowerShell to use a later version of the CLR. To do this, you need to create a config file, named PowerShell.Exe.Config, located in the same folder as PowerShell.Exe (and another one for PowerShellISE.Exe, or PowerShellISE.Exe.Config). These config files contain a small bit of XML to tell the system which version of the CLR to use. To access the .NET 4.0 versions, use the following:

<?xml version="1.0"?>
<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0.30319"/>
        <supportedRuntime version="v2.0.50727"/>
    </startup>
</configuration>

With this XML created, just restart PowerShell and you can add the System.Numerics.Dll and use the classes in that namespace!