PowerShell & SCCM – Client

In the previous posts we created a new Package containing Windows PowerShell and distributed it to all all XP clients in the “All Windows XP Systems” Collection. Assuming that everything went OK the package should have been distributed and installed on the Client.

With Windows PowerShell installed on the Client we can manage the SMS Client using Windows PowerShell. In the Install.bat file used when installing the program we also enabled PowerShell remoting so we can run commands against the client remote. Here’s an example on how to connect to the Client remote.

PS > Enter-PSSession XP01.powershell.nu
[xp01.powershell.nu]: PS >

We can connect to the SMS Client using the Microsoft.SMS.Client COM Object as shown below.

PS > $smsClient = New-Object -ComObject Microsoft.SMS.Client

The COM Object supports a couple of methods that we can use to manage the SMS Client. We can display the properties by sending the object through a pipeline to the Get-Member cmdlet.

PS > $smsClient | Get-Member

   TypeName: System.__ComObject#{d535c884-6b82-47dd-9a15-

Name                           MemberType Definition
----                           ---------- ----------
AutoDiscoverSite               Method     string AutoDisc
ClearProxy                     Method     void ClearProxy
DiscoverDefaultMP              Method     string Discover
EnableAutoAssignment           Method     void EnableAuto
GetAssignedSite                Method     string GetAssig
GetCurrentManagementPoint      Method     string GetCurre
GetCurrentManagementPointEx    Method     void GetCurrent
GetDnsSuffix                   Method     string GetDnsSu
GetInternetManagementPointFQDN Method     string GetInter
GetProxy                       Method     void GetProxy (
IsClientAlwaysOnInternet       Method     int IsClientAlw
IsClientOnInternet             Method     int IsClientOnI
MSIReinstallClient             Method     uint MSIReinsta
ReAssignSite                   Method     string ReAssign
RemoveAssignedSites            Method     void RemoveAssi
ResyncPolicy                   Method     void ResyncPoli
SendClientAssignmentMessage    Method     void SendClient
SetAssignedSite                Method     void SetAssigne
SetClientProvisioningMode      Method     void SetClientP
SetCurrentManagementPoint      Method     void SetCurrent
SetDnsSuffix                   Method     void SetDnsSuff
SetInternetManagementPointFQDN Method     void SetInterne
SetProxy                       Method     void SetProxy (
UseAdminLocator                Method     void UseAdminLo

If we want to display the Assigned Site we use the GetAssignedSite() method.

PS > $smsClient.GetAssignedSite()

It’s also possible to change the Assigned Site using the SetAssignedSite() method. In the example below we change site from LAB to P01.

PS > $smsClient.SetAssignedSite("P01")
PS > $smsClient.GetAssignedSite()

We can even set the Current SMS Advanced Client Management Point using the SetCurrentManagementPoint() method. The method accepts an IP-Address followed by [int]1 or a Computer Name followed by [int]0.

PS > $smsClient.SetCurrentManagementPoint("SCCM",0)

It’s also possible to use the CPAppletMgr, which is a COM automation class that provides an automated way to perform the same tasks as the Configuration Manager program on the Client.

First we store the COM Object in a variable.

PS > $cpAppletMgr = New-Object -ComObject CPApplet.CPAppletMgr

We can display the supported methods using the Get-Member cmdlet as shown below.

PS > $cpAppletMgr | Get-Member

   TypeName: System.__ComObject#{279463bb-1034-4fb5-878e-4a330a08beab}

Name                MemberType Definition
----                ---------- ----------
GetClientActions    Method     IClientActions GetClientActions ()
GetClientComponents Method     IClientComponents GetClientComponents ()
GetClientProperties Method     IClientProperties GetClientProperties ()

Let’s take a look at the GetClientActions() method. If we simply use the method the available we get a list of the Client Actions available.

PS > $cpAppletMgr.GetClientActions()

ActionID                      Name                           DisplayNameResID DisplayNameResDLL
--------                      ----                           ---------------- -----------------
{00000000-0000-0000-0000-0... Software Inventory Collect...             10005 cfg_res.dll
{00000000-0000-0000-0000-0... MSI Product Source Update ...             10010 cfg_res.dll
{00000000-0000-0000-0000-0... Hardware Inventory Collect...             10001 cfg_res.dll
{00000000-0000-0000-0000-0... Software Updates Assignmen...             10011 cfg_res.dll
{00000000-0000-0000-0000-0... Standard File Collection C...             10006 cfg_res.dll
{00000000-0000-0000-0000-0... Updates Source Scan Cycle                 10013 cfg_res.dll
{00000000-0000-0000-0000-0... Discovery Data Collection ...             10004 cfg_res.dll
{3A88A2F3-0C39-45fa-8959-8... Request & Evaluate User Po...             10007 cfg_res.dll
{00000000-0000-0000-0000-0... Peer DP Maintenance Task                  10012 cfg_res.dll
{8EF4D77C-8A23-45c8-BEC3-6... Request & Evaluate Machine...             10008 cfg_res.dll
{00000000-0000-0000-0000-0... Software Metering Usage Re...             10009 cfg_res.dll

We can retrieve a specific Action using the Where-Object cmdlet. In the example below we retrieve the “Request & Evaluate Machine Policy” Action.

PS > $machinePolicy = $cpAppletMgr.GetClientActions() | 
>> Where-Object { $_.Name -eq "Request & Evaluate Machine Policy" }

Now that we’ve stored a specific Action in a variable we can simply use the PerformAction() method to perform the Action.

PS > $machinePolicy.PerformAction()

Pretty Cool!

Rating 4.33 out of 5

PowerShell & SCCM – Advertisement

In this post we’ll look at Advertisements in SCCM 2007. First we’ll retrieve an existing advertisement using PowerShell.

PS > $pkgAdobe = Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_Package WHERE Name = 'Adobe Reader'"

In the example above we use the SMS_Package Class to retrieve a specific Package, next we use the SPS_Advertisement and retrieve an Advertisement where the PackageID equals the one stored in $pkgAdobe.

PS > $advAdobe = Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_Advertisement WHERE PackageID = '$($pkgAdobe.PackageID)'"

Let’s check out some of the Advertisements Properties.

PS > $advAdobe | Select-Object AdvertFlags, DeviceFlags, RemoteClientFlags, SourceSite, TimeFlags

AdvertFlags       : 34603040
DeviceFlags       : 0
RemoteClientFlags : 8240
SourceSite        : LAB
TimeFlags         : 8193

In the example above we display the AdverFlags which indicates how the advertisement should be announced to the user, the DeviceFlags that describes the device (default value is 0), the RemoteClientFlags that specify how the program should run, the SourceSite and the TimeFlags which are reserved for internal use.

Now let’s see how we can create a new Advertisement. First we need to gather some information such as CollectionID, PackageID and ProgramName.

PS > $collectionID = (Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_Collection WHERE Name = 'All Windows XP Systems'").CollectionID
PS > $packageID = (Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select PackageID from SMS_Package WHERE Name = 'Windows PowerShell'").PackageID
PS > $prg = Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_Program WHERE PackageID = '$packageID'"

Next we store the arguments in a HashTable. Since many of the values (AdvertFlags, DeviceFlags, RemoteClientFlags and TimeFlags) can be a little hard to figure out we’ll use the “Adobe Reader” Advertisement as reference. (for more information on possible values check out this link).

PS > $arguments =
>> @{AdvertFlags = $advAdobe.AdvertFlags;
>> AdvertisementName = "PowerShell";
>> CollectionID = $collectionID;
>> PackageID = $packageID;
>> DeviceFlags = $advAdobe.DeviceFlags;
>> ProgramName = $prg.ProgramName;
>> RemoteClientFlags = $advAdobe.RemoteClientFlags;
>> SourceSite = $advAdobe.SourceSite;
>> TimeFlags = $advAdobe.TimeFlags
>> }

With the arguments prepared and ready we can go ahead and create a new Advertisement using the Set-WmiInstance Cmdlet and the SMS_Advertisement class.

PS > Set-WmiInstance -class SMS_Advertisement -arguments $arguments -namespace "root\SMS\Site_LAB"

__GENUS                 : 2
__CLASS                 : SMS_Advertisement
__SUPERCLASS            : SMS_BaseClass
__DYNASTY               : SMS_BaseClass
__RELPATH               : SMS_Advertisement.AdvertisementID="LAB20002"
__PROPERTY_COUNT        : 28
__DERIVATION            : {SMS_BaseClass}
__SERVER                : SCCM
__NAMESPACE             : root\SMS\Site_LAB
__PATH                  : \\SCCM\root\SMS\Site_LAB:SMS_Advertisement.AdvertisementID="LAB20002"
ActionInProgress        : 1
AdvertFlags             : 34603040
AdvertisementID         : LAB20002
AdvertisementName       : PowerShell
AssignedSchedule        : {}
AssignedScheduleEnabled : False
AssignedScheduleIsGMT   : False
AssignmentID            : 0
CollectionID            : SMS000ES
Comment                 :
DeviceFlags             : 0
ExpirationTime          : 19900101000000.000000+***
ExpirationTimeEnabled   : False
ExpirationTimeIsGMT     : False
HierarchyPath           :
IncludeSubCollection    : True
ISVData                 :
ISVDataSize             : 0
MandatoryCountdown      : 0
PackageID               : LAB00024
PresentTime             : 19900101000000.000000+***
PresentTimeEnabled      : True
PresentTimeIsGMT        : False
Priority                : 2
ProgramName             : PowerShell - Install
RemoteClientFlags       : 8240
SourceSite              : LAB
TimeFlags               : 24577

When we create a new advertisment using Windows PowerShell it’s placed in the default container. We can move the advertisement to a specific folder using the SMS_ObjectContainerItem class.

First we retrieve the Container Node using the SMS_ObjectContainerNode. Notice how we point out the Name and ObjectType in the WQL statement. ObjectType 3 equals SMS_Advertisement.

PS > $containerNode = Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_ObjectContainerNode WHERE Name = 'Applications' AND ObjectType = '3'"

We also need the Advertisements ID so we’ll go ahead and store it in a variable.

$advID = (Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select AdvertisementID from SMS_Advertisement WHERE AdvertisementName = 'PowerShell'").AdvertisementID

Next we store the arguments in a HashTable as shown below.

PS > $arguments = @{
InstanceKey = $advID;
ObjectType = 2;
ContainerNodeID = $containerNode.ContainerNodeID

Finally we use the SMS_ObjectContainerItem Class to move the Advertisement to a folder.

PS > Set-WmiInstance -Class SMS_ObjectContainerItem -arguments $arguments -namespace "root\SMS\Site_LAB"

__GENUS          : 2
__CLASS          : SMS_ObjectContainerItem
__SUPERCLASS     : SMS_BaseClass
__DYNASTY        : SMS_BaseClass
__RELPATH        : SMS_ObjectContainerItem.MemberID=138
__DERIVATION     : {SMS_BaseClass}
__SERVER         : SCCM
__NAMESPACE      : root\SMS\Site_LAB
__PATH           : \\SCCM\root\SMS\Site_LAB:SMS_ObjectContainerItem.MemberID=138
ContainerNodeID  : 12
InstanceKey      : LAB20002
MemberGuid       : 53D8BAD4-09D9-4304-9C24-65723453F6CD
MemberID         : 138
ObjectType       : 3
SourceSite       : LAB

If we take a look in the Configuration Manager Console now we’ll see that our Advertisement is created and in the correct folder

In the Next post we’ll take a look at how we can manage the SMS Client.

Rating 3.00 out of 5

PowerShell & SCCM – Distribution Point

We can use the SPS_DistributionPoint class to retrieve information about all or a specific distribution point in SCCM 2007 using Windows PowerShell. In the example below we first retrieve a Package and then use the PackageID to retrieve the Distribution Point associated with the Package.

PS > $pkgAdobe = Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_Package WHERE Name = 'Adobe Reader'"
PS > $distAdobe = Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_DistributionPoint WHERE PackageID = '$($pkgAdobe.PackageID)'"

Now we can use the variable to Display all or specific properties. In the example below we use the Select-Object cmdlet to display the ServerNALPath, SiteCode, SiteName and ResourceType. Each role (DP, PXE, SUP, MP etc) has a NAL Path. The NAL Path contains a netbiosName, SiteCode and a Path if its a Distribution Point. The ResourceType property displays the resource type of the distribution point.

PS > $distAdobe | Select ServerNALPath, SiteCode, SourceSite, SiteName, ResourceType

ServerNALPath : ["Display=\\SCCM\"]MSWNET:["SMS_SITE=LAB"]\\SCCM\
SiteCode      : LAB
SourceSite    : LAB
SiteName      : Lab Site
ResourceType  : Windows NT Server

Now let’s see how we can create a new Distribution Point. First we retrieve a specific PackageID which we will use when creating a new Distribution Point.

PS > $packageID = (Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select PackageID from SMS_Package WHERE Name = 'Windows PowerShell'").PackageID

PS > $arguments = @{
>> PackageID = $packageID;
>> ServerNALPath = '["Display=\\SCCM\"]MSWNET:["SMS_SITE=LAB"]\\SCCM\';
>> SiteCode = "LAB";
>> SiteName = "LAB Site";
>> SourceSite = "LAB";
>> ResourceType = "Windows NT Server"
>> }

Finally we use the Set-WmiInstance cmdlet to create a new Distribution Point as shown below.

PS > Set-WmiInstance -class SMS_DistributionPoint -arguments $arguments -namespace "root\SMS\Site_LAB"

__GENUS          : 2
__CLASS          : SMS_DistributionPoint
__SUPERCLASS     : SMS_BaseClass
__DYNASTY        : SMS_BaseClass
__RELPATH        : SMS_DistributionPoint.PackageID="LAB00024",ServerNALPath="[\"Display=\\\\SCCM\\\"]M
__DERIVATION     : {SMS_BaseClass}
__SERVER         : SCCM
__NAMESPACE      : root\SMS\Site_LAB
__PATH           : \\SCCM\root\SMS\Site_LAB:SMS_DistributionPoint.PackageID="LAB00024",ServerNALPath="
BitsEnabled      : False
IsFileStreaming  : False
IsPeerDP         : False
IsProtected      : False
ISVData          :
ISVDataSize      : 0
LastRefreshTime  : 19900101000000.000000+***
PackageID        : LAB00024
RefreshNow       : False
ResourceType     : Windows NT Server
ServerNALPath    : ["Display=\\SCCM\"]MSWNET:["SMS_SITE=LAB"]\\SCCM\
SiteCode         : LAB
SiteName         : LAB Site
SourceSite       : LAB
Status           : 2

If we take a look in the Configuration Manager console we see that a Distribution Point is added to our Package.

In the next post we’ll take a look at advertisements.

Rating 3.00 out of 5

PowerShell & SCCM – Program

In this post we’ll see examples on retrieving, modifying and creatint Programs in SCCM 2007. First let’s see how to retrieve a specific Program using Windows PowerShell.

PS > $pkgAdobe = Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_Package WHERE Name = 'Adobe Reader'"
PS > $prgAdobe = Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_Program WHERE PackageID = '$($pkgAdobe.PackageID)'"

In the example above we first use the SMS_Package class to retrieve a package where the Name is equal to “Adobe Reader”, next we use the SMS_Program class and in the WQL statement we specify that the PackageID should be equal to $pkgAdobe.PackageID.

We can use the Select-Object cmdlet to display specific properties – notice how the “Comment” property is empty in the example below.

PS > $prgAdobe | Select ProgramName, PackageID, Comment

ProgramName                 PackageID    Comment
-----------                 ---------    -------
Adobe Reader - Install      LAB00016

If we want to set the Comment we can simply type.

PS > $prgAdobe.Comment = "Adobe Reader"
PS > $prgAdobe.Put()

Path          : \\localhost\root\SMS\Site_LAB:SMS_Program.PackageID="LAB00016",ProgramName="Adobe Reader - Install"
RelativePath  : SMS_Program.PackageID="LAB00016",ProgramName="Adobe Reader - Install"
Server        : localhost
NamespacePath : root\SMS\Site_LAB
ClassName     : SMS_Program
IsClass       : False
IsInstance    : True
IsSingleton   : False

In the example above we use the Put() method to commit the changes. If we Select the Comment Property we’ll see that the Comment property contains a value.

PS > $prgAdobe | Select-Object Comment

Adobe Reader

Now let’s see how to create a new Program. in a previous post we created a new Package Named “Windows PowerShell”. Let’s go ahead and add a Program to the package. First we retrieve the PackageID using the SMS_Package class.

PS > $packageID = (Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select PackageID from SMS_Package WHERE Name = 'Windows PowerShell'").PackageID

Next we build up a HashTable containing the Properties and Values that we want to use when creating our new package.

PS > $arguments = @{
>> PackageID = $packageID;
>> ProgramFlags = $prgAdobe.ProgramFlags;
>> ProgramName = "PowerShell - Install";
>> CommandLine = "Install.bat"
>> }

In the example above we set the PackageID, ProgramFlags, ProgramName and CommandLine.

The ProgramFlags identify the installation characteristics of the program. In this example we copy the characteristics from the “Adobe Reader – Install” program. You can also set up specific ProgramFlags. You can check out this link for more information on ProgramFlags.

The CommandLine shows the command that runs when the program is started. In this example we use a bat file. Here’s the code placed in the install.bat file.

If we type $arguments the Name and Values stored in the HashTable are displayed.

PS > $arguments

Name                           Value
----                           -----
PackageID                      LAB00024
CommandLine                    Install.bat
ProgramFlags                   135307264
ProgramName                    PowerShell - Install

Finally we can create a new Program using Set-WmiInstance and the SMS_Program Class as shown below.

PS > Set-WmiInstance -class SMS_Program -arguments $arguments -namespace "root\SMS\Site_LAB"

If we take a look in the Configuration Manager Console we’ll see that the Program is added to the “Windows PowerShell” package.

The image below demonstrates the Program Properties in the Configuration Manager Console.

In the next post we’ll take a look at Distribution Points.

Rating 3.00 out of 5

PowerShell & SCCM – Collections

There are a couple of WMI classes that handle Site Collections. We can display them by using the Get-WmiObject cmdlet as shown below.

PS > Get-WmiObject -Namespace "root\SMS\Site_LAB" -List | 
>> Where-Object { $_.Name -match "Collection" } | 
>> Select-Object -Property Name


Let’s take a closer look at the SMS_Collection class. If we want to get a specific Collection we can use the Get-WmiObject cmdlet. In the example below we use the -Query parameter and specify WMI Query Language (WQL) statement to run.

PS > Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_Collection WHERE CollectionID = 'SMS000ES'"

__GENUS                  : 2
__CLASS                  : SMS_Collection
__SUPERCLASS             : SMS_BaseClass
__DYNASTY                : SMS_BaseClass
__RELPATH                : SMS_Collection.CollectionID="SMS000ES"
__PROPERTY_COUNT         : 16
__DERIVATION             : {SMS_BaseClass}
__SERVER                 : SCCM
__NAMESPACE              : root\SMS\Site_LAB
__PATH                   : \\SCCM\root\SMS\Site_LAB:SMS_Collection.CollectionID="SMS000ES"
CollectionID             : SMS000ES
CollectionRules          :
CollectionVariablesCount : 0
Comment                  : All Windows XP Systems
CurrentStatus            : 1
LastChangeTime           : 20100924123504.383000+***
LastMemberChangeTime     : 20100926162237.750000+***
LastRefreshTime          : 20101006172345.000000+***
MemberClassName          : SMS_CM_RES_COLL_SMS000ES
Name                     : All Windows XP Systems
OwnedByThisSite          : True
PowerConfigsCount        : 0
RefreshSchedule          :
RefreshType              : 1
ReplicateToSubSites      : False
ServiceWindowsCount      : 0

The command above retrieves an instance of the SMS_Collection class. Notice how we specify the CollectionID in the WQL statement. If we don’t know the collections ID we can change the query to check for the collections name instead as demonstrated below.

PS > Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_Collection WHERE Name = 'All Windows XP Systems'"

If we want to list all available collections we can change the query to “Select * from SMS_Collection” instead. Note that if you have alot of Collections in your test environment this command may use alot of memory.

PS > Get-WmiObject -Namespace "root\SMS\Site_LAB" -Query "Select * from SMS_Collection"

It’s also possible to use additional PowerShell Cmdlets with Get-WmiObject. If we only want to display the Name and CollectionID properties we can pipe the objects to the Select-Object cmdlet as shown below.

PS > Get-WmiObject -Namespace "root\SMS\Site_LAB" `
>> -Query "Select * from SMS_Collection" | 
>> Select-Object Name, CollectionID

Name                                                        CollectionID
----                                                        ------------
Root Collection                                             COLLROOT
All Systems                                                 SMS00001
All Users                                                   SMS00002
All User Groups                                             SMS00003
All Windows Workstation or Professional Systems             SMS00004
All Active Directory Security Groups                        SMS00005
All Windows Server Systems                                  SMS000DS
All Windows 2000 Professional Systems                       SMS000GS
All Windows 2000 Server Systems                             SMS000HS
All Windows XP Systems                                      SMS000ES
All Windows Server 2003 Systems                             SMS000FS
All Windows Mobile Devices                                  SMSDM001
All Desktops and Servers                                    SMSDM003
All Windows Mobile Pocket PC 2003 Devices                   SMSDM002
All Windows Mobile Pocket PC 5.0 Devices                    SMSDM005
All Windows Mobile Smartphone 2003 Devices                  SMSDM006
All Windows Mobile Smartphone 5.0 Devices                   SMSDM007
OSD                                                         LAB00012
Demo                                                        LAB00013

Finally, if we want to create a csv file based on our collections we can use the Export-Csv cmdlet.

PS > Get-WmiObject -Namespace "root\SMS\Site_LAB" -Query "Select * from SMS_Collection" | 
>> Select-Object -Property Name, CollectionID | 
>> Export-Csv C:\Temp\Collections.csv -NoTypeInformation

In the example above we use Get-WmiObject to retrieve all Collections and pipe the objects to the Select-Object where we select the Name and CollectionID properties. Finally we send the objects down the pipe and use the Export-Csv cmdlet to create a csv file.

In the next post we’ll see examples on how to Display, Update and Create Packages in SCCM using Windows PowerShell.

Rating 4.00 out of 5