Sunday, February 23, 2014

PowerShell + SCCM 2012 R2 : Extending Discovery; Create Custom DDRs

While working on the previous post on exploring Discovery methods with PowerShell I came across this awesome post on creating custom DDRs with PowerShell in ConfigMgr07.

The above post explains how to create custom DDRs using ConfigMgr SDK for ConfigMgr 07.

So I got tempted to immediately try it out in my ConfigMgr12 environment and found out that there exists another cool way shown by Adam Meltzer (using C#) in his blog to create DDRs in ConfigMgr12. So in this post will try to cover :
  • Create DDRs using COM Interface (DLL used : smsrgenctl.dll)
  • Create DDRs using the new DiscoveryDataRecordFile Object Interface (DLL used: Microsoft.ConfigurationManagement.Messaging.dll)
Note : Both the above DLLs are part of ConfigMgr 2012 SDK.

Create DDRs using COM Interface (DLL used : smsrgenctl.dll)

Tried loading the smsrgenctl.dll from PowerShell using Add-Type , System.Reflection.Assembly's LoadFrom Method which is supposed to load the dependencies.

Finally used the resgvr32.exe to load and it did work but it would show sometime that it was success but won't show up the ProgID in my registry

After the DLL is loaded is pretty Straight Forward to follow the post mentioned earlier. Below is the Code which I used it has comments explaining what each line does:

After this you will see the entry reflect in ConfigMgr Console:

Create DDRs using the new DiscoveryDataRecordFile Object Interface (DLL used : Microsoft.ConfigurationManagement.Messaging.dll )

If you look in the "Redistributables" folder for ConfigMgr 12 SDK there is a dll named 'Microsoft.ConfigurationManagement.Messaging.dll'. Following the post by Adam (which is in C#) I was able to do it in PowerShell. Below is the what the documentation says about the class DiscoverDataRecordFile which will be used:

Note that this supersedes the old COM Method we used to create the DDRs.

This one is actually easy. See the code below (comments explaining each step):

Now the proof:

So this is how you can extend discovery using PowerShell.....I find this one very cool. Now I can populate a lot of device entries in my SCCM environment for testing.

I happen to be one of the speakers at the First PowerShell Saturday Event in India [Bangalore] (March 8th, 2014) and would be speaking on my ConfigMgr + PowerShell Experiments. If you are around and interested then do drop by.
You can register for PowerShell Saturday Event here (limited seats) -->

UPDATE:: There is a cmdlet in the CM2012 R2 PowerShell Module which does this job of creating DDRs for you Import-CMComputerInformation, came to knew about this while reading this post HERE 

Wednesday, February 19, 2014

Use PowerShell to remove packages from the Distribution Points

This post is inspired by one of the activities which we had to recently do.

We have a lot of branch DP's where we want to cleanup all the obsolete packages (which are not used anymore). This can be done manually by going in the ConfigMgr Console Packages node and updating the DP's manually for each package.

But where is fun in doing that ...Lol

I couldn't find much on the internet ..So I tested it in my Lab first and then in QA in our environment and then did it in PROD.

For this post demonstration I am showing this on my LAB (ConfigMgr12) but it does work with ConfigMgr07.

Note- ConfigMgr 2012 R2 has this cmdlet Remove-CMContentDistribution which can do this but am showing the method which will work with all ConfigMgr versions (hopefully).

Right now I have distributed 3 packages to the only DP (DexSCCM) in my environment.

Now we can get the same Information about which DP the particular package is Distributed by querying the SMS_DistributionPoint Class. See below:

Now If you want to remove suppose the Package with ID DEX00001 (USMT package) then I just have to go ahead and remove this object. See me do it:

ConfigMgr Console does reflect the change:

[UPDATE] - You can see the SMSProv.log that will have entry of you deleting an instance of SMS_DistributionPoint.

Once I knew was very easy to quickly wrap a function which will remove a list of PackageIDs supplied to it from a DP name.

Have uploaded the Script in Technet Repositoy (tested in ConfigMgr 07 and 12). Give it a try and if you like it give it a good rating.

Once you use this method then it may take some time for the package to be removed and free Disk Space on the DP. For me it was around 1 hour (in the PROD environment)...So be patient and get a Coffee while the Script cleans up your DPs ;)

Monday, February 17, 2014

PowerShell + SCCM 2012 R2 : Discovery

So my lab is all setup. Now before starting to manage Objects (Computers, Users etc. ) we need to discover them.

If you want to read more on Discovery in ConfigMgr, you can browse to this link.

For this post am trying to automate things done in this post at Windows-Noob.

Note - To manage ConfiMgr using PowerShell one needs the ConfigrationManger Module (this is available after you install Admin Console on a Client/ Server) loaded in the session, which can be done in two ways:

  1. You can open a PowerShell session and import the ConfigurationManager module.
  2. Import-Module -Name "$(split-path $Env:SMS_ADMIN_UI_PATH)\ConfigurationManager.psd1"
  3. Using ConfigMgr Admin Console you get an option to connect using PowerShell which essentially does the same thing done in above step.

Note: To run all the CM Cmdlets your location needs to be set to the CMSite and properties you reference are case sensitive. Below is the Screenshot showing that :

Now see the Property Reference thing I was referring to:

[I tried Implicit Remoting but the the PSDrive for the CMSite won't load on the PSSession while importing the Module.]

Step1 : Enable Discovery Methods

The Cmdlet used to work with configuring Discovery methods is:
If you go and have a look at the Online help page for the cmdlet you will see that the parameter set names and the parameters are really very descriptive.

AD Forest Discovery [LogFile - ADForestDisc.log] : With ConfigMgr 2012 this is a new discover methods added which discovers AD Sites, Subnets and domains and gives an option to automatically create Boundaries based on it.

To enable it using PowerShell and run it ASAP the code is below:

So after this hit refresh on the ConfigMgr console and the changes reflect.

AD Group Discovery [Logfile - Adsgdis.log] :
BTW run this discovery method after you have run the AD System and User discovery as it creates partial DDR for the Computers and Users part of the Groups. Read more here.

I did hit a little bump while trying to configure this discovery, at first was able to configure all options properly except the one to set Discovery Scopes. Later on was able to do that after digging deep into the ConfigMgr SDK , trying out things via GUI to analyze them and found out that it is way easy to do in PowerShell by just issuing few CIM calls :)

Below is the code :

The Screenshots after running the above cmdlet:


AD System Discovery [Logfile : Adsysdis.log ]

I found out that the Set-CMDiscovery Cmdlet does have a parameter named -ActiveDirectoryContainer  but it throws an error when you use that so I went ahead and did it using CIM Cmdlets ;)

