Roberts Blog

The House of SCCM and Intune on System Center Street

Tag: ConfigMgr (Page 1 of 3)

DP_Locality flags or bitmask in SMS_UpdatesAssignment

I recently had to figure out how to properly set the DP_Locality property in the WMI SMS_UpdatesAssignment server SMS Provider class, as part of some work being done on PatchMaster, which automates the deployment of patches.

Eventually I figured it out, but at first I couldn’t quite grasp what was going on. I had to query the PG to verify my thinking (Thank you Hugo!), and in this post I’m going to go over as much detail as possible so as to spam the bejesus out of the subject.

To frame things better, every time you create a new Software Updates deployment in SCCM, a new SMS_UpdatesAssignment instance is created in WMI on the Site server to represent it.

Here’s a shot of the property sheet of a deployment, note the Neighbour DP and fall-back DP panels at the top and middle, and the WUMU\Metering panel at the bottom:

This is what it looks like behind the wizards curtain, using WBEMTEST to take a peek, DPLocality is an unsigned 32-bit integer:

* Note that you can do the same with PowerShell: get-wmiobject -namespace “root\sms\site_<YOUR SITES SITE CODE>” -query “select * from SMS_UpdateGroupAssign
ment where AssignmentID = <DeploymentID>” | Format-List -Property DPLocality

The DPLocality properties value shows 786512 (0xC0050). We’ll decode this in a moment.

That integer actually represents a bit mask, or a set of flags. This is noted in the documentation under qualifiers for that property as bits.

When I set about to decode DPLocality, I came up short. The documentation on Microsoft Docs doesn’t quite explain the bit positions properly, we’ll go over this now.

Firstly, the information you need is spread across two pages, shown below is the class, and then the class that class is inherited from:

SMS_UpdatesAssignment Server WMI Class

https://docs.microsoft.com/en-us/sccm/develop/reference/sum/sms_updatesassignment-server-wmi-class

The property we’re looking for is DPLocality:

As is shown above, this class is actually derived from the SMS_CIAssignmentBaseClass.

Deeper into the doc for the SMS_UpdatesAssignment class we get some information on the property we want to set, DPLocality:

First note that Qualifiers calls out that this is an integer formed using a bitmask (bits), concocted using flags.

Qualifiers: [not_null, bits]

It is also noted that the DPLocality property defaults to the flag combination DP_DOWNLOAD_FROM_LOCAL | DP_DOWNLOAD_FROM_REMOTE (0x50).

We have an assertion here, it states that when these two flags are combined they weigh in at 0x50 (hex), or 80 in decimal.

Great.

So we know that DP_DOWNLOAD_FROM_LOCAL and DP_DOWNLOAD_FROM_REMOTE are both set by default, and if we build ourselves a bit-table in excel, which I do a little bit further into this post, we can essentially figure out those two flags bit positions.

When these two flags are set the following radio button switches to “Download…”:

This panel defines whether the local DP or a neighbour DP can be used by clients for this deployment.

If you remove the DP_DOWNLOAD_FROM_REMOTE flag, the “Do not…” radio button is enabled instead.

That’s LOCAL or REMOTE DP defined, now let’s quickly look at the fall-back DP option and return to it in more detail further into the post:

To toggle the fall-back DP radio control we need to set another flag called DP_NO_FALLBACK_UNPROTECTED (detailed in the SMS_CIAssignmentBaseClass doc) so as to disable the fall-back DP option, or remove the flag to enable the option as highlighted in the shot above.

There isn’t much more noted for this class in this doc page, but we are told to go visit the base class that this one was inherited from, there is more for us there, so let’s go take a look.

SMS_CIAssignmentBaseClass Server WMI Class

https://docs.microsoft.com/en-us/sccm/develop/reference/sum/sms_updatesassignment-server-wmi-class

Nothing worthy of note here but I include a shot of the properties for this base class:

Let’s cut straight to the chase, no need to dilly dally, roll down until you find the DPLocality property:

