Approaches to GUID Management in #PSDSC Pull Mode

In large deployments using PowerShell Desired State Configuration (DSC) it is inevitable to implement a pull server because of the centralized configuration management. The nodes connecting to a pull server are identified by a globally unique identifier (GUID). Those GUIDs are - for a start - entirely independent from the hostname. I will present several approaches to managing the GUIDs used for DSC nodes.

Generating Random GUIDs

The easiest approach is using random GUIDs generated by the following command:

[System.Guid]::NewGuid()

Using Active Directory GUIDs

On System Center Central, this post describes how to grab hostnames and Security IDs from Active Directory and generate the appropriate configuration data:

#Pull computer objects for AD
function GetComputers {
    import-module ActiveDirectory
    Get-ADComputer -SearchBase "OU=Servers,OU=HQ,DC=contoso,DC=com" -Filter *
}
$computers = GetComputers

#Pull list of computers and GUIDs into hash table
$ConfigData = @{
    AllNodes = @(
        foreach ($node in $computers) {
            @{NodeName = $node.Name; NodeGUID = $node.objectGUID;}
        }
    )
}

Reading through the code you will notice that the constructed configuration data uses the hostname for the NodeName and stores the computers security ID as NodeGUID.

Although this approach uses a central store (i.e. Active Directory) for GUIDs, it assumes that all systems are domain joined. In addition computers may be distributed across several domains.

The exciting advantage of pulling GUIDs from Active Directory is that groups can be used to assign server roles to computers.

Using VM GUIDs

Most companies are implementing a virtualize-everything strategy. As a result hardly any servers are physical boxes. At least the most widely spread hypervisors (VMware ESX and Microsoft Hyper-V) use a unique identifier for virtual machines.

Microsoft Hyper-V offers a unique ID for all virtual machines. This ID can be obtained through the PowerShell cmdlet Get-VM executed on the appropriate host. I have wrapped this in a function to re-use it:

function Get-VmIdFromHyperV {
    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$ComputerName
        ,
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Name
    )
    (Get-VM @PSBoundParameters | Select Id).Id
}

The downside of the above example is the fact that you need to know on which host the virtual machine is located. A centralized management environment like System Center Virtual Machine Manager solves this issue by providing a central VM repository. VMM offers a separate ID that is garantueed to be unique across all managed hosts. The following example demonstrates retrieving this ID similar to the function above:

function Get-VmIdFromVmm {
    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$VMMServer
        ,[Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Name
    )
    (Get-SCVirtualMachine @PSBoundParameters | Select Id).Id
}

VMware vCenter provides an InstanceUuid as well as a MoRef ID (Managed Object Reference ID) to uniquely identify a virtual machine. They can be retrieved through the vSphere API. A function similar to the examples above can easily be written by someone familiar with the API.

How to Map GUIDs to Hostnames

Whatever way you decide for managing GUIDs, you will need some mechanism to map them to hostnames.

If you are using Active Directory or a VM management solution to retrieve GUIDs, you will only need to build the tools to resolve a GUID to a VM name, then to an IP address and then to a DNS name.

If you are using randomly generated GUIDs for your nodes you will have to store NodeName and NodeGUID to be able to map one to the other. I have found two examples for this:

Summary

Apparently, it is necessary to manage the GUIDs used for pull nodes in one way or the other. I am currently planning to use the VM ID of System Center Virtual Machine Manager. Although I do see the advantages of using Active Directory for GUIDs as well as assigning server roles using groups, I don’t like to be limited to domain joined systems. You may want to refer to my post about designing node configurations.

Feedback is always welcome! If you'd like to get in touch with me concerning the contents of this article, please use Twitter.