Note that the schedule in which discovery is running in my Environment are very short's just my Lab environment you shouldn't do that in a Production as it could be overwhelming for the Site Servers to process the discovery data.

Code is below:

Below is one of the Screenshots...not putting every screen up now. You can verify it in your environment. Play with the Script code a bit and you would explore what various values do.

AD User Discovery [Logfile : Adusrdis.log ]
Based on pretty much what is done with the AD Sys Discovery the PowerShell code is similar. Code is below

Network [LogFile : NetDisc.log ] & HeartBeat Discovery [ LogFile : InventoryAgent.log  (Client Side)]

Code below:

Now, this past week was interesting as I was reading the ConfigMgr SDK to figure out most of the things like setting AD Container for User/ System discovery but in the end it was lot of experimenting that made it work.

Also after you make changes to the Discovery methods, they won't reflect until you restarted the Component Manager service on the SCCM Server. This took me little time to figure out. Once you do this the relevant log files will spawn up or have the relevant entries about the run.

I must say I had my share of fun figuring things hoping for more learning in next few weeks when I dive deep into  the ConfigMgr SDK ;)

Saturday, February 08, 2014

PowerShell + SCCM 2012 R2 : Installation

Recently decided to embark on this little adventure of mine...where I will setup my SCCM 2012 R2 Lab and try doing most of things using PowerShell.