We know this is a bit-mask, and here we have all 5 flags and their bit positions listed for us.

Yes those are bit positions and consequently starts at 0.

With these flags and bit positions (adjusted in just a moment) that’s all we need to construct and deconstruct the DPLocality value.

As I hint, actually three of the bit positions are noted incorrectly, we’ll take a ganders at that in a moment.

With this information I put together a bit-mask table in excel for easy reference, so as to figure out what the values should be, this gives me the decimal and hex value represented by the bit positions.

Here’s the bit-mask lookup table as a shot:

So armed with that initial assertion of the value 0x50 (decimal 80) from the two DP_DOWNLOAD flags being turned on, we can see that decimal 16 and 64 are added together to yield 80 (hex 0x50), that verifies bit positions 4 and 6 nicely..

So, we’re told that bit positions 4 and 6 are for the DP_DOWNLOAD flags, and bit positions 17, 18 and 19 are for the other three flags.

The problem with this is that the references to flags starts out using the bit position (bit column in table above) starting from 0 (DP_DOWNLOAD flags), and then starting from 1 (as sequence column in table above) for the other three flags, giving incorrect bit positions..

If we purely use bit position, the flags actually reside in positions 4, 6, 16, 17 and 18, and not 4, 6, 17, 18, 19. It’s an easy amendment to the docs which I’ll try to submit soon.

Worth noting that you just need to add these flag’s decimal value together to produce a valid integer.

There are four combinations for the Neighbour and fall-back DP, these are:

  • Neighbour No – Fall-back DP No –  = DP_DOWNLOAD_FROM_LOCAL + DP_NO_FALLBACK_UNPROTECTED
  • Neighbour Yes – Fall-back DP Yes = DP_DOWNLOAD_FROM_LOCAL + DP_DOWNLOAD_FROM_REMOTE
  • Neighbour Yes – Fall-back DP No = DP_DOWNLOAD_FROM_LOCAL + DP_DOWNLOAD_FROM_REMOTE + DP_NO_FALLBACK_UNPROTECTED
  • Neighbour No – Fall-back DP Yes = DP_DOWNLOAD_FROM_LOCAL

To handle WUMU and Metering just add their decimal value in once you’ve calculated the Remote\Local\Fall-back DP options.

And that’s about all you need to handle DPLocality.

Since I was handling this for a C# project, I might as well pass on what I wrote, I’m sure it can be done better, this is enabling code not the high of perfection code.

Below I show a method used to encode the bitmask based on some .Net controls ‘state’, I.e. a checkbox is checked or unchecked:

private int handledplocalityBitmask()

{

if (!globalObjects.GlobalClass.disableProcessing)

{

int tosendInt = 80;

if (cb_deployment_downloadNeighbour.Checked && cb_deployment_defaultFallback.Checked) tosendInt = 80;

if (cb_deployment_downloadNeighbour.Checked && !cb_deployment_defaultFallback.Checked) tosendInt = 131152;

if (!cb_deployment_downloadNeighbour.Checked && cb_deployment_defaultFallback.Checked) tosendInt = 16;


if (!cb_deployment_downloadNeighbour.Checked && !cb_deployment_defaultFallback.Checked) tosendInt = 131088;


if (cb_deployment_usemsUpdates.Checked) tosendInt = tosendInt + 262144 ;

if (cb_deployment_allowMetered.Checked) tosendInt = tosendInt + 524288 ;


return tosendInt;

}

return 0;

}

The four variations on Default and Neighbour are covered, and WUMU and Metering are added in at the end.

To decode the bitmask requires some more interesting coding.

First define some flags and respective decimal values that can be referenced later on:

[Flags]
public enum DPLocalityBitMask
{
     DP_DOWNLOAD_FROM_LOCAL = 16,
     DP_DOWNLOAD_FROM_REMOTE = 64,
     DP_NO_FALLBACK_UNPROTECTED = 131072,
     DP_ALLOW_WUMU = 262144,
     DP_ALLOW_METERED_NETWORK = 524288
}

