PowerShell Remoting Project Home

Friday, November 30, 2007

PowerShell Script: Amazon WII Watch

I just wanted a WII for Christmas gift and didn't want to spend $500 on ebay.

A Small powershell script will do!


# Begin of script
# =============================================================
# This code is for test purposes only. Use it at your own risk.
# =============================================================
param([string] $query= "B0009VXBAQ", [string] $button = "btn-atc._V46858960_.gif")

#Submit query sequence
"================================================================="
"ASIN: " + $query
"Button: " + $button
""
"Submit query ..."
$uri="http://www.amazon.com/gp/product/" + $query
$AmazonClient = new-object System.Net.WebClient

#checking for results
While ($true)
{
$pagecontent = $AmazonClient.DownloadString($uri);
"================================================================="
# Get Availability
if ($pagecontent -match $button)
{
write-host "In Stock`a`a`a" -foregroundcolor Red
}
else
{
write-host "out of Stock" -foregroundcolor yellow
}
[datetime]::Now.tostring()
"Wait..."
Start-sleep 60
}

#End of script





=================================================================
out of Stock
2007-11-30 13:07:52
Wait...
=================================================================
In Stock

2007-11-30 13:08:58
Wait...
=================================================================
out of Stock
2007-11-30 13:10:01
Wait...
=================================================================
In Stock

2007-11-30 13:11:05
Wait...

Tags:       



Wednesday, February 28, 2007

New Project Home at CodePlex.com

Private workspaces @ gotdotnet.com will be phased out on 3/20/2007. I moved new project home to CodePlex.com @ http://www.codeplex.com/powershellremoting. You can get news, report bugs and request feature there.

We are working on a beta release on X64 and VISTA. We will come up a road map for future PowerShell Remoting development soon. If you have any suggestions, please reply here or discussion section @ new Powershell Remoting project home.

Tags:       



Thursday, January 25, 2007

PowerShell Remoting Go OpenSource!

You can now download full source code of PowerShell Remoting from my workspace.


Let's welcome our new developers: Romangeeko and JaviRuso. We are still looking for developers. If you are intersted, please Email me (shenzhonghao AT gmail DOT com).

Enjoy.

Tags:



Tuesday, December 12, 2006

Looking For Developers

I am very busy with my daytime job and my new born daughter. So I don't have enough time for PowerShell Remoting Project. But I would like to continue the development of this project in a community (probably open source).

I have been contact some friends also intersted in PowerShell Remoting.There are also a couple of user requesting for source code of PowerShell Remoting. If you are interested in this project and would like to contribute your time to it, please Email me (shenzhonghao AT gmail DOT com). It would be great if you could include some details about your previous development experience. Any other suggestion about this project is also welcome.



Tags:       



Wednesday, November 15, 2006

PowerShell Remoting version 0.2.9.0 For V1.0

PowerShell Remoting version 0.2.9.0
1. Rebuild For PowerShell V1.0 RTW.
2. Fix "All User" profile not load at server problem.


Download here (381k)

Some user reported that PowerShellRemoting.ClientPSHost.dll is not registered properly in x64 platform. So I also uploaded a x64 build of PowerShell Remoting. Warning: This package have not been tested on x64 platform, use it at your own risk.


Please uninstall old version of Powershell Remoting before uninstall PowerShell RC2. After install PowerShell v1.0, you can install new version of Powershell Remoting.


Tags:       



Wednesday, September 27, 2006

PowerShell Remoting version 0.2.8.0 For RC2 Drop

Windows PowerShell Team finally released PowerShell RC2. If you are running windows server 2003, you can enjoy new active directory provider. If you are a windows XP (non-English) user like me, I suggest you download Windows PowerShell 1.0 RC2 Language-Neutral Package for Windows XP (KB925228)

Some important changes not in release note.

Big window, different color
> $host.ui.rawui

ForegroundColor       : DarkYellow
BackgroundColor       : DarkMagenta
CursorPosition        : 0,4
WindowPosition        : 0,0
CursorSize            : 25
BufferSize            : 120,3000
WindowSize            : 120,44
MaxWindowSize         : 120,44
MaxPhysicalWindowSize : 128,44
KeyAvailable          : False
WindowTitle           : Windows PowerShell
If you like color setting of old version
>$host.ui.rawui. ForegroundColor = "gray"
>$host.ui.rawui. BackgroundColor = "black"
>clear
Path change
1. Home
C:\WINDOWS\system32\windowspowershell