I know this is ambitious and might take longer (even longer to blog about it)......But that hasn't stopped me in past. I am sure I will learn a lot in the process.

So for this post it is the installation am focussing on and I am following the Windows-Noob Guide here.

Steps which I won't be doing using PowerShell will be mentioned.

My LAB :
1. DexterDC  -- Domain Controller [Domain name -] (server 2012 R2)
2. DexSCCM -- Machine where SCCM will be installed (Server 2008 R2)
3. DexClient -- Windows 7 Client

To make my Quest easy, I have enabled PSRemoting in the Domain using GPO.

Step 1. Create the Lab Environment

Create AD Users

First let's create the Users and then try to give the permissions needed.

* SMSadmin, a domain user 
* Testuser, a domain user
* Testuser2, a domain user
* Testuser3, a domain user
* DomJoin, a domain user,(for joining computers to the domain) 
* ReportsUser, a domain user for reporting services.
* ClientInstall, a domain user used when installing the Configuration Manager Client for Client Push. This user must be a local administrator on computers you want to install the Configuration Manager Client.
* SCCMNAA, a domain user, (Network Access Account) used during OSD

On the SCCM server add the SMSadmin user to the Local Administrators group (you can add the ClientInstall account also)

Below is what the PowerShell region for this part looks so far:

Step2 is download so manually done already or can be done using Start-BitsTransfer (see Step 8)

Step 3 & 4: Create the Systems Management Container and Delegate Permission to it

Below is the Code which will create the container and give the Computer Account for DexSCCM appropriate permissions on the container.

Step 5- Extend the AD Schema
This one is just double-click the Executable , this is how you do it in PowerShell:

Step 6- Open TCP Ports for Replication 1433 and 4022 for replication
For this we will create a GPO and add the firewall rules to it and link the GPO back to the domain. Below is the code with comments:

So after I do this in the Group Policy Management Console, I see below :

Pretty neat huh!

Step 7: Install .NET 3.5.1 and WCF activation
Till now all the steps were being done on my Domain Controller. You can use a Client (Win7/Win8) to do all this stuff if it has RSAT installed too, but that costs me one more machine on my poor Hyper-V server ;) . So I tend to do most stuff on DC ...remember it's my LAB.

For this step we need to add the features to the SCCM Server (DexSCCM). So let's get to it. Let's try Get-WindowsFeature

Let's try the PSRemoting way now (already setup in my environment):

Step 8 code to download .NET 4 (code Above)
Step 9 add features BITS,RDC (code above)

Step 10 &11:  Install SQL Server 

I have SQL Server 2012 SP1 and I tried for a while to silent install it but I was able to mess up the Configuration File each time. So I decided to this manually on the DexSCCM server.
One can try this.

Step 12 : Install Configuration Manager 2012 R2

I went with manual install for this too. But you can try the silent install by following the instructions here.

So this sums up my post. If you are really looking to automate the whole installation process then there is a Project by name CM12Automation @ Codeplex do try it. 

Will be back with more of my PowerShell and Configuration Manager experiments.

Thursday, February 06, 2014

PowerGUI wraps PS1 to EXE - How does it work ?

I have lot of PowerShell Script which I want wrapped as an executable using PowerGUI (as PowerGUI Pro is free now).

PowerGUI lets you do that easy.....

After this it gives you option to name the exe , .NET version to target, Hide/Show console window in the back-end, Password protect your source etc.

I thought maybe putting password will protect my source and was curious how does it really works. 

But it works a bit differently then I thought. When you share this with your colleagues then in order for them to use this exe you need to share the password above.

In this case I have a simple script which creates a simple UI and asks for a Computer name to reboot.

When I give a wrong machine name it throws me an error and if you see the highlighted entry it points to a PS1 .
If I go to the path in the error message I can see the source lying around:

Now I haven't put any hard-coded credentials on it (BTW that's a bad practice ).
Though PowerGUI wraps the PS1 as an exe, but it eventually puts the PS1 in a temporary location and executes it.

Now I can hide the back console window just as a precaution but my source PS1 is still lying around in the system.