And here is the code sitting in a method that does the decoding:

// Handle DPLocality Bitmask Combinations (expect Metering and WUMU)

var DPLocalityMask = (DPLocalityBitMask)adeploymentProperty.DPLocality;

var decodedDPLocality = new List<DPLocalityBitMask>();

foreach (DPLocalityBitMask DPLocalityBit in Enum.GetValues(typeof(DPLocalityBitMask)))
{

    if (DPLocalityMask.HasFlag(DPLocalityBit))
     {
         decodedDPLocality.Add(DPLocalityBit);
     }
}

// Neighbour, Fallback

if (decodedDPLocality.Contains(DPLocalityBitMask.DP_DOWNLOAD_FROM_LOCAL) && decodedDPLocality.Contains(DPLocalityBitMask.DP_DOWNLOAD_FROM_REMOTE))
{
     cb_deployment_downloadNeighbour.Checked = true;                       
}

if (decodedDPLocality.Contains(DPLocalityBitMask.DP_DOWNLOAD_FROM_LOCAL) && !decodedDPLocality.Contains(DPLocalityBitMask.DP_DOWNLOAD_FROM_REMOTE))
{
     cb_deployment_downloadNeighbour.Checked = false;
}

if (decodedDPLocality.Contains(DPLocalityBitMask.DP_NO_FALLBACK_UNPROTECTED))
{
     cb_deployment_defaultFallback.Checked = false;
}
else
{
     cb_deployment_defaultFallback.Checked = true;
}
                    
// Metered network

if (decodedDPLocality.Contains(DPLocalityBitMask.DP_ALLOW_METERED_NETWORK))
{
     cb_deployment_allowMetered.Checked = true;
}
else
{
     cb_deployment_allowMetered.Checked = false;
}

// Use WUMU

if (decodedDPLocality.Contains(DPLocalityBitMask.DP_ALLOW_WUMU))
{
     cb_deployment_usemsUpdates.Checked = true;
}
else
{
     cb_deployment_usemsUpdates.Checked = false;
}

Enjoy.

ConfigMgr–CMG and the DMZ

Patching servers or ‘managing Windows assets’ in a DMZ has always been a challenge.

Trying to manage assets with one systems management solution in two domains, the DMZ (external network) and the intranet (Internal network) broadens the challenge further.

All designs put forward to manage assets in a DMZ using the internal networks systems management solution, essentially depend on spinning services, or in ConfigMgr lingo ‘roles’, out into the DMZ so that the devices that reside there, do not need to reach back into the internal network for content and communications purposes.

The holy grail of DMZ design is to literally eliminate all communications from the DMZ into the Intranet, but allow communications from the intranet into the DMZ.

That’s a tall order.

To give a sense of what I mean, here is an analogy using tennis!

If you imagine a tennis court, a net, two players with racquet in hand and a tennis ball.

To have a sensible game of tennis both players need to be able to bounce a ball over the net and attempt to return the ball if it is received.

Now imagine that the net is the DMZ’s firewall, player 1 is the Site server, player 2 is an asset in a DMZ, the tennis ball is the content and communications.

In our imaginary game of tennis, player 2 cannot return the ball as the net always blocks it, thus the game cannot be played. Game over. Insert coins to continue.

In some rare configurations, IPSEC and other security services are employed to tunnel communications from a SPOC such as an MP, from the DMZ, back into the internal network to overcome the challenges. For those that do not tolerate this, providing a solution that can manage assets in both the internal and DMZ networks gets complicated quickly.

In the past I’ve managed to achieve complete DMZ compliance while using ConfigMgr to service DMZ assets. And yes it was complicated.

I achieved this by introducing a Management Point Replica so that the clients communications with an MP in the DMZ does not result in the MP talking to the DB located within the intranet, as well as by deploying a DP, a SUP, and all rounded off by reversing the Site system to Site server communications (set on the Site system itself). Site systems in the DMZ never talk back to the intranet, and assets always talk to those site systems, job done.

