Wednesday, December 31, 2008

Monad Manifesto – A Blast from the Past

I was looking today for some information about PowerShell (details on modules if you must know!), and I came across a very old Blog Posting by Jeffrey Snover. Entitled “Monad Manifesto – the origin of Windows PowerShell”, there’s also an 18-page white paper dated August 8 2002 entitled Monad Manifesto.

With the New Year just ahead, this old paper makes great reading. Of course, as the blog post points out, this is not an official white paper and it’s no longer very accurate (and shows the very old syntax that we had in the early versions of MSH). But as a vision, writen in 2002, this paper is required reading.

It’s interesting that it’s taken nearly 6.5 years from that paper to CTP3, and we’re still 6-9 months (or more) away from V2 RTW/RTM. I’ve always sort of thought the pace of development in PowerShell was fairly quick. As the Grateful Dead sing: “What a long, strange trip it’s been”.

Happy new year – and best wishes for 2009.

Tuesday, December 30, 2008

PowerShell’s [WMICLASS] Type accelerator

In January of this year, I wrote a basic article on PowerShell’s WMI Type Accelerators. A type accelerator is, in effect,a shortcut to some underlying .NET component. PowerShell comes with three type accellerators for WMI:
  • [WMI] – a shortcut way of getting to a single instance of a class. I described this type accellerator in an article in February.
  • [WMICLASS] – a short cut to a WMI Class definition to enable access to the class’s static properties and methods. I describe this type accelerator below.
  • [WMISEARCHER] – a short cut to .NET’s ManagementObjectSearcher enabling you to search for objects easily. This type accellerator is an opportunity for a future article.
The [WMICLASS] type accelerator takes a string containing a relative or absolute path to an WMI class, and returns a a System.Management.ManagementClass object that represents the specified class (as opposed to an occurance of that class). For example let’s take a look at the Win32_Share WMI Class. First, look at what Get-WMIObject returns, then look at what the [WMICLASS] type accelerator returns:
 PS c:\foo:\> Get-WMIOBjecct Win32_share | get-memberm
  TypeName: System.Management.ManagementObject#root\cimv2\Win32_Share
