Tuesday, October 2, 2007

.NET Framework 2.0 hotfix that might affect PowerShell

I just noticed this Microsoft KB article:

FIX: You may notice that the memory load is very high when you run an application that is built on the .NET Framework 2.0

I've not checked how this might affect PowerShell, but this information might be useful to others.

Microsoft MVP award

I have received my first Microsoft MVP award.  I have received the award under the Windows Server - Admin Frameworks category for my community efforts around Windows PowerShell.

I want to thank Microsoft for recognizing my community efforts and providing me with the chance to expand my horizons using the MVP logo.

Monday, October 1, 2007

Virtual PowerShell user group meeting... 100 people have signed up!

The virtual PowerShell user group I announced  here has 100 people signed up!  I'm so excited.  I hope everyone will enjoy it, and be excited about future meetings I'm already starting to plan.

Friday, September 28, 2007

Guest blog post on PowerGadgets.com

I just posted a blog entry on the PowerGadgets site on using the credential object with invoke-sql and invoke-webservice.  The latter cmdlet's documentation doesn't indicate, to my knowledge, that the credential parameter is supported.

Tuesday, September 25, 2007

Howto: Invoking cmdlets within a cmdlet using C# (part III: ...using csc.exe)

In the introduction to this howto series, I mentioned part III would show how one invokes cmdlets within a cmdlet using csc.exe.  In this particular example, I'm going to show an example of when the cmdlet we are going to invoke does not derive from the cmdlet class.

As I mentioned in part II, there's a quick PowerShell one-liner to determine if a cmdlet derives from the cmdlet or pscmdlet class.

In our case, our example is from PowerGadgets where we will use their invoke-webserice cmdlet again.  This cmdlet derive from the cmdlet class so my example from part II will also work, but I'm going to use this cmdlet again to show how one can invoke a cmdlet that derives from the pscmdlet class.

In other words, this method I will use works for both types of cmdlets, so it could be seen as the better solution where one doesn't have to determine what class the cmdlet derives from before using it.

Here's the non-commented "guts" of the C# code (I've stripped the regular stuff like the pssnapin stuff), but the full C# code is downloadable here:

   1: string[] args = new string[] { "http://www.webservicex.net/WeatherForecast.asmx?WSDL","GetWeatherByZipCode","80526" };
   2: string command = "invoke-webservice -wsdl $args[0] -method $args[1] $args[2]";
   3: if (PostProcess)
   4: {
   5:     Collection<PSObject> results =
   6:     this.InvokeCommand.InvokeScript(command,false, PipelineResultTypes.None, null, args);
   7:     foreach (PSObject p in results)
   8:     {
   9:          WriteObject(">>> " + LanguagePrimitives.ConvertTo(p, typeof(string)));
  10:     }
  11: }
  12: else
  13: {
  14:     this.InvokeCommand.InvokeScript(command,false, PipelineResultTypes.Output, null, args);
  15: }