Another way to overcome this is to utilise IBCM, if it is setup for client management over the internet. Placing an MP, a DP and a SUP in the DMZ, and letting those internet-based devices access those roles, and most importantly the servers in the DMZ seals the deal.

As you can see, there are many ways to go at this problem.

With the cloud-first approach Microsoft have adopted for the last decade, we’re seeing heavy integration taking place through cloud products and services evolving, that is yielding some very interesting tooling.

With the introduction of the Client Management Gateway, we have another solution for managing DMZ clients.

Let the servers in the DMZ go out onto the internet via the CMG, and back into the on-premise roles, while using the Cloud DP to issue content.

It is worth noting that the Cloud DP can now be installed along with the CMG itself, and does not require another virtual machine to house it, reducing the cost of the solution somewhat.

There are so many options available right now, you can even throw an IBCM DP into the mix along with a CMG running just an MP and SUP, just to negate content delivery costs, but I suspect this is a short-term solution, and that over the long term it might cost more than using a Cloud DP with its associated metered download costs.

In the simplified above shot we see the DMZ layers, protecting company assets from external interference, and generally as a rule of thumb, preventing any communications originating from the DMZ into the internal network.

The servers will reach out to the CMG and not talk directly to the ConfigMgr Stand-alone hierarchy.

Outstanding.

So today, to service (patch\update) assets in the DMZ we can go one of several routes:

  • Abandon the idea of servicing DMZ assets using the production ConfigMgr hierarchy instance, and instead stand up a new ConfigMgr Hierarchy located in the DMZ itself
  • Opt to use stand-alone WSUS
  • Service directly using Microsoft Updates, while employing some form of control using Local Group Policy to configure the Windows Update Agent
  • Employ Management Point Replicas, Site systems using reverse replication (SMB level) and with the SQL replication reversed (important so as to maintain DMZ compliance), deploy DP’s and SUP’s
  • Join to Azure and service from there
  • Use Operations Manager Suite (token nod to Sam Erskine who bangs the drum for servicing using OMS!)
  • Implement IBCM

or

  • Service using ConfigMgr and the super-amazing Client Management Gateway

The list isn’t exhaustive by the way …

In this article, I’m going to walk through how to setup a method for managing DMZ assets that involves ConfigMgr, CMG and PKI, with Certificate issuance to workgroup clients being handled by Certificate Enrollment Policy and Certificate Enrollment Services (CEP\CES).

I do not have a DMZ, and my PKI infrastructure is on the intranet. If you were aiming to test this with a real DMZ you’ll need to ponder how to deploy the PKI infrastructure appropriately.

Some of you may already have NDES setup, as part of your Intune implementations or explorations, and can use that to service the workgroup assets.

In a real production environment you’d break down how you’re going to place a CA\CEP\CES\CDP in the DMZ that they can utilise, while making sure these PKI services in the DMZ are not reaching back into the intranet.

In the shot above, is a Callout for the Primary showing 6 servers. This is my stand-alone Primary, which is configured for High Availability and really does consist of 6 servers:

  • 2 Primaries (Active/Passive) running Build 1806
  • 2 Site systems (single instance roles, duplication of non-single-instance roles, SMS Providers, some Shares)
  • 2 SQL servers running SQL AlwaysOn on top of a Windows Cluster, File Cluster services to accommodate the Content Library

I also have:

  • 1 Domain Controller for Lab1.com
  • 2 Certificate Authority servers
    • 1 running CA, CA Web Enrollment, NDES (IIS HTTP)
    • 1 running CEP, CES (IIS HTTPS)
  • 4 Windows 10 test clients
    • 2 AD/AAD joined
    • 2 Workgroup joined

