mardi 8 avril 2008

PowerShell mindmap with Silverlight

Michael S. Scherotter gives us on his synergist blog an application that convert MindManager mindmap to Silverlight.

This is really fun to play with, and it gives inspiration on how to bind Silverlight to our day to day work with Infrastructure developpement ! :)

To illustrate this, I've inserted below a Silverlight Control with my personnal bookmarks about PowerShell. Blogger main frame isn't really wide, so please use the "Full screen" button to have a better look at this control. Notes are in French, I'll translate them soon. Links are all operational.
Have fun with Silverlight !


SCCM and PowerShell Part 2

SCCM and PowerShell Part 2

Add Computer to a specific collection

Ok, our computer is in SCCM, let see how to add it in a specific collection. What told the SDK ? the VBScript sample is :

' Add the computer to the all systems collection.
set collection = connection.Get("SMS_Collection.CollectionID='SMS00001'")
set collectionRule=connection.Get("SMS_CollectionRuleDirect").SpawnInstance_
collectionRule.ResourceClassName="SMS_R_System"
collectionRule.ResourceID= outParams.ResourceID
collection.AddMembershipRule collectionRule

We can reorganize the code as shown below to ease our understanding of the process :

set collectionRule=connection.Get("SMS_CollectionRuleDirect").SpawnInstance_ collectionRule.ResourceClassName="SMS_R_System" collectionRule.ResourceID= outParams.ResourceID

set collection = connection.Get("SMS_Collection.CollectionID='SMS00001'")
collection.AddMembershipRule collectionRule


This sample is about "All Systems" Collection, however this collection isn't really usefull because, as we saw in the previous part of this tutorial, when you add a computer in SCCM, it is added by default in this collection. But this example shows us usefull elements: we know that we need to create an "SMS_CollectionRuleDirect", fills some parameters, then invoke the Method "AddMemberShipRule" with this object as a parameter.

Let's go slowy, step by step...

Create an object from the SMS_CollectionRuleDirect class

With PowerShell, we can initialise an instance of a WMI like this :

$objColRuledirect = [WmiClass]"\\$Computer\ROOT\SMS\site_001:SMS_CollectionRuleDirect"

You can see the properties of this object with the psbase.properties :

In the SDK, we learned that 2 properties has to be filled :

  • ResourceClassName with value "SMS_R_System"
  • ResourceID with the ResourceID property of the computer object that we build in Part 1

So with PowerShell :

$objColRuleDirect.psbase.properties["ResourceClassName"].value = "SMS_R_System"
$objColRuleDirect.psbase.properties["ResourceID"].value = $objCMComputer.resourceID

As you can see below, the CollectionRuleDirect is now properly set with the ResourceID of the $objCMComputer (same as sample of Part 1) :

We need now to use this object with the AddMemberShipRule method

How to use the AddMemberShipRule Method of the SMS_Collection class

When we say "WMI Method", we call WmiExplorer in order to have à "pre-build" script sample :

What we see here is that we need the ID of the target collection. We have 2 options :

  • Using Hard-Coded Collection ID found in the SCCM console (smart)
  • Determine this ID with, for example, a collection Name (Smarter)

We are smart people, we will determine this ID with PowerShell!

It's really easy, just create a "classic" connexion to the SMS_Collection class, and filter it with our target collection name (in my example : "PowerShell Collection")

$Collection = gwmi -computer $computer -namespace "root\sms\site_001" -class "SMS_Collection" $PoshCollec = $collectionwhere{$_.Name -eq "PowerShell Collection"}

No difficult at all ! the last thing to do is adapt the WmiExplorer sample with the collectionID of this object, and use our previously build CollectionRuleDirect object :

$Class = "SMS_Collection"
$Method = "AddMembershipRule"
$CollectionID = $PoshCollec.CollectionID
$filter="CollectionID = '$CollectionID'"
$MC = Get-WmiObject $class -computer $Computer -Namespace "ROOT\SMS\site_001" -filter $filter
$InParams = $mc.psbase.GetMethodParameters($Method)
$InParams.collectionRule = $MCCollectionRuledirect
$inparams.PSBase.properties select name,Value Format-Table
$R = $mc.PSBase.InvokeMethod($Method, $inParams, $Null)