We setup our environment in the same way I explained in part II:



   1: PSH> $framework=$([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())
   2: PSH> set-alias csc "$($framework)csc.exe"
   3: PSH> set-alias installutil "$($framework)installutil.exe"
   4: PSH> $ref=[psobject].assembly.location
   5: PSH> $pg="c:\program files\powergadgets\"
   6: PSH> $pg1="$($pg)powergadgets.commands.dll"
   7: PSH> $pg2="$($pg)powergadgets.data.dll"

 


(NOTE: Again from part II, this is to get you going quickly, most do not recommend you use DLLs from the GAC as I do above with how I create the "$ref" variable. Problem is, you need to go and download a huge SDK otherwise, which you should do if you do regular PowerShell development.)

Now, we are going to compile the cmdlet, load it, then run it. I provided the link for the full C# source code above which you will need to go and get:


PSH> csc /t:library /r:$ref /r:$pg1 /r:$pg2 invokewebservice2.cs
PSH> installutil invokewebservice2.dll
PSH> Add-PSSnapin InvokeWebService2
PSH> invoke-webservice2
Latitude         : 40.54729
Longitude        : 105.1076
AllocationFactor : 0.008857
FipsCode         : 08
PlaceName        : FORT COLLINS
StateCode        : CO
Status           :
Details          : {WeatherData, WeatherData, WeatherData, WeatherData...}

 


Now, if you're cycling through all of my examples, I've named the resulting cmdlet invoke-webservice2, so you're going to get a name conflict if you don't unregister the .DLL you might have created from my other examples or rename the namespace and the cmdlet name in the .cs file before you compile.


Again, the same warning applies here about where you decide to put your .cs file and resulting DLLs.  Please read part II again, if you're not sure what I'm referring to.


Success!

I've just shown one way to invoke a cmdlet from within another cmdlet.   You can use this method when the cmdlet you are invoking derives from the cmdlet or the pscmdlet class. In one of my next postings, I'll show you how to do some of this from with Visual Studio 2005 C# Express.

Monday, September 24, 2007

Windows PowerShell Virtual User Group Meeting!!!

Windows PowerShell Virtual User Group Meeting 

Time: October 3rd, 2007 at 12PM (noon) EST (New York time)
Place: Online via Live Meeting 2007

-----------------------------------------------------------
To sign up:
-----------------------------------------------------------
Registration site: http://www.clicktoattend.com/?id=121386
Event Code: 121386
-----------------------------------------------------------

I am proud to announce a new PowerShell user group.  This user group will have its meetings done via Live Meeting with the help of Microsoft.  The intent for the first few meetings is to invite international "PowerShell superstars" to give some brief talks on what they are doing with PowerShell.

-Guest speakers**
*Keith Hill (Microsoft MVP): “We'll look at the evolution of PSCX, the challenges of open source development and take a peek at the roadmap for future versions.”
URL/blog/site:  http://KeithHill.spaces.live.com &
http://www.codeplex.com/powershellcx
*Marc van Orsouw (/\/\o\/\/) (Microsoft MVP): Marc will talk about his PowerTab add-on to PowerShell.
URL/blog/site: http://www.thepowershellguy.com

-Vendor spotlight**
PowerGadgets: The vendor will talk about their PowerShell extensions.
URL/blog/site: http://www.powergadgets.com

-Agenda (all times are EST)**
12:00PM-12:10PM: Introduction by Marco Shaw
12:10PM-12:25PM: Keith Hill (MVP)
12:25PM-12:40PM: Marc van Orsouw (MVP)
12:40PM-12:55PM: PowerGadgets
12.55PM-1:00PM: Closing by Marco Shaw

Please note:
1. This will be done with Live Meeting *2007*.  Most of you will need to download and install the new client.
2. Voice-over-IP will be enabled for this call.  You should be able to hear the audio over your computer's speakerphone if setup properly.
3. International call-in numbers are included at the bottom of this message.
4. This session will be recorded for future offline viewing.
Special thanks to: Rodney Buike from Microsoft.  Thanks for helping make this a reality.

Sponsors: PowerGadgets and Microsoft Technet

**Subject to change without notice. 

International call-in numbers:
(You will be billed unless you are using a number identified as "toll free")

USA/CANADA          1-866-500-6738 (toll free)
AUSTRALIA      1-800-202-713 (toll free)
BELGIUM            32-3-400-2811
BRAZIL            0800-8911983 (toll free)
DENMARK            45-7014-0278
FRANCE            33-1-70-70-62-75
GERMANY            49-69-2222-7227
HONG KONG      852-2286-5645
IRELAND            353-1-247-5443
JAPAN            81-3-5539-5167
NEW ZEALAND      0800-448-997 (toll free)
SWITZERLAND      41-44-580-6291

Howto: Invoking cmdlets within a cmdlet using C# (part II: ...using csc.exe)

(NOTE: The formatting is a bit off.  I really believe this is due to the Live Writer code snippet plugin.  I will try to edit the post to fix it up at a later time.)

In the introduction to this howto series, I mentioned part II would show how one invokes cmdlets within a cmdlet using csc.exe. In this particular example, I'm going to show an example of when the cmdlet we are going to invoke derives from the cmdlet class.

Oisin Grehan provided me with a cool one-liner to determine whether a cmdlet derives from the cmdlet or pscmdlet class:

   1: get-command invoke-webservice |`
   2:   foreach-object {
   3:     $_.name +`
   4:     " is pscmdlet: " +`
   5:     [management.automation.pscmdlet].`
   6:     IsAssignableFrom($_.implementingtype)
   7: }