I’ve ‘faked’ having a client in a DMZ, by blocking all communications to the ConfigMgr intranet servers using the HOSTS file on one of my workgroup based Windows 10 test clients. It cannot directly talk to ConfigMgr, it has unfettered access to the internet.

I had a few issues along the way that burnt a serious amount of hours, firstly not having an HTTP CDP for the CRL tripped me up, and then figuring out what the CEP URI is supposed to be caused delays.

With hindsight, this is pretty easy stuff, the CEP URI can be found in several places, and I didn’t need to do much to enable a HTTP CDP.

Here’s where you turn on the HTTP CDP, it has to be done before you begin issuing certificates, or existing certificates will need to be renewed to pick up this meta change:

Tick the Include in CRLs and the Include in the CDP extension tick boxes.

Another thing to tick off is the FriendlyName for the IIS virtual directory running within default website on the CA running CEP\CES:

Open IIS, head to the virtual directory residing in the default website containing CEP and UsernamePassword, visit its Application Settings and change FriendlyName to include something, I chose Lab1. You will see this show up later on when requesting certificates.

Once that was all taken care of, the entire chain of proceeding activities fell into place nicely.

The next piece is about preparing the PKI certificates needed to allow the ConfigMgr client to talk to the CMG, a Trusted Root CA and a computer certificate with Client Authentication present.

The root certificate can be exported from any domain-joined device, or from the Certificate Authority server in your lab, here’s a guide.

ConfigMgr itself can deploy the root certificate, but it first has to have the client installed and have access to the intranet roles. Since you can service devices in Workgroup mode, if you are already setup to use ConfigMgr to service your DMZ assets, delivery of the Root CA is a cinch using Certificate Profiles, forming one of the activities needed to transition from internal management to external via the CMG.

Or you can drop the Root CA in manually.

We now need a computer certificate which has client authentication capability. In my lab’s CA I created one by cloning the Workstation Authentication certificate template:

On your CA, open the Certificate Authority console, right click Certificate Templates and select Manage. Nose around and find the Workstation Authentication template:

Right click it, and select Duplicate Template. A new template will be prepared, and its property sheet shown, so that we can populate the template before committing it:

Populate the Template display name, mine is called Lab 1 Client Certificate.

Head to the Request Handling tab:

Untick Allow private key to be exported.

Head to the Subject Name tab:

Select Supply in the request.

Select the Security tab:

By all means make changes here, but for my lab I’ve left as-is as my Domain Admin account will be used to initiate the certificate enrolment from the client.

You can select OK now and commit this new template.

Head back to the Certificate Authority console, right click Certificate Templates and this time select New > Certificate Template to Issue:

Once you’ve selected Certificate Template to Issue, from the list produced, select your newly created Certificate Template. This will make it available to anyone with enough permissions as defined in the Security tab of the template, to request the certificate.

Now on the client, we need to add a Certificate Enrollment Policy server using the Certificates MMC.

Run the MMC as an administrator or accept the UAC prompt, choose Computer account when adding the Certificates snap-in.

Right click Certificates > Personal or Certificates > Personal > Certificates if any certificates have already been issued, select All Tasks, then Advanced Operations, finally select Manage Enrollment Policies…:

We can now add and remove Enrollment policy servers:

Select Add…

You can obtain the format needed to create the CEP URI by using CERTUTIL.EXE, which as shown below returns the CES URI, just replace CES with CEP:

Or by visiting IIS:

Bound to be other ways to find it.

For my example it is:

https://L1CA.Lab1.com/ADPolicyProvider_CEP_UsernamePassword/service.svc/CEP

So I punch that in as the enrollment policy server (URI) value, and select Validate Server.

We’re now prompted for credentials to access the CEP:

In my lab I chose the Domain Admin again.

You should now get some information back on what happened, the validation of the Certificate Enrollment point was successful:

Our Policy server is in place, we can request Certificates using it:

Select OK.

Just as an aside, if you do not set the FriendlyName as we did earlier in the article, you’ll get a warning when you validate, and the Name will show as a GUID: