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!

Sunday, September 23, 2007

Howto: Invoking cmdlets within a cmdlet using C# (part I: the intro)

As part of my involvement with the  PowerGadgets MVP program, I have seen users requesting a way to hide sensitive information.  They aren't looking for fool-proof methods, but something that at least hides plain text information like usernames, passwords and other sensitive information.

The Windows PowerShell SDK has some information on invoking cmdlets within a cmdlet.  I set out to figure out a way to create cmdlets that invoke other cmdlets using the SDK information.  I had some issues figuring out a few things, but with the help of Bruce Payette of the Windows PowerShell development team, I was able to find a working solution.

I'm going to use 2 cmdlets from PowerGadgets to show how this can be done.

I'm going to do this howto in 5 major parts.  First, I will do this with PowerGadgets' invoke-webservice cmdlet (and later do their invoke-sql cmdlet perhaps all in one post or over a few):

  1. Introduction (this message you're reading).
  2. When dealing with cmdlets that derive from the cmdlet class (using csc.exe).
  3. When dealing with cmdlets that *do not* derive from the cmdlet class (using csc.exe).
  4. When dealing with cmdlets that derive from the cmdlet class (using Visual Studio 2005 C# Express).
  5. When dealing with cmdlets that *do not* derive from the cmdlet class (using Visual Studio 2005 C# Express).

If there's any kind of demand for it, I could also shows how to do this via a screencast.

Thursday, September 13, 2007

PowerShell scripts contest (French)

The guys at PowerShell-Scripting (based in France I assume) are putting on a PowerShell scripting contest until the end of December.

Winners will be based on the total points that their scripts will get from other users.  The top 10 point scorers will win prizes such as their upcoming French PowerShell book and some other stuff.

French PowerShell book due early in 2008

Jeffrey Snover will be able to add another book to his multi-lingual selection soon enough.  I see the French guys at PowerShell-Scripting have announced a PowerShell book due out early in 2008.

New FTP automation add-on (COM)

Sapien is offering a free FTP automation library (COM interface) for automating FTP stuff from within scripting languages that have COM support.  I can't wait to try it with PowerShell!

I'm hoping to put on a few blog posts on this (if somebody else doesn't beat me to it).

RSSBus update

I've blogged about RSSBus before.  They recently released RC1 of their server and desktop versions.  Definitely worth checking out if you want to do cool things with RSS feeds.

Tuesday, September 11, 2007

New PowerGadgets build

PowerGadgets has just come out with build 1.0.2806 as of this morning.  The trial version available online is 1.0.2760.

Friday, September 7, 2007

I am a technical reviewer... part 2

I blogged in June that I was a technical reviewer for Sapien.  I just started doing a technical review of an upcoming book from Wrox.  I am under an NDA, so cannot say anything else at this time.