If the output from the above is false, our cmdlet derives from the cmdlet class.


In our case, our example is from PowerGadgets where I will use their invoke-webservice cmdlet (in later posts, I will do the same with their invoke-sql cmdlet). This cmdlet derives from the cmdlet class.


We're going to try to use the invoke-webservice in a new invoke-webservice2 cmdlet. I was inspired by Keith Hill's post on calling a web service from PowerShell.


Here's the non-commented "guts" of the C# code (I've stripped the regular stuff like the pssnapin stuff), but the full C# code is downloadable here:



   1: InvokeWebServiceCommand iws = new InvokeWebServiceCommand();
   2: iws.WSDL = "http://www.webservicex.net/WeatherForecast.asmx?WSDL";
   3: iws.Method = "GetWeatherByZipCode";
   4: iws.Parameters = new object[] { "80526" };
   5: foreach (object o in iws.Invoke<object>())
   6: {
   7:     WriteObject(o);
   8: }

 


Compiling from the command-line using the .NET Framework's C# compiler (csc.exe) is pretty easy and is packaged with the .NET 2.0 (and a new one with the .NET 3.5 framework), so any machine with PowerShell installed has the compiler.


Let's setup the environment:



   1: PSH> $framework=$([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())
   2: PSH> set-alias csc "$($framework)csc.exe"
   3: PSH> set-alias installutil "$($framework)installutil.exe"
   4: PSH> $ref=[psobject].assembly.location
   5: PSH> $pg="c:\program files\powergadgets\"
   6: PSH> $pg1="$($pg)powergadgets.commands.dll"
   7: PSH> $pg2="$($pg)powergadgets.data.dll"



(NOTE: This is to get you going quickly, most do not recommend you use DLLs from the GAC as I do above with how I create the "$ref" variable. Problem is, you need to go and download a huge SDK otherwise, which you should do if you do regular PowerShell development.)


Now, we are going to compile the cmdlet, load it, then run it. I provide the link for the full C# source code above which you will need to go and get:




PSH> csc /t:library /r:$ref /r:$pg1 /r:$pg2 invokewebservice.cs
PSH> installutil invokewebservice.dll
PSH> Add-PSSnapin InvokeWebService2
PSH> invoke-webservice2
Latitude         : 40.54729
Longitude        : 105.1076
AllocationFactor : 0.008857
FipsCode         : 08
PlaceName        : FORT COLLINS
StateCode        : CO
Status           :
Details          : {WeatherData, WeatherData, WeatherData, WeatherData...}



(NOTE: Again, this is just quick and dirty, *before* you run the above commands, you should create a permanent directory somewhere in C:\Program Files, maybe something like "My_Cmdlets", for example, where you will place the .cs file, and create the .dll from there. Otherwise, you risk creating the DLLs in a temporary directory, then deleting them by mistake down the road.)


Success!


I've just shown one way to invoke a cmdlet from within another cmdlet. As I briefly mentioned, you can only use this method when the cmdlet you are invoking derives from the cmdlet class. In one of my next postings, I'll show you how to invoke a cmdlet when it does not derive from the cmdlet class.


Enjoy!