2. User Profile folder
<My Documents>\WindowsPowerShell

3. Assembly change
System.Management.Automation now goes to GAC

PowerShell Remoting version 0.2.8.0
1. Rebuild for PowerShell RC2 version

Download from here. (381k)

Please uninstall old version of Powershell Remoting before uninstall PowerShell RC1. After install PowerShell RC2, you can install new version of Powershell Remoting.

Tags:       



Sunday, August 06, 2006

Do You Know There is a $Host Variable

PowerShell has a build-in $host variable which expose a System. Management. Automation. Internal. Host. InternalHost object. It is an internal object so you can't access it from assembly but monad team made it directly accessible from PowerShell script. $host is interesting and powerful. Just an example how powerful it is: my PowerShell Remoting "steal" the $host.UI for user interface remoting.

$Host is an implementation of System. Management. Automation. Host. PSHost abstract class. PSHost defined some important properties and methods which will be used for all cmdlet. For more detailed information about PSHost, you can consult Monad SDK online.

Let's see what we can do with $host
1. Some read-only properties provide information about current host.
These could be useful when you have to distinguish among multiple hosts (For example, my PowerShell Remoting has a remote host. Remote host have different Name, InstanceId, Version, etc).

2. Two methods to support legacy application (like ping.exe).

Usually you do not need to call them directly. Monad engine will call them automatically if you invoke legacy application.

3. Two methods about nested prompt.

I already discussed how to use those methods previously.

4. One method to force PowerShell exit.
This could be useful if some sever error occurs and you want to quit PowerShell.exe from your script. You can also pass error code to environment. For example:
>$host.SetShouldExit(10000)
5. $host.UI
This is an implementation of PSHostUserInterface object which expose some import user interface API.

5.1 public override Dictionary<string, PSObject> Prompt(string caption, string message, Collection<FieldDescription> descriptions)
This API is called when cmdlet required field(s) is null or empty. It is capable of get user input ([string]) and cnvert them to almost any .Net type in current appdomain. But the task of constructing Collection<FieldDescription> from script can be daunting.

5.2 public override int PromptForChoice(string caption, string message, Collection<ChoiceDescription> choices, int defaultChoice)
This is standard PowerShell text-base menu system. Don't re-invent wheels! If you want to provide a menu for user input, look nowhere and this method got you all covered. Mow has a nice example of how to use this methods.

5.3 Some more input API to get user input


5.4 Some output API to direct output to different channel and with color support.


5.5 $Host.UI.RawUI
This is an implementation of PSHostRawUserInterface abstract class. This is a new concept in PowerShell. In the prompt post, we use this object to do a lot of tricks.

5.5.1 Some properties to control Console window size, window title, cursor, buffer size, background/foreground color

5.5.2 Some console buffer API. Lee has a great burn-console script to demonstrate these methods.

5.5.3   public override KeyInfo ReadKey(ReadKeyOptions options)

It is a powerful API to read keyboard input. Check out the retuned KeyInfo object, with this method, one can theoretically write a script act like a simple screen editor.
Here is the ReadKeyOption enum:
[Flags]
public enum ReadKeyOptions
{
      AllowCtrlC = 1,
      IncludeKeyDown = 4,
      IncludeKeyUp = 8,
      NoEcho = 2
}
For example
> $host.ui.RawUI.ReadKey(12)
a
     VirtualKeyCode           Character     ControlKeyState             KeyDown
     --------------           ---------     ---------------             -------
                 65                   a              262176                True

Just to remind you, my PowerShell Remoting remote host implemented all Host, UI and RawUI. So feel free to explore those interesting API on you remote host.

Have Fun

Tags:       



Tuesday, July 18, 2006

Runspace Remoting

Scott Hanselman is one of the early users and supporters of my PowerShell Remoting. He did an interesting post about Runspace Remoting. Briefly, he used export-clixml to serialize objects at server and used import-clixml to reconstruct PSObject at client. I have tried similar mechanism and failed. Actually Karl Prosser and I have been talking about using export-clixml/import-clixml a while ago . Great job, Scott!

Despite of my failure on serialization/de-serialization of PSObject, there is other reasons made me choose user interface remoting:
  1. Monad was designed to capable of user interface remoting. Monad engine will manage to display and format (out-default) remote objects. Monad engine can even truncate objects collection for you if there are too many objects in the pipline.
  2. Not all tasks require local objects exactly matching remote objects. For most remote scripting tasks, user interface remoting is good enough. User interface remoting deliver similar user experience as local shell. SSHD already proved itself successful story by similar mechanism. 
  3. User can manipulate "Real" remote objects via user interface remoting (No "Heisenberg Uncertainly Principle of PowerShell").
  4. Serialization/de-serialization method has its own limitations.
    • It can use a lot of resources and band-width. Consider the situation when multiple runspace ouput huge collection of objects at the same time, even with proper threading management server could still be overloaded.
    • What if you just need one simple property of an object with hundreds or thounds of properties, you would have to serialize all public properties of that object and transfer it to client.
    • It can loose some property associate with original objects.
  5. "Clustering" multiple servers is possible with user interface remoting. I am trying to "fork" single client input to multiple servers by simply add current client component to server component. (There are still some problems with this model)

PS: To Monad Team, a public helper API to serialize PSObject to string will be really helpful.

Have Fun

Tags:       



Thursday, July 13, 2006

How to: Using PowerShell through SSH

It is possible to use PowerShell through SSH. Read the story from The Hive Archive.

But there are certain limitations:
1. You have to install cygwin, sshd and ssh client like putty (Well I can certainly live with that. Actually they are always on my hard drive).
2. No prompt
3. some Raw UI might not work

I am really looking forward to the new version of PowerShell with buildin Remoting function. According to Jeffrey Snover : Our plans for remoting are to leverage WS-MGMT the remoting protocol recently standardized through the DMTF.

Have Fun

Tags:       



Wednesday, July 12, 2006

Why There Is an Out-Default Cmdlet

PowerShell have a couple of output control cmdlets:
> gcm out-*

CommandType     Name                            Definition
-----------     ----                            ----------
Cmdlet          Out-Default                     Out-Default [-InputObject <P...
Cmdlet          Out-File                        Out-File [-FilePath] <String...
Cmdlet          Out-Host                        Out-Host [-Paging] [-InputOb...
Cmdlet          Out-Null                        Out-Null [-InputObject <PSOb...
Cmdlet          Out-Printer                     Out-Printer [[-Name] <String...
Cmdlet          Out-String                      Out-String [-Stream] [-Width...
Out-Default cmdlet is one of the most mysterious one.
> help out-default

NAME
    Out-Default

SYNOPSIS
    The default controller of output.

DETAILED DESCRIPTION
    The standard treatment at the end of a pipeline is to send all objects to o
    ut-default.  Out-default then sends them all to format-default. It takes th
    e objects that return and sends them to the default destination.  For this
    reason, it is functionally equivalent to out-host but is not called from th
e console.
The help message does not help at all. Luckily enough, Jeffrey Snover has a blog entry talking about this cmdlet.  In summary, It will "figure out how to format and output the object stream" and send them to host via Out-host cmdlet.

Here is my two cents:
1. Out-Default cmdlet is NOT for interactive console User.
Every interactive command from console will have Out-Default appended automatically by Monad engine. Add Out-Default in the middle of pipline could even cause unexpected output.
> gps | format-table
> gps | out-default | format-table      # format-table will not work.
2. Out-Default cmdlet is for Monad hosting application.
To have a full-blown Monad hosting application, you have to create your own "Host" (System.Management.Automation.Host.PSHost) which implement interface to process output (If you don't have your PSHost output interface implemented, your will get an exception when Out-default finally called out-host.). Every interactive command from user input should have Out-Default appended. Then the output of user command were assessed by out-default, formatted by format-* cmdlet, and eventually sent to user interface by out-host cmdlet.
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;

namespace HostingExample
{
    class TestHost
    {
        static void Main(string[] args)
        {
            string command = "gps";
            PSHost myhost = new MyHost();
            Runspace myRunspace = RunspaceFactory.CreateRunspace(myhost);
            myRunspace.Open();
            Pipeline pipeline1 = myRunspace.CreatePipeline(command, true);
            pipeline1.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
            pipeline1.Commands.Add("out-default");
            Pipeline1.Invoke();
        }
    }

    Class MyHost : PSHost
    {
            // MyHost class should be derived from PSHost abstract class.
    }
}
Although you don't have to (and probably should not) type "Out-Default" at the end of your command, it is always there working for you. Given this reason, Out-Default cmdlet is registered and loaded as default cmdlets.

You see it is there, you do not use it, but it is definitely important.

Tags: