views:

506

answers:

2

I should probably not ask a generic question with a specific example, but I have a hard time translating some basic commands from the PowerShell console to reusable functions and custom cmdlets. Is there a definitive guide to the syntax of PowerShell somewhere, with gotchas, hints and tips?

For instance, I'm trying to create a function in order to automate the administration of BizTalk Host instances. The following function does not work (fails at runtime) whereas each individual line works and performs as expected when individually pasted in a PowerShell console.

function AddNewHostInstance([string]$ServerName, [string]$HostName, [string]$Login, [string]$Password)
{
    [System.Management.ManagementObject]$objServerHost = `
        ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_ServerHost").CreateInstance()

    $objServerHost["ServerName"] = $ServerName
    $objServerHost["HostName"] = $HostName
    $objServerHost.Map()

    $name = "Microsoft BizTalk Server " + $HostName + " " + $ServerName

    [System.Management.ManagementObject]$objServerHost = `
        ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostInstance").CreateInstance()

    $objHostInstance["Name"] = $name
    $objHostInstance.Install($Login, $Password, $True)
}

By the way, the error I receive in this particular case is this one:

PS C:\Users\username> createHostInstances $server, $host, $user, $pwd
Exception calling "Map" : "Invalid parameter "
At line:14 char:39
+     $objServerHost.Map <<<< ()
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : WMIMethodException
Exception calling "Install" : "Instance of the WMI class is not found.
No instance was found with the specified key.  This could be the result of the instance being deleted by another BizTalk Admin session."
At line:19 char:29
+     $objHostInstance.Install <<<< ($Login, $Password, $True)
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : WMIMethodException
PS C:\Users\username>

[Edit] After further investigation, it seems that the function does not like assigning properties to WMI object via a variable. If I hardcode all values (instead of relying on the supplied function parameters), then it works as expected !

Basically, this works:

# Using hard-coded value
$objServerHost["HostName"] = "TestHost"

Whereas this, does not:

# Using function supplied parameter
$objServerHost["HostName"] = $HostName

Still, I don't understand why...

+4  A: 

As far as guides go, the best book out there is Windows PowerShell in Action by Bruce Payette. There is a second edition due in February but you can get early access to the electronic draft. There are also a couple of free books out there. Mastering PowerShell by Dr. Tobias Weltner and I also have a short < 60 pages eBook - Effective Windows PowerShell. This last one covers a number of gotchas as well as providing you with a mental model for how PowerShell works.

WRT the error, I wonder if you would have better luck using PowerShell's built-in support for WMI e.g.:

$namespace = 'root/MicrosoftBizTalkServer' 
$host = Get-WmiObject -namespace $namespace -class MSBTS_HostInstance

See if the resulting WMI object has the appropriate data & methods (Map & Install):

$host | fl *
$host | Get-Member
Keith Hill
+1 for a freely downloadable eBook.
Maxime Labelle
I think Get-WmiObject is only to retrieve existing objects. Can it be used to create new instances of WMI classes?
Maxime Labelle
A: 

Regarding the Map() error, sometimes with WMI you need to drop back and instead do $objServerHost.psbase.Invoke("Map"). Other than that, I've got a few sample PowerShell scripts for BizTalk administration you might find useful as guides.

tomasr
Unfortunately, this does not work in my case. I obtain an error "Method invocation failed because System.Management.Automation.PSInternalMemberSet does not contain a method name 'Invoke'".
Maxime Labelle
Thanks for the links ; I stumbled across them occasionnaly.
Maxime Labelle