Work done : our computer is now in the "PowerShell Collection" collection.

With some R&D, and with a good understanding of these different examples, you are now able to create many kinds of PowerShell scripts with SCCM. Note that nearly all this samples can be used with SMS too !

Hope this helps you SCCM people, have a Ctrl+C below for a complete PowerShell sample script :

**************************************************************************

## Name : Add Computer to Collection SCCM PowerShell script
## Author : Antoine Habert
devinfra@gmail.com

### Variables
$strTargetMac = "0A:0B:0C:0D:0E:0F"
$strTargetComputerAccount = "NomDeMachine"
$computer = "."
$strTargetCollection = "La collection cible"

# Create computer in SCCM
$Class = "SMS_Site"
$Method = "ImportMachineEntry"
$MC = [WmiClass]"\\$Computer\ROOT\SMS\site_001:$Class"
$InParams = $mc.psbase.GetMethodParameters($Method)
$InParams.MACAddress = $strTargetMac
$InParams.NetbiosName = $strTargetComputerAccount
$InParams.OverwriteExistingRecord = $true
$inparams.PSBase.properties select name,Value Format-Table
$objCMComputer = $mc.PSBase.InvokeMethod($Method, $inParams, $Null)

# Create Collection Rule Direct
$objColRuledirect = [WmiClass]"\\$Computer\ROOT\SMS\site_001:SMS_CollectionRuleDirect"
$objColRuleDirect.psbase.properties["ResourceClassName"].value = "SMS_R_System"
$objColRuleDirect.psbase.properties["ResourceID"].value = $objCMComputer.resourceID


# Target Collection connection
$Collection = gwmi -computer $computer -namespace "root\sms\site_001" -class "SMS_Collection"
$PoshCollec = $collectionwhere{$_.Name -eq $strTargetCollection}

# Add Computer to Target Collection
$Class = "SMS_Collection"
$Method = "AddMembershipRule"
$CollectionID = $PoshCollec.CollectionID
$filter="CollectionID = '$CollectionID'"
$MC = Get-WmiObject $class -computer $Computer -Namespace "ROOT\SMS\site_001" -filter $filter
$InParams = $mc.psbase.GetMethodParameters($Method)
$InParams.collectionRule = $MCCollectionRuledirect
$inparams.PSBase.properties select name,Value Format-Table
$R = $mc.PSBase.InvokeMethod($Method, $inParams, $Null)

**************************************************************************

vendredi 4 avril 2008

SCCM and PowerShell Part 1

SCCM and PowerShell (Part 1)

Introduction

SCVMM and Exchange 2007 provide native cmdlets. SCCM doesn't, but does provide (nearly) everything with WMI. Let see how to use classes, methods and properties of SCCM with PowerShell.

Before we begin

To ease your life, 2 downloads are required :
Our First Script

There's some subtleties to know in order to use WMI methods exposed by SCCM with PowerShell.

Let first discover SCCM namespaces. Launch wmiexplorer.ps1 on your SCCM server :
The "ROOT\SMS" namespace is available, under it you'll see "ROOT\SMS\inv_schema" that we bypass for now, and another namespace called "ROOT\SMS\Site_NameOfSite"

DoubleClick on a Site namespace to list the classes

570 (!) classes will appear in the bottom left listbox. Yes, that's quite a lot, but take it cool because we will filter our search pretty easely as our needs arise.

For our first example, we will build a script that add a computer in a collection. Our first step is to look at the SDK chm file to find the proper class to do this task.


Here we see on the right side that, in order to add a computer, we should use the ImportMachineEntry classe of "SMS_Site" namespace. The SDK usually shows VB/C#/VBScript samples. The PowerShell syntax differs from this langage, but this doesn't really matters for our PowerShelled mind : we use the SDK only to know wich Methods/properties we need yo use.