Name                MemberType   Definition
----                ----------   ----------
Delete              Method       System.Management.ManagementBaseObject Delete()
GetAccessMask       Method       System.Management.ManagementBaseObject GetAccessMask()
SetShareInfo        Method       System.Management.ManagementBaseObject SetShareInfo(System.UInt32 MaximumAllowed, System.String Descr...
AccessMask          Property     System.UInt32 AccessMask {get;set;}
AllowMaximum        Property     System.Boolean AllowMaximum {get;set;}
Caption             Property     System.String Caption {get;set;}
Description         Property     System.String Description {get;set;}
InstallDate         Property     System.String InstallDate {get;set;}
MaximumAllowed      Property     System.UInt32 MaximumAllowed {get;set;}
Name                Property     System.String Name {get;set;}
Path                Property     System.String Path {get;set;}
Status              Property     System.String Status {get;set;}
Type                Property     System.UInt32 Type {get;set;}
__CLASS             Property     System.String __CLASS {get;set;}
__DERIVATION        Property     System.String[] __DERIVATION {get;set;}
__DYNASTY           Property     System.String __DYNASTY {get;set;}
__GENUS             Property     System.Int32 __GENUS {get;set;}
__NAMESPACE         Property     System.String __NAMESPACE {get;set;}
__PATH              Property     System.String __PATH {get;set;}
__PROPERTY_COUNT    Property     System.Int32 __PROPERTY_COUNT {get;set;}
__RELPATH           Property     System.String __RELPATH {get;set;}
__SERVER            Property     System.String __SERVER {get;set;}
__SUPERCLASS        Property     System.String __SUPERCLASS {get;set;}
PSStatus            PropertySet  PSStatus {Status, Type, Name}
ConvertFromDateTime ScriptMethod System.Object ConvertFromDateTime();
ConvertToDateTime   ScriptMethod System.Object ConvertToDateTime();

PS c:\foo:\> [WMICLASS]'Win32_share' | get-member
   TypeName: System.Management.ManagementClass#ROOT\cimv2\Win32_Share
Name                MemberType    Definition
----                ----------    ----------
Name                AliasProperty Name = __Class
Create              Method        System.Management.ManagementBaseObject Create(System.String Path, System.String Name, System.UInt32 ...
__CLASS             Property      System.String __CLASS {get;set;}
__DERIVATION        Property      System.String[] __DERIVATION {get;set;}
__DYNASTY           Property      System.String __DYNASTY {get;set;}
__GENUS             Property      System.Int32 __GENUS {get;set;}
__NAMESPACE         Property      System.String __NAMESPACE {get;set;}
__PATH              Property      System.String __PATH {get;set;}
__PROPERTY_COUNT    Property      System.Int32 __PROPERTY_COUNT {get;set;}
__RELPATH           Property      System.String __RELPATH {get;set;}
__SERVER            Property      System.String __SERVER {get;set;}
__SUPERCLASS        Property      System.String __SUPERCLASS {get;set;}
ConvertFromDateTime ScriptMethod  System.Object ConvertFromDateTime();
ConvertToDateTime   ScriptMethod  System.Object ConvertToDateTime();
In this example, you can see that Get-WMIObject returns System.Management.ManagementObject objects, while [WMICLASS} returns System.Management.ManagementClass objects – in other words, different object types with different members. I note that the MSDN library documentation does not really differentiate static and object members clearly – so you just have to know which is which when dealing with WMI classes.
The object occurrences returned from Get-WMIObject contain three methods: Delete, GetAccessMask and SetShareInfo. These three methods operate on a particular occurrence, i.e. Delete means “delete this occurrence”. However, the object returned from [WMICLASS} both contains none of those three dynamic methods, but does create a static method: Create, i.e. create a new share.
Why bother with [WMICLASS] you might ask. The answer is simple: to access the static methods and properties/fields that the class exposes. In the case of theWin32_Share class, the class has a static method (create) and three dynamic methods( delete, GetAccessMask and SetShareInfo). If you want to create a new share, then use [WMICLASS] to get access to the create method. You can get access to the Delete method by getting the appropriate method. This bit of code illustrates this:

.SYNOPSIS
    Demonstrates WMI and Win32_Share
.DESCRIPTION
    This script looks at objects retured from Get-WMIObject, and [WMICLASS] and demonstrates
    the use of a static method (create) and a dynamic or object method (delete).
.NOTES
    Author   : Thomas Lee - tfl@psp.co.uk
.LINK
    http://www.pshscripts.blogspot.com
.EXAMPLE
    Left as an exercise for the reader
#>

# Display shares at start
$start = get-wmiobject win32_share | where {$_.name -match "Foo"}
if ($start) {
  "{0} foo shares at start, as follows:" -f $start.count;
  $start}
else {"No foo shares"}

# Create a foo22 share
"";"Adding Foo22 share"
$class = [WMICLASS]'win32_share'
$ret = $class.create("c:\foo", "foo22", 0,$null,"Test Share Creation with WMI")
if ($ret.returnvalue -eq 0){
"Foo22 Share created OK"}
else {
"Share not created, error code: {0}" -f $ret.returnvalue
}

# Display results
"";"Foo shares now:"
get-wmiobject win32_share | where {$_.name -match "foo"}
""

# Delete the foo22 share
$del = Get-WmiObject win32_share | where {$_.name -eq "foo22"}
$ret = $del.delete()
if ($ret.returnvalue -eq 0){
"share deleted OK"}
else {
"Share not deleted, error code: {0}" -f $ret.returnvalue
}

# Display final results
"";"Foo at the end:"
$finish = get-wmiobject win32_share | where {$_.name -match "foo"}
if ($finish) {
  "{0} foo shares at the end, as folllows:" -f $start.count;
  $start}
else {"No foo shares at the end:"}
""
This sample, after the now obligatory Advanced Function help stuff, obtains and displays any shares on the local system that contain the string “foo”. Then, in line 24 the scripts gets the Win32_Share class, and in line 25 used the create static method to create a new share (Foo22). In line 39, the script deletes the newly added share, and finally prints out the remaining shares matching “foo”.
In summary, the [WMICLASS] gives you access to the static methods or members exposed by a WMI class.

Monday, December 29, 2008

Type Accelerators for PowerShell CTP3

Type Accelerators are a PowerShell feature that simplifies access to underlying WMI or .NET objects. Earlier this year I wrote two blog articles, the first about the WMI type accelerators and the second specifically about the [WMI] type accelerators. At some point, I intend to write about the other two ([WMICLASS] and [WMISEARCHER]) WMI related type accelerators.
In a most interesting Christmas Day post, Osin posted a detailed look at Type Accelerators within PowerShell CTP3. By using Reflector to look at the actual PowerShell code, you can see how PowerShell implements Type Accelerators, through using the TypeAccellerator class. Neat! But neater still, Osin shows how to make use of this technique to both list out the existing Type Accelerators as well as how to add more.
Here’s a simple function definition that returns the existing type accelerators:

function Get-Typeaccelerator
{  #  reference the accelerators
     $acceleratorsType = [type]::gettype("System.Management.Automation.TypeAccelerators")  
  #  return all built-in accelerators (property)     return $acceleratorstype::get.GetEnumerator()|
     select @{Name="Name"; expression={$_.key}},
     @{name="Type"; expression={$_.value}} | sort name
}


Sunday, December 28, 2008

PowerShell CTP3 Comment Based Help

I’ve been playing a lot with comment based help (CBH) in PowerShell CTP3.CBH enables you to decorate a script with help information. This information can then be read by Get-Help to provide help text back to a user of your script. From an enterprise, production scripting point of view, this is very cool and super useful. Production scripts should always be well documented. And for community generated scripts, having great help text will only aid other users trying to integrate these community scripts into their environment.

The CBH information is specified inside a block comment at the start of your script. A block comment begins with  “<# “ and ends with “#>”- everything inside these two character blocks is considered to be a comment. Here’s a very simple CBH block within a script:

# Script CBH-1
<# .SYNOPSIS
     Cool Script 
.DESCRIPTION
     No really. It's really really cool"
.NOTES
     Author     : Thomas Lee - tfl@psp.co.uk
.LINK
     http://tfl09.blogspot.com
#>
"The meaning of life, the universe and everything is {0}" -f 42 
You can run this script, and it'll produce a predictable output. BUT, if you save it, say as Truth.Ps1, you can then run Get-Help against it, with output as follows:

PS C:\Foo:\> Get-Help  C:\Foo\Truth.ps1
NAME
     C:\foo\truth.ps1
SYNOPSIS
     Cool Script
SYNTAX
     C:\Foo\truth.ps1 []
DETAILED DESCRIPTION
     No really. It's really really cool"
RELATED LINKS http://tfl09.blogspot.com
REMARKS
     To see the examples, type: "get-help C:\Foo\Truth.ps1 -examples".     For more information, type: "get-help C:\Users\tfl\AppData\Local\Temp\Untitled19.ps1 -detailed".
     For technical information, type: "get-help C:\Foo\Truth.ps -full".
PS C:\foo>Get-Help C:\foo\truth.ps1 -Full
NAME     C:\foo\truth.ps1
SYNOPSIS     Cool Script
SYNTAX     C:\Foo\Truth.ps []
DETAILED DESCRIPTION
     No really. It's really really cool"
PARAMETERS
     This cmdlet supports the common parameters: -Verbose, -Debug,
     -ErrorAction, -ErrorVariable, -WarningAction, -WarningVariable,
     -OutBuffer and -OutVariable. For more information, type,
     "get-help about_commonparameters".
 INPUT TYPE
 RETURN TYPE
 NOTES
         Author     : Thomas Lee - tfl@psp.co.uk
RELATED LINKS http://tfl09.blogspot.com

This is very useful, as I hope you can imagine.

I’ve been doing some digging into this feature. The CTP3 release notes make mention of the various sections that help reports. I’ve built a sample script with what I think to be all the section names used. The idea being that this basic script can be used to demonstrate Get-Help in all its glory. However, what I’ve discovered is a great idea, but with some challenges.
First, here’s my sample auto-help demo script:

<#
.SYNOPSIS
    A summary of what this script does
    In this case, this script documents the auto-help text in PSH CTP 3
    Appears in all basic, -detailed, -full, -examples
.DESCRIPTION
    A more in depth description of the script
    Should give script developer more things to talk about
    Hopefully this can help the community too
    Becomes: "DETAILED DESCRIPTION"
    Appears in basic, -full and -detailed
.NOTES
    Additional Notes, eg
    File Name  : Get-AutoHelp.ps1
    Author     : Thomas Lee - tfl@psp.co.uk
    Appears in -full
.LINK
    A hyper link, eg
    http://www.pshscripts.blogspot.com
    Becomes: "RELATED LINKS"
    Appears in basic and -Full
.EXAMPLE
    The first example - just text documentation
    You should provide a way of calling the script, plus expected output
    Appears in -detailed and -full
.EXAMPLE
    The second example - more text documentation
    This would be an example calling the script differently. You can have lots
    and lots, and lots of examples if this is useful.
    Appears in -detailed and -full
.INPUTTYPE
   Documentary text, eg:
   Input type  [Universal.SolarSystem.Planetary.CommonSense]
   Appears in -full
.RETURNVALUE
   Documentary Text, eg:
   Output type  [Universal.SolarSystem.Planetary.Wisdom]
   Appears in -full
.COMPONENT
#>

Saturday, December 27, 2008

MSDN Code Search Preview (http://msdn.krugle.com/)

Looking at the MSDN Library site tonight and I noticed a new “Feature Spotlight” – point to a new site that enables you to search for code inside MSDN. The site enables  you to search for code, and if you find something of interest, you can book mark it, or create a unique URL to the appropriate page. It’s clearly early days for this site. You can’t yet search for  code on the MSDN Forums, the MSDN Code Gallery or Codeplex.

Another downside – under Language, there’s no PowerShell. There’s Perl and Ruby and Python and C++ and  C#, etc – but no PowerShell. :-(  You can filter on PowerShell and find some PowerShell related code. Shame no one in MSDN recognises PowerShell as a language!

Technorati Tags: ,

Friday, December 26, 2008

Enums, Enum values and PowerShell

 

I’ve been reading Jeffrey Snover's discussions on ENUMs over on the PowerShell Team blog (here, and here). I knew most of this stuff and have  been playing with Enums and PowerShell for a while. I’ve created a bunch of sample scripts I’ve uploaded both to the MDSN Wiki and to my PowerShell Scripts blog. This morning, I stumbled upon an interesting use of Enums – parsing strings into Integer values, as shown on the MSDN Library at http://msdn.microsoft.com/en-us/library/system.globalization.numberstyles.aspx.

Effectively want I wanted to do was to convert the following C# code to PowerShell:

  1. // Parse the string, allowing a leading sign, and ignoring leading and trailing white spaces. 
  2. num = "    -45   "
  3. val = int.Parse(num, NumberStyles.AllowLeadingSign |  
  4.      NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite); 
  5. Console.WriteLine("'{0}' parsed to an int is '{1}'.", num, val); 

Initially, I could not work out how to use the enums  (In System.Globalization.NumberStyles). Thanks to Shay Levy, it turns out to be remarkably easy (although not quite as succinct as in C'#). Basically, in true PowerShell style, every enum value is just an object. Objects have properties, and one property of an enum value is “value__” as demonstrated here:

PSH [D:\foo]: [System.Globalization.NumberStyles]::AllowLeadingSign
AllowLeadingSign
PSH [D:\foo]: [System.Globalization.NumberStyles]::AllowLeadingSign | gm

   TypeName: System.Globalization.NumberStyles

Name        MemberType   Definition
----        ----------   ----------
CompareTo   Method       System.Int32 CompareTo(Object target)
Equals      Method       System.Boolean Equals(Object obj)
GetHashCode Method       System.Int32 GetHashCode()
GetType     Method       System.Type GetType()
GetTypeCode Method       System.TypeCode GetTypeCode()
ToString    Method       System.String ToString(), System.String ToString(String format, IFormatPr...
value__     Property     System.Int32 value__ {get;set;}
MSDN        ScriptMethod System.Object MSDN();

PSH [D:\foo]: [System.Globalization.NumberStyles]::AllowLeadingSign.value__
4
PSH [D:\foo]:

As you can see from this output, the enum [System.Globalization.NumberStyles]::AllowLeadingSign displays normally the value “AllowLeadingSign” , but if you use the .value__ property on this enum value, you get back a number – in this case a decimal 4 (0x0004). You can then combine these as follows to convert the above C# Code into PowerShell:

  1. $num = " -45 "
  2.   $val = [system.int32]::Parse($num, 
  3.                [System.Globalization.NumberStyles]::AllowLeadingSign.value__ + 
  4.                [System.Globalization.NumberStyles]::AllowLeadingWhite.value__ + 
  5.                [System.Globalization.NumberStyles]::AllowTrailingWhite.value__) 
  6. "'{0}' parsed to an int is '{1}'." -f $num, $val 

Thanks to Shay Levy for his post in the PowerShell newsgroup for helping me to work this out. FWIW: you can the results of this up on the MSDN Library and on my PowerShell Scripts blog.

 

Thursday, December 25, 2008

Merry Christmas

Today is Christmas day and I’m away from the computer, enjoying Christmas dinner with my wife and daughter – I’m off the grid! As is our tradition, we’ll start with a nice bottle of Champagne and some smoked salmon. Then a bottle of Opus 1, with some cold roast duck, along with roasted turkey and roasted boneless chicken. We’ll finish up with some pudding and a nice bottle of vintage port. If anyone’s in the area and is not driving, they would be most welcome – I’d be happy to open up another bottle or two should that prove needed!

There’s no real PowerShell content today, but in keeping with the spirit of the season, there’s a fun PowerShell script up on PowerShell.Com to keep you amused. Enjoy.

And for the real hard-core PowerShell Addict, I’ll be posting tomorrow with some interesting stuff I discovered about using Enums and .NET. Stay tuned.

Merry Christmas and Seasons Greetings to you all.

Windows PowerShell Holiday Gift Guide

From the PowerShell Scripting Guys team comes this Windows PowerShell Holiday Gift Guide.

Merry Christmas!

 

Technorati Tags:

Wednesday, December 24, 2008

PowerShell – Online Virtual Lab

Microsoft TechNet has produced an on-line Virtual Lab on PowerShell.

The lab, which lasts up to 2 hours 50 minutes, covers the following topics:

  • PowerShell Variables
  • Branching and Script Blocks
  • Looping, Functions, and Filters
  • WMI Scripting
  • .NET Forms with Windows PowerShell
  • Visual Basic scripting functionality within PowerShell
  • PowerShell and Active Directory Domain Services
  • PowerShell scripting to reset a ADDS user password
  • Remote management using PowerShell
  •  

    If you are unfamiliar with PowerShell, or if you want to dig a bit deeper into some of these areas, then head on over. It takes a minute or two for the TechNet Virtual Lab to come up, but once it does, you’re presented with a screen like this:

    image

    This lab is based on PowerShell 1.0 (although everything in the lab should work fine with PowerShell V2.0).

    Technorati tags: , ,

    Tuesday, December 23, 2008

    Tweet Grid For PowerShell

    Now this is neat - Tweet Grid, a page that shows recent posts about PowerShell, side by side with CTP3. It looks like this:

    image

    The page auto updates, so you can see new Tweets as they come in. I will be using this page a lot over the coming days to monitor the Twitter-sphere reaction to CTP 3.

    One minor issue – the right hand pane is searching just for the phrase “CTP3” – which could also be some other product, or a part of a URL. While most tweets are relevant, a few aren’t. A slightly improved URL is here.

    Technorati Tags: ,,,

    Windows PowerShell V2 CTP3 Arrives!!

    Well –this is cool and a tad unexpected. In a recent post, I noted that I’d heard PowerShell had been delayed till the new year. Well, that’s WRONG. It released last night, as explained over on the PowerShell Team blog.

    image

    image

    You can get PowerShell from the MS download site. And if you plan to use remoting (one of the key features of PowerShell V2, you’ll also need WinRM which you can also download from Microsoft connect.

    Let the fun begin!

     

    Technorati Tags: ,,

    Monday, December 22, 2008

    PowerShell and Clustering in Server 2008 R2

    Just read an interesting blog article over on the Clustering and High Availability blog written by Symon Perriman a program manager for clustering and high availability. The article, entitled PowerShell for Failover Clustering in Windows Server R2, discusses the clustering team’s intention to use PowerShell as the scripting language for clustering technologies in Server 2008 R2.

    If you are a clustering person, you should check this article out – it documents that the team will deliver over 60 cmdlets to manage clustering. There will also be a custom console, as shown in the blog article.

    It looks like the Windows team(s) now finally get PowerShell!

    Sunday, December 21, 2008

    PowerShell Twitterers

    If you are in to Twitter, and into PowerShell –here's a list of PowerShell Twitterers. It appears to be relatively up to date!  The list was created by Steven Murawski, a US based PowerShell guy.

    Technorati Tags: ,

    Saturday, December 20, 2008

    PowerShell Scripts Blog now features on PowerShell.com

    Tobias and the cool folks from Idera are behind the PowerShell.Com community site. They’ve just added my PowerShell Scripts Blog (http://pshscripts.blogspot.com) to their featured blogs list.
    Yeah!  So come on over and join the community!

    Friday, December 19, 2008

    Pipes: PowerShell Bloggers – Broken?

    Jaykul has created a pretty cool Yahoo Pipe application (PowerShell Bloggers). However, today it seems to be not working – I am getting the error message: The Pipes engine request failed (504). :-(

    This is a shame as the application is pretty useful in keeping up with PowerShell bloggers. Hopefully it will get fixed soon.

     

    [Later]

    It’s now working again! And along with it is the news that today should see CTP 3! Yeah!!

    Technorati Tags: ,,

    Thursday, December 18, 2008

    Windows 7 Info - WinHEC 2008 White Papers

    Microsoft has published a number of White Papers on various aspects of  Windows 7 (including Windows Server 7). These White papers come from Microsoft’s Windows Hardware Engineering Conference (aka WINHEC). You can get the papers here.

     

    Technorati tags: , ,

    Steve Dunn's Code Formatter for Windows Live Writer Breaks New Live Writer Version

    I use the code formatter from Steve Dunn's web site to format code on my PowerShell Scripts Blog. Having just updated my main workstation to use the latest version of Windows Live Writer, I find the current version of the formatting tool (1.0.0.4) now breaks using the latest version of  Live Writer.

    Until I find a fix, I am falling back on the On-line Syntax Highlighter tool I posted about yesterday.

    [Later]

    I’ve had mail from Steve – he’s found the problem and will have a fix up shortly.What great service – thanks!!

    Wednesday, December 17, 2008

    Online Syntax Highlighting for Powershell

    If you are posting PowerShell code sample and want to format the text nicely, there’s an on-line high-lighter tool that will do this for you available here.

    This formatting tool is pretty nice. Consider the following script (from http://pshscripts.blogspot.com):

    # Parse and TryParse static methods on Int64 type # Sample using PowerShell # Thomas Lee - tfl@psp.co.uk

    # Create an int64 and two strings $i=new-object system.int64 "varable `$i created - type is {0}" -f $i.GetTypeCode() $s1="1234" $s2="12345678934212321212"

    # Use the Parse static method on S1 that WILL work OK $i=[system.int64]::parse($s1) "The integer `$i={0} - parsed OK as Int64" -f $s1 ""

    # Use the TryParse static method with small and too large a number $result=[system.int64]::tryparse($s1,[ref] $i) "The string `"{0}`" parsed correctly as an int64: {1}" -f $s1,$result $result=[system.int64]::tryparse($s2,[ref] $i) "The string `"{0}`" parsed correctly as an int64: {1}" -f $s2,$result

    Using the online Highligher tool creates HTML you can cut/past into your web site, thus you end up with something that looks like this:

    1. # Parse and TryParse static methods on Int64 type
    2. # Sample using PowerShell
    3. # Thomas Lee - tfl@psp.co.uk
    4. # Create an int64 and two strings
    5. $i=new-object system.int64
    6. "Variable `$i created - type is {0}" -f $i.GetTypeCode()
    7. $s1="1234"
    8. $s2="12345678934212321212"
    9. # Use the Parse static method on S1 that WILL work OK
    10. $i=[system.int64]::parse($s1)
    11. "The integer `$i={0} - parsed OK as Int64" -f $s1
    12. ""
    13. # Use the TryParse static method with small and too large a number
    14. $result=[system.int64]::tryparse($s1,[ref] $i)
    15. "The string `"{0}`" parsed correctly as an int64: {1}" -f $s1,$result
    16. $result=[system.int64]::tryparse($s2,[ref] $i)
    17. "The string `"{0}`" parsed correctly as an int64: {1}" -f $s2,$result

    The Highlighter tool can create the HTML fragement with or without a link to a CSS style sheet. In using this tool with Live Writer to produce this blog posting there seems to be little difference. To demonstrate this point, here’s the code without a CSS link:

    1. # Parse and TryParse static methods on Int64 type
    2. # Sample using PowerShell
    3. # Thomas Lee - tfl@psp.co.uk
    4. # Create an int64 and two strings
    5. $i=new-object system.int64
    6. "varable `$i created - type is {0}" -f $i.GetTypeCode()
    7. $s1="1234"
    8. $s2="12345678934212321212"
    9. # Use the Parse static method on S1 that WILL work OK
    10. $i=[system.int64]::parse($s1)
    11. "The integer `$i={0} - parsed OK as Int64" -f $s1
    12. ""
    13. # Use the TryParse static method with small and too large a number
    14. $result=[system.int64]::tryparse($s1,[ref] $i)
    15. "The string `"{0}`" parsed correctly as an int64: {1}" -f $s1,$result
    16. $result=[system.int64]::tryparse($s2,[ref] $i)
    17. "The string `"{0}`" parsed correctly as an int64: {1}" -f $s2,$result
    Technorati Tags: ,

    WireShark Training – part 3

    Those nice folks at Network Protocol Specialists have part three of their WireShark training today. The webcast starts in a few hours – see https://www1.gotomeeting.com/register/415806842 to register.

    This week’s webcast convers separating ‘good’ traffic from ‘bad’ traffic. The webcast is an hour long.

    If you miss the web cast, then there will be a recorded version you can download.

    Technorati Tags: ,,

    Tuesday, December 16, 2008

    PowerShell CZ – Another PowerShell blog (In Czech)

    Sadly, I don’t speak Czech – if I did, the PowerShell CZ blog would be more useful. Nevertheless, some of the articles are clear enough to PowerShell folks – just look at the code posted in the article. I tried the translator at www.tranexp.com, but the results were not very good.
    Maybe the author could be persuaded to translate into English?
    Technorati Tags: ,

    PowerShell CTP 3 Coming soon – But How Soon is Soon?

    In an article posted during TechEd Barcelona, I suggested that PowerShell CTP 3 was coming “soon”. The statements from the MS folks suggested that “soon” would be “early December”. I joked last week that I did not ask which December. :-)

    I can see from hits to this blog that many folks are trying to find this update or more information on it. I’m sorry to disappoint those visitors to this blog, but it looks like CTP 3 is delayed (again). I’m now hearing on the grapevine that CTP3 will not now come this year, but will come sometime in January in concert with the Windows 8 beta.

    Of course, this information could be wrong too. MS could decide to release it today (if only to prove this post wrong).We will just have to wait and find out. I’m accurate, then you heard it here first. And if I’m wrong, well, this blog post is just one more in a set of unsubstantiated and incorrect rumours about when CTP3 will hit. :-)

    But whatever, I know two things. First, CTP3 will rock whenever it’s released. Second, no matter how late, CTP3 is worth waiting for. I also recognise that despite being very late, PowerShell Version 2 is really going to be a world beating release. I can’t wait. I’ll be posting a lot more both here and on my PowerShell Scripts blog as soon as the new release if available.

    Technorati Tags: ,,

    Windows Live Writer and Messenger – Working on Server 2008!

    Like many techies I know, I use Windows Server 2008 as my main workstation OS. I find it much more stable than any other MS OS, with none of the consumer gimmicks of Vista. I am very happy with using Server 2008 – I get all the useful features of Vista, plus I get key features like Hyper-V, SMTP Server, and DFS. It rocks! My new laptop (due “soon”) will also be tricked out this way!

    Out of the box, of course, it’s a server OS, and not a desktop OS. But Google to the rescue – there are several sites that tell you how to trick out Server 2008 to run as a workstation. The site I’m using at present is http://www.win2008workstation.com/wordpress/. I’m very happy with the end results and would not ever consider moving back to either XP or Vista.

    As an aside, I think there’s a market here for a workstation class OS – in effect what I have running now. Tools like DFS, or more importantly Hyper-V are are needed for a small but important set of users. A workstation OS would put (client) Windows on a better footing against Linux/Unix OSs which allow these sorts of tools. Instead of having upteen home versions of Win7, why not have a Windows 7 Professional Workstation edition? Slug it with limited inbound connections (say 25 vs 10 for client), and don’t allow some features like being a DC. You could even call this Windows 7 Ultimate and have the term “ultimate” actually mean something other than just being misleading marketing waffle.

    One of the (very few!) problems I’ve had up to now is that Windows Live Writer and Windows Live Messenger did not install since the OS version is not supported. I really like Live Writer, and use it on all three of my blogs (here, here and here) as the main tool for adding blog posts.

    On Sunday, on the very long flight from Bangalore back home (an 11 hour flight, with two unscheduled stops was 11 hours late into LHR!), I had a brain spark. I guess 5 hours on the ground in Baku with no drink or food tends to do that! The idea was very simple: just use the compatibility tab on the program installer and tell the OS to lie to the installer as shown here:

    image

    After selecting Windows XP SP2, click OK and then run the setup program. On my system, it took another 2-3 minutes and I now have Live Messenger and Live Writer working perfectly.

    Thanks to the Application Compatibility team at Microsoft for helping out!

    Monday, December 15, 2008

    .NET and PowerShell

    This week, Jeffrey Snover has posted an excellent post, Explore Your [Environment], that examines both some of the details of the [System.Environment] class but also on how PowerShell integrates with .NET. As I said in a comment on the blog, I wish I’d seen this post many years ago, as I struggled in the early days to understand how you could reach into .NET with PowerShell.

    As Jeffrey describes, the .NET class has thousands of types, or types of objects. For example, System.Int32, a 32-bit integer. To access this type in Powerhell, simply enclose the type name in square brackets, as follows:

    PS C:\Users\tfl> [system.int32] IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Int32 System.ValueType

    You can also pipe the class to Get-Member to discover some of the properties and methods this type supports, as follows:

    PS C:\Users\tfl> [system.int32] | get-member TypeName: System.RuntimeType Name MemberType Definition ---- ---------- ---------- Clone Method System.Object Clone() Equals Method System.Boolean Equals(Object obj), System.Boolean Equals(Type o) FindInterfaces Method System.Type[] FindInterfaces(TypeFilter filter, Object filterCriteria) FindMembers Method System.Reflection.MemberInfo[] FindMembers(MemberTypes memberType, Binding... GetArrayRank Method System.Int32 GetArrayRank() GetConstructor Method System.Reflection.ConstructorInfo GetConstructor(BindingFlags bindingAttr,... GetConstructors Method System.Reflection.ConstructorInfo[] GetConstructors(BindingFlags bindingAt... GetCustomAttributes Method System.Object[] GetCustomAttributes(Boolean inherit), System.Object[] GetC... GetDefaultMembers Method System.Reflection.MemberInfo[] GetDefaultMembers() GetElementType Method System.Type GetElementType() GetEvent Method System.Reflection.EventInfo GetEvent(String name, BindingFlags bindingAttr... GetEvents Method System.Reflection.EventInfo[] GetEvents(BindingFlags bindingAttr), System.... GetField Method System.Reflection.FieldInfo GetField(String name, BindingFlags bindingAttr... GetFields Method System.Reflection.FieldInfo[] GetFields(BindingFlags bindingAttr), System.... GetGenericArguments Method System.Type[] GetGenericArguments() GetGenericParameterConstraints Method System.Type[] GetGenericParameterConstraints() GetGenericTypeDefinition Method System.Type GetGenericTypeDefinition() GetHashCode Method System.Int32 GetHashCode() GetInterface Method System.Type GetInterface(String fullname, Boolean ignoreCase), System.Type... GetInterfaceMap Method System.Reflection.InterfaceMapping GetInterfaceMap(Type ifaceType) GetInterfaces Method System.Type[] GetInterfaces() GetMember Method System.Reflection.MemberInfo[] GetMember(String name, MemberTypes type, Bi... GetMembers Method System.Reflection.MemberInfo[] GetMembers(BindingFlags bindingAttr), Syste... GetMethod Method System.Reflection.MethodInfo GetMethod(String name, BindingFlags bindingAt... GetMethods Method System.Reflection.MethodInfo[] GetMethods(BindingFlags bindingAttr), Syste... GetNestedType Method System.Type GetNestedType(String fullname, BindingFlags bindingAttr), Syst... GetNestedTypes Method System.Type[] GetNestedTypes(BindingFlags bindingAttr), System.Type[] GetN... GetObjectData Method System.Void GetObjectData(SerializationInfo info, StreamingContext context) GetProperties Method System.Reflection.PropertyInfo[] GetProperties(BindingFlags bindingAttr), ... GetProperty Method System.Reflection.PropertyInfo GetProperty(String name, BindingFlags bindi... GetType Method System.Type GetType(), System.Type GetType() InvokeMember Method System.Object InvokeMember(String name, BindingFlags bindingFlags, Binder ... IsAssignableFrom Method System.Boolean IsAssignableFrom(Type c) IsDefined Method System.Boolean IsDefined(Type attributeType, Boolean inherit) IsInstanceOfType Method System.Boolean IsInstanceOfType(Object o) IsSubclassOf Method System.Boolean IsSubclassOf(Type type) MakeArrayType Method System.Type MakeArrayType(), System.Type MakeArrayType(Int32 rank) MakeByRefType Method System.Type MakeByRefType() MakeGenericType Method System.Type MakeGenericType(Type[] instantiation) MakePointerType Method System.Type MakePointerType() ToString Method System.String ToString() Assembly Property System.Reflection.Assembly Assembly {get;} AssemblyQualifiedName Property System.String AssemblyQualifiedName {get;} Attributes Property System.Reflection.TypeAttributes Attributes {get;} BaseType Property System.Type BaseType {get;} ContainsGenericParameters Property System.Boolean ContainsGenericParameters {get;} DeclaringMethod Property System.Reflection.MethodBase DeclaringMethod {get;} DeclaringType Property System.Type DeclaringType {get;} FullName Property System.String FullName {get;} GenericParameterAttributes Property System.Reflection.GenericParameterAttributes GenericParameterAttributes {g... GenericParameterPosition Property System.Int32 GenericParameterPosition {get;} GUID Property System.Guid GUID {get;} HasElementType Property System.Boolean HasElementType {get;} IsAbstract Property System.Boolean IsAbstract {get;} IsAnsiClass Property System.Boolean IsAnsiClass {get;} IsArray Property System.Boolean IsArray {get;} IsAutoClass Property System.Boolean IsAutoClass {get;} IsAutoLayout Property System.Boolean IsAutoLayout {get;} IsByRef Property System.Boolean IsByRef {get;} IsClass Property System.Boolean IsClass {get;} IsCOMObject Property System.Boolean IsCOMObject {get;} IsContextful Property System.Boolean IsContextful {get;} IsEnum Property System.Boolean IsEnum {get;} IsExplicitLayout Property System.Boolean IsExplicitLayout {get;} IsGenericParameter Property System.Boolean IsGenericParameter {get;} IsGenericType Property System.Boolean IsGenericType {get;} IsGenericTypeDefinition Property System.Boolean IsGenericTypeDefinition {get;} IsImport Property System.Boolean IsImport {get;} IsInterface Property System.Boolean IsInterface {get;} IsLayoutSequential Property System.Boolean IsLayoutSequential {get;} IsMarshalByRef Property System.Boolean IsMarshalByRef {get;} IsNested Property System.Boolean IsNested {get;} IsNestedAssembly Property System.Boolean IsNestedAssembly {get;} IsNestedFamANDAssem Property System.Boolean IsNestedFamANDAssem {get;} IsNestedFamily Property System.Boolean IsNestedFamily {get;} IsNestedFamORAssem Property System.Boolean IsNestedFamORAssem {get;} IsNestedPrivate Property System.Boolean IsNestedPrivate {get;} IsNestedPublic Property System.Boolean IsNestedPublic {get;} IsNotPublic Property System.Boolean IsNotPublic {get;} IsPointer Property System.Boolean IsPointer {get;} IsPrimitive Property System.Boolean IsPrimitive {get;} IsPublic Property System.Boolean IsPublic {get;} IsSealed Property System.Boolean IsSealed {get;} IsSerializable Property System.Boolean IsSerializable {get;} IsSpecialName Property System.Boolean IsSpecialName {get;} IsUnicodeClass Property System.Boolean IsUnicodeClass {get;} IsValueType Property System.Boolean IsValueType {get;} IsVisible Property System.Boolean IsVisible {get;} MemberType Property System.Reflection.MemberTypes MemberType {get;} MetadataToken Property System.Int32 MetadataToken {get;} Module Property System.Reflection.Module Module {get;} Name Property System.String Name {get;} Namespace Property System.String Namespace {get;} ReflectedType Property System.Type ReflectedType {get;} StructLayoutAttribute Property System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute... TypeHandle Property System.RuntimeTypeHandle TypeHandle {get;} TypeInitializer Property System.Reflection.ConstructorInfo TypeInitializer {get;} UnderlyingSystemType Property System.Type UnderlyingSystemType {get;}

    As you can see, the System.INT32 class has a number of methods and properties. A method is something you can invoke to do something on the object, for example ToString() produces a string representing the value of the system.int32. A property is some attribute of the type, for example Name which is the name of the object. Within .NET there are two types of methods: static and object. Object methods are methods that you can invoke on a particular occurrence of a type. The ToString() method, for example, converts a specific System.Int32 to a string while TryParse() takes a value and sees if it will fit inside a 32-bit integer vaue. Static methods are methods that the class provides but that are not tied to a specific instance of a class. Classes can also have static fields, or values you can use in a PowerShellscript. In the case of system.int32, there are two static fields MaxValue and MinValue.

    Here is a look at the TryParse static method, the ToString object method, plus the two static fields.

    PS C:\Users\tfl> $ok=1 PS C:\Users\tfl> [system.int32]::tryparse("12345",[ref] $ok) True PS C:\Users\tfl> [system.int32]::tryparse("1234567890123",[ref] $ok) False PS C:\Users\tfl> (23456).tostring() 23456 PS C:\Users\tfl> [system.int32]::maxvalue 2147483647 PS C:\Users\tfl> [system.int32]::minvalue -2147483648

    To see the static methods, object methods and object properties, you can use Get-Member or for fuller information, see the MSDN Library documentation on-line. To find this imploration simply, just Google for the type name (enclosed in square brackets) – this should show a link to the class definition as the first result, from which you can drill down to see more details about the class.

    Technorati Tags: ,

    Monday, December 08, 2008

    PowerShell WMI Based Audit Script

    I’ve been writing about WMI and PowerShell of late – and notices this cool PowerShell Audit Script on Alan Renouf’s Virtu-Al’s blog. It’s not a particularly new post, but the result if pretty awesome. It produces a nice rich HTML file as output that looks a bit like this:

    image

    A great demonstration of what you can get from WMI plus what you can do with HTML in PowerShell

    Technorati tags: ,

    Sunday, December 07, 2008

    PowerScripting Podcast

    For those of you who like podcasts and PowerShell, take a look at the PowerScripting Podcast site. These podcasts are primarily all about PowerShell and air weekly. The last episode (their 50th!!) featured Ed Wilson, who wrote PowerShell Step-by-Step.

    You can listen to them online. Or you can do as I do and subscribe to them and get them downloaded to my Zune (or your IPOD via I-Tunes). Using my Zune software, I just add the feed from http://feeds.feedburner.com/PowerScripting. I’ve got the last few podcasts loaded up and will be listening to them on my long flight to India.

    Technorati Tags: ,

    Windows PowerShell Scripting Guide - DON’T DOWNLOAD THIS

    I just got a Google alert showing where I could download a free copy of the Windows PowerShell Scripting Guide. However, the download contains a Trojan!

    Be careful and avoid http: //download-apps.net/2008/11/28/windows-powershell-scripting-guide.html.

    [Later]

    Thanks to Halr9000, who noted that Blogger had "helpfully" added in a hyperlink to the above content. Hyperlink now gone.

    Technorati tags: , ,

    Saturday, December 06, 2008

    Discovering WMI using Windows PowerShell

    Around 2 1/2 years ago, I wrote a blog item entitled Discovering Networking with Monad and MSH where I looked at some aspects of WMI and how to discover more. Since then, I’ve published a few more articles on WMI.

    The key thing for IT Pros to understand is that WMI is both a friend and other folks’ friend. What I meant by that is that WMI was built to be an interface. And for Microsoft, that means developer focused. WMI was the way for one application to surface management information and for other applications to leverage that information. This enables tools such as SCCM (aka SMS) to do such cool things.

    But with PowerShell, the various classes of information are but a simple command away. The key is the GET-WmiObject cmdlet. This cmdlet enables you to retrieve any WMI class and access both its properties and methods and that means considerable power. PowerShell also provides WMI type accelerators, such as [WMI] that further simplify the use of WMI.

    So how does an IT Pro get started. The first thing, I suppose is to understand how WMI is structured. To simplify, WMI is implemented on a host. On that host, there is a set of information that is organised with a hierarchical namespace which breaks up the information in a structured manner. In each Node of the WMI namespace, you’ll find a number of classes. Each class has a definition (what it should/can contain) and instances. Each instance of a class represents a real-world occurrence of that object. The class and hence the instance contains properties and methods. You can use the properties for reporting and can also update the values of these properties for any instance (and create and manipulate new instances). Instances (and the class) contain methods that you can call to get an instance to do something. The details of the namespaces, classes, properties and methods are described on MSDN.

    With PowerShell, however the best place to start is with MOW’s most excellent WMI Explorer. This tool is incredibly cool. First, because it’s written all in PowerShell, but more importantly, because it’s the best browser I’ve seen. It’s a big PowerShell script – when you run it, you can open WMI on a system and browse the namespaces. In each namespace node you can look at the classes in that node. And for each class, you can simply see both the existing instances as well as the definition of that class. Here’s a screen shot of this tool running on one of my workstations:

    image

    As an IT Pro, you should download WMI Explorer and explore. I’ll be posting more on WMI and PowerShell coming up.

    Technorati Tags: ,,

    Friday, December 05, 2008

    Get-Process Produces Negative Numbers

    I saw an interesting item over on the PowerShell newsgroup today. The poster was using Get-Process on an X64 system and was seeing negative numbers in the Working Set column against the SQL Server. The answer was a simple one, as it turns out.

    The Get-Process cmdlet returns [System.Diagnostics.Process] objects, but with some added members – the cmdlet in effect expands the objects for PowerShell. Specifically, the Cmdlet adds 6 Alias Properties that are aliased to other properties in the [System.Diagnoistics.Process] Class:

    • Handles = Handlecount
    • Name = ProcessName
    • NPM = NonpagedSystemMemorySize
    • PM = PagedMemorySize
    • VM = VirtualMemorySize
    • WS = WorkingSet

    This makes life easier for the admin who can use the shorter Alias property names, et:

    $process = “*SQL"*”
    GPS $process | ft name, ws -auto

    The reason the poster was seeing negative numbers is fairly simple: the WS property is aliased to WorkingSet, but WorkingSet is a 32-bit value. In the poster’s case, the working set size overflowed the 32-bit value, resulting in a negative number being displayed. The solution is fairly simple if you look at the class’s Property details: use a different property which contains a 64- bit value. The class has several 64-bit properties:

    • NonpagedSystemMemorySize64
    • PagedMemorySize64
    • VirtualMemorySize64
    • WorkingSet64

    So the solution was easy – just use:

    $process = “*SQL"*”
    GPS $process | ft name, workingset64 –auto

    The maximum size of an Int32 is 2**32, meaning the maximum size of the WS/WorkingSet property is 4GB. Thus this problem can never occur on an I386 system since on i386, processes have a maximum size of 4GB, But as x64 becomes more common, and from Server 2008 R2 becomes the norm, this problem will grow.

    Interestingly, in the API documentation MIcrosoft now state that the 32-bit values are obsolete. You could argue this is a bug in PowerShell. For PowerShell V2, Microsoft really should change the WS and other AliasProperties to alias the 64-bit properties. For CTP2, this has not been done.

    Thursday, December 04, 2008

    Oblong's g-speak: the 'Minority Report' OS brought to life

    Just one word: cool

    Open XML with FireFox

    Microsoft as announced the availability of Open XML Document viewer plug-in for FireFox. This provides a light-weight way to view OOXML document (i.e. .docx, .xlsx, etc) documents from within FireFox.

    These plugins are available from Codeplex at: http://www.codeplex.com/OpenXMLViewer. This page has a good description of the high level architecture, a cool-ish 4-minute video demo of the translation and the FireFox plugins.  There’s also a link to the download, including viewers for Windows and Linux versions of FireFox.

    The Windows download is fairly big – 3.5MB – indicating the complexity of the underlying code. To install the plugin, just expand the .ZIP download and drag/drop the XPI to FireFox, restarting FireFox to complete the installation. After installation, it looks like this:

    image

    The viewer is a CodePlex project (and not a formal Microsoft project), and the videos are YouTubed not available directly from Microsoft. An interesting approach – pragmatic to say the least (plus  google gets to pay for the bandwidth used to view the videos).

    Also, these viewers are at present just a Community technology Preview and not fully ready for release. Final release will come in the spring of 2009.

    Technorati tags: , ,

    SQL Server and PowerShell

    Buck Woody presented a session at the recent PASS conference on PowerShell and SQL. Entitled “Advanced PowerShell for SQL Server”, the session looked at using PowerShell with SQL Server 2008. The presentation also included a bunch of demos of how to integrate PowerShell with SQL Server 2008.

    Buck has published a blog article about the talk, which includes a link to a download. The download contains the slides and two cool demo scripts. I’m going to try to get a SQL Server 2008 VM built to test these scripts out (and derive a few more).

    Buck’s blog, Carpe Datum, is an interesting read for SQL folks. And for those of you more PowerShell focused, you can use the tagging mechanism on the MSDN Blog site and view just those  entries that are PowerShell focused.

    Technorati tags: , ,

    Wednesday, December 03, 2008

    ICSharpCode’s SharpZipLib’s Help File

    In yesterday’s post, I described a cool Zip file Library from ICSharpCode and showed how you could use it within PowerShell. I noted it had a help file which would be of value when using this library. I spent some this morning playing with the Zip lib and wanted to see more details (i.e. from the help file).

    However, when I started playing with the help file, I just got lots of blank pages and no content – like this:

    image

    It It took me a few minutes to work out that it was Windows “helping” me by not showing any content since the file had been obtained from the Internet! The file was downloaded by Firefox and FireFox (like IE) adds a NTFS stream to the file to indicate it had been downloaded from the Internet. Since the file had been downloaded, IE rendered nothing on security grounds. Thanks but…

    Sysinternals to the rescue. I just used the Streams.exe utility to remove the added stream:

    image

    Once the additional data stream was removed, the help file worked great:

    image