In the VBscript sample of this SDK tip, we see that we need to use a "Connection.get" function to instance the class, then a SpawnInstance of the method, to finally add the required parameters (Mac Address, NetBiosName...). At last, we use ExecMethod to launch the process.

' Connect
Set siteClass = connection.Get("SMS_Site")
Set inParams = siteClass.Methods_("ImportMachineEntry"). _
inParameters.SpawnInstance_()

' Add the input parameters.
inParams.Properties_.Item("MACAddress") = macAddress
inParams.Properties_.Item("NetbiosName") = netBiosName
inParams.Properties_.Item("OverwriteExistingRecord") = False
inParams.Properties_.Item("SMBIOSGUID") = smBiosGuid

' Add the computer
Set outParams = connection.ExecMethod("SMS_Site", "ImportMachineEntry", inParams)

Here comes the real deal

How to do the same with PowerShell ?

Let use MoW's WmiExplorer to get our answer :


Double Click on the SMS_Site Class to list all properties and methods of the class. You'll see on the right panel that there's a Method called "ImportMachineEntry"

Now Double Click on this Method. Mow's WmiExplorer is a smart tool : it buil dynamically PowerShell sample to use the method as shown below :

Last but not least, it enumerate the different parameters of the script and the variable type (String, Boolean...)... Our remaining job is to populate these variables with appropriate values :
  • MacAddress (MAC Address of the target computer)
  • NetbiosName
  • ...
Let's get more in details in this script to understand the invocation process in PowerShell :

When we create a connection to the SMS_Site class and we display as shown above the $mc object, we only got "SMS_Site" in the console

If we use get-membere, we see that there isn't any "ImportMachineEntry" method here. This is due to the specific object output formatting of PowerShell. In order to access properties and methods of this class, we need to use the PSBASE method to have a "RAW" access on this object (more information on PSBASE here ) :


As we can see, $mc.psbase brings Methods and Properties. Now list methods :

We got here our "ImportMachineEntry" method. In the VBSCript sample in the SDK, they told us to use SpawnInstance to define parameters for this method :

Set inParams = siteClass.Methods_("ImportMachineEntry"). _
inParameters.SpawnInstance_()

inParams.Properties_.Item("MACAddress") = macAddress
inParams.Properties_.Item("NetbiosName") = netBiosName
inParams.Properties_.Item("OverwriteExistingRecord") = False
inParams.Properties_.Item("SMBIOSGUID") = smBiosGuid

To do the same thing in PowerShell, have a look at the Mow generated script :

$InParams = $mc.psbase.GetMethodParameters(“ImportMachineEntry”)

$InParams.MACAddress = [string]
$InParams.NetbiosName = [string]
$InParams.OverwriteExistingRecord = [boolean]
$InParams.SMBIOSGUID = [string]

As you can see, the code is rather simple : this example just do the same thing.

Have a more indepth look at the $inParams members :

We see here our 4 properties : MacAddress, NetbiosName, OverwriteExistingRecord and SMBIOSGUID, all empty. Notice that each properties Types are exposed in the definition column, and that they are all Read/Write (get;Set)

Great ! know let's write values for 3 of our properties (we don't need MSBIOSGUID if MacAddress is filled... XP is the key to discover this kind of funny details :) )


Sorting the Output of $Inparams, we see that our object's properties aren't empty anymore.

Now we need to execute our Method with the parameters. The VBScript sample said :


Set outParams = connection.ExecMethod("SMS_Site", "ImportMachineEntry", inParams)

With Powershell, Execution is handled as shown in the MoW Example :

$mc.PSBase.InvokeMethod($Method, $inParams, $Null)

Here we are ! Our Computer is properly import in SCCM. For now, only in the "All Systems" collection.
Image Hosted by ImageShack.us

The next step in the SDK is to add this machine to a specific collection. We will explain this in the Part 2 of this discussion.

You know now how to identify the class, method and properties to accomplish SCCM task in the SDK, and convert them in PowerShell. Have Fun !


Introduction

Hi !

I'll post here the translation of my french posts on devinfra.blogger.com. We will talk here about PowerShell, .NET, Silverlight development.

Have a nice reading :)