Unable to Pull configuration using WMF 4 Pull server

Hi
Using Windows server 2012R2 with the KB2883200 installed. I have set up a Pull Server using a certificate.

Iam unable to get my node to fetch confiurations from the pull server.
Using the get.xDscOperation I find the following error:

WebDownloadManager for configuration 3f2fb53d-129c-44ff-8fcc-cc2a55ab738b Do-DscAction command, GET Url: PSDSCPullServer.svc/Action(ConfigurationId='3f2fb53d-129c-44ff-8fcc-cc2a55ab738b')/GetAction.
WebDownloadManager for configuration 3f2fb53d-129c-44ff-8fcc-cc2a55ab738b Do-DscAction command with server url: https://vm06.contoso.com:8080/PSDSCPullServer.svc.
Attempting to get the action from pull server using Download Manager WebDownloadManager. Configuration Id is 3f2fb53d-129c-44ff-8fcc-cc2a55ab738b. Checksum is . Compliance status is true.
Configuration is sent from computer NULL by user sid S-1-5-21-195968190-741174349-770780043-93293.
This event indicates that failure happens when LCM is trying to get the configuration from pull server using download manager WebDownloadManager. ErrorId is 0x1. ErrorDetail is Failed to get the action from server https://vm06.contoso.com:8080/PSDSCPullServer.svc/Action(ConfigurationId='3f2fb53d-129c-44ff-8fcc-cc2a55ab738b')/GetAction.
WebDownloadManager for configuration 3f2fb53d-129c-44ff-8fcc-cc2a55ab738b Do-DscAction command, GET call result: Failed to get the action from server https://vm06.contoso.com:8080/PSDSCPullServer.svc/Action(ConfigurationId='3f2fb53d-129c-44ff-8fcc-cc2a55ab738b')/GetAction..
Message One or more errors occurred. 
HResult -2146233088 
StackTrack    at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at Microsoft.PowerShell.DesiredStateConfiguration.Commands.GetDscActionCommand.IssueRequest(HttpClient client, String subLink, String& responseStatus, ErrorRecord& errorRecord)
WebDownloadManager processed certificate: [Subject]
  CN=DscSecure

and

Thumbprint]
  12437D58F28E4E52B63B0FBCF0E34CF4C8BD8797
RemoteCertificateNameMismatch, RemoteCertificateChainErrors.
Configuration is sent from computer NULL by user sid S-1-5-21-195968190-741174349-770780043-93293.
This event indicates that failure happens when LCM is trying to get the configuration from pull server using download manager WebDownloadManager. ErrorId is 0x1. ErrorDetail is Failed to get the action from server https://vm06.contoso.com:8080/PSDSCPullServer.svc/Action(ConfigurationId='3f2fb53d-129c-44ff-8fcc-cc2a55ab738b')/GetAction.
WebDownloadManager for configuration 3f2fb53d-129c-44ff-8fcc-cc2a55ab738b Do-DscAction command, GET call result: Failed to get the action from server https://vm06.contoso.com:8080/PSDSCPullServer.svc/Action(ConfigurationId='3f2fb53d-129c-44ff-8fcc-cc2a55ab738b')/GetAction..
Message One or more errors occurred. 
HResult -2146233088 
StackTrack    at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at Microsoft.PowerShell.DesiredStateConfiguration.Commands.GetDscActionCommand.IssueRequest(HttpClient client, String subLink, String& responseStatus, ErrorRecord& errorRecord)
WebDownloadManager processed certificate: [Subject]
  CN=DscSecure

Trying to open my pull server site on target node or pull server gives me “There’s a problem with this website’s security certificate”. I have not manually set a certificate onto the pull server site in IIS.

My configuration is as follows:

#CERT
$Certificate = "dscSecure"
$certSubject = "CN=$Certificate"
$keysFolder = Join-Path $env:SystemDrive -ChildPath "Keys"
$cert = dir Cert:\LocalMachine\My | ? { $_.Subject -eq $certSubject }
if (! (Test-Path $keysFolder ))
{
    md $keysFolder | Out-Null
}

#Copy publickey to folder
$certPath = Export-Certificate -Cert $cert -FilePath (Join-Path $keysFolder -ChildPath "$Certificate.cer") -Force

#CERT PUBLIC for PULL SERVER
#This is done on the configuration server, The pfx (private key will only be on the node server)
#Import the public key to trustedroot if it does not already exist there.
$Existingcert = @()
$Existingcert += dir Cert:\LocalMachine\Root | % {$_.Subject}
If(!($Existingcert.where({$_ -eq $certSubject})))
{
    Import-Certificate -FilePath ($certPath.FullName) -CertStoreLocation Cert:\LocalMachine\Root > $null
}

#CREATE REGKEY
$RegKey = [guid]::newGuid() #Current a5d8b762-5102-4082-b088-be9c671975df
$Thumbprint = (Dir Cert:\LocalMachine\my | ? {$_.Subject -eq "CN=$Certificate"}).Thumbprint #12437D58F28E4E52B63B0FBCF0E34CF4C8BD8797


$ConfigurationData = @{
    AllNodes = @(
        @{
            NodeName="*"
            PSDscAllowPlainTextPassword=$true
            PSDscAllowDomainUser = $true
         }
        @{
            NodeName='localhost'
         }
    )
}


configuration DscWebService
{
    param 
    (
        [string[]]$NodeName = 'localhost',
        [ValidateNotNullOrEmpty()] [string] $certificateThumbPrint
    )

    Import-DSCResource -ModuleName xPSDesiredStateConfiguration 
    Import-DscResource –ModuleName PSDesiredStateConfiguration

    Node $AllNodes.NodeName 
    {
        WindowsFeature DSCServiceFeature
        {
            Ensure = "Present"
            Name   = "DSC-Service"            
        }

        WindowsFeature Auth
        {
            Ensure = "Present"
            Name   = "web-windows-Auth"            
        }

        xDscWebService PSDSCPullServer
        {
            Ensure                  = "Present"
            EndpointName            = "PSDSCPullServer"
            Port                    = 8080
            PhysicalPath            = "$env:SystemDrive\inetpub\wwwroot\PSDSCPullServer"
            CertificateThumbPrint   = $certificateThumbPrint         
            ModulePath              = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules"
            ConfigurationPath       = "$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration"            
            State                   = "Started"
            DependsOn               = "[WindowsFeature]DSCServiceFeature"                        
        }

        xDscWebService PSDSCComplianceServer
        {
            Ensure                  = "Present"
            EndpointName            = "PSDSCComplianceServer"
            Port                    = 9080
            PhysicalPath            = "$env:SystemDrive\inetpub\wwwroot\PSDSCComplianceServer"
            CertificateThumbPrint   = $certificateThumbPrint
            State                   = "Started"
            #IsComplianceServer      = $true
            DependsOn               = @("[WindowsFeature]DSCServiceFeature","[xDSCWebService]PSDSCPullServer")
        }
    }
}

#RUN CONFIGURATION
$MofConfigFile = DscWebService -ConfigurationData $configurationData -certificateThumbPrint $Thumbprint -OutputPath c:\Configs\PullServer

# This creates a MOF at:
$MofConfigDirectory = $MofConfigFile.DirectoryName
ii $MofConfigDirectory

#RUN MOF
Start-DscConfiguration -Path $MofConfigDirectory -Wait -verbose -ComputerName "localhost" -force

Then copying certificate to node:

#NODE
$Node = 'vm05'

#COPY PFX TO NODE
$block =
{
$Certificate = "dscSecure"
$CertificatePwd = "Password99"
$NewPath = "C:\$Certificate.pfx"

$mypwd = ConvertTo-SecureString -String $CertificatePwd -Force –AsPlainText
Import-PfxCertificate –FilePath $NewPath cert:\localMachine\my -Password $mypwd

}
Set-Content "\\share\import_sert.ps1" $block

#Import private key to nodes
copy "\\share\$Certificate.pfx" \\$Node\c$
copy "\\share\import_sert.ps1" \\$Node\c$

$testscriptblock = 
{
    powershell C:\import_sert.ps1
}

Invoke-Command -ComputerName $Node -ScriptBlock $testscriptblock


#CREATE CHECKSUM FOR MODULES
New-DSCCheckSum -ConfigurationPath 'C:\Program Files\WindowsPowerShell\DscService\Modules' -OutPath 'C:\Program Files\WindowsPowerShell\DscService\Modules'

/pre> 



Configuring the LCM



 

#GUID FOR EACH TARGET NODE
$guid = '3f2fb53d-129c-44ff-8fcc-cc2a55ab738b' #[Guid]::NewGuid().ToString() #


#LCM
$ConfigData = @{
    AllNodes = @(
        @{
            NodeName="*"
            PSDscAllowPlainTextPassword=$true
            PSDscAllowDomainUser = $true
            CertificateFile = "C:\keys\$Certificate.cer"
            Thumbprint = $Thumbprint
         }
        @{
            NodeName = $Node
            NodeGuid = $guid
         }
    )
}

Configuration ConfigureTargetLCMs 
{

    Node $AllNodes.NodeName
    {
        LocalConfigurationManager 
        {
            CertificateId                 = $Node.Thumbprint
            ConfigurationID                = $Node.NodeGuid;
            RefreshMode                    = "PULL";
            AllowModuleOverwrite           = $true
            DownloadManagerName            = "WebDownloadManager";
            RebootNodeIfNeeded             = $true;
            RefreshFrequencyMins           = 15;
            ConfigurationModeFrequencyMins = 15; 
            ConfigurationMode              = "ApplyAndAutoCorrect";
            DownloadManagerCustomData      = @{
            ServerUrl               = "https://vm06.contoso.com:8080/PSDSCPullServer.svc"}
        }
    }
}

ConfigureTargetLCMs -ConfigurationData $ConfigData -nodename $Node -OutputPath c:\Configs\TargetNodes
New-DSCCheckSum -path C:\Configs\TargetNodes


#REMOTE SET
Write-Host "Starting CimSession"
$pwd = read-host
$pass = ConvertTo-SecureString $pwd -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("contoso\user", $pass)
$cim = New-CimSession -ComputerName $Node -Credential $cred

Write-Host "Writing config"
Set-DscLocalConfigurationManager -CimSession $cim -Path C:\Configs\TargetNodes -Verbose

# read the config settings back to confirm
Get-DscLocalConfigurationManager -CimSession $cim


#TEST pull
cd '\\share'
.\Invoke-PullonNode.ps1 -computername $Node
cd C:\windows\System32


#REMOVE OLD dscConfiguration from node:
$Session = New-CimSession -ComputerName $node -Credential $cred
Remove-DscConfigurationDocument -Stage Current -CimSession $Session 

Here is the configuration I want the node vm05 to get:

$ConfigurationData = @{
    AllNodes = @(
        @{
            NodeName="*"
            PSDscAllowPlainTextPassword=$true
            PSDscAllowDomainUser = $true
         }
        @{
            NodeName="vm05"
            NodeGuid = '3f2fb53d-129c-44ff-8fcc-cc2a55ab738b' # $guid #
            CertificateFile = 'C:\Keys\dscSecure.cer'
            Thumbprint = $Thumbprint # '12437D58F28E4E52B63B0FBCF0E34CF4C8BD8797'
         }
    )
}

Configuration WindowsManagementFrameWork5
{
param ([Parameter(Mandatory=$true)] [ValidateNotNullorEmpty()] [PSCredential] $Credential)

    
    Import-DscResource –ModuleName PSDesiredStateConfiguration
    Import-DscResource –ModuleName xWindowsUpdate


    Node $AllNodes.NodeName     
    {        
                
        xHotfix PowerShell5
        {
                Ensure = "Present"
                Id = "KB3134758"
                Path = "\\share\Win8.1AndW2K12R2-KB3134758-x64.msu"
                Credential = $cred
        }
    }
}

WindowsManagementFrameWork5 -ConfigurationData $configurationData -Credential $cred -OutputPath C:\Configs\TargetNodes

#Here I change name of the mof to 3f2fb53d-129c-44ff-8fcc-cc2a55ab738b.mof, then run the:
New-DSCCheckSum -path C:\Configs\TargetNodes

#Then copy this to the C:\Program Files\WindowsPowerShell\DscService\Configuration. I have made sure that i have both modules zipped with their checksum; xPSDesiredStateConfiguration_3.12.0.0.zip and xWindowsUpdate_2.5.0.0.zip

Any tips or advice are welcome!

Brgs

Bjørn.

Based on, “RemoteCertificateNameMismatch, RemoteCertificateChainErrors,” I’d say the problem is definitely in the certificate. Either the name on the certificate is wrong, or it isn’t chaining up to a trusted CA. So, what happens here, and why the LCM’s debug output isn’t all that useful, is that the LCM is just asking Windows to establish the connection. That’s not happening, and so the LCM itself doesn’t have a ton of good data. It just knows it failed. But triple-check the CN on the certificate, and make sure that it’s fully trusted by the node.

In terms of manually setting an SSL cert on the pull server, you just do that in IIS Manager as with any other website. It isn’t special.

Hi Don,
Thank you for the reply.

Ill check the CN on the certificate tomorrow. Europe time :slight_smile:

So if I get this right, ill need to use two certificates:

Pull Server:
When creating a https Pull Server, the certificate I use her should have the Pull Server in CN right?
Do I need to transfer the Pull Servers .cer (Public key to the node)?

Node:
I create all node configurations on my Pull Server.

So when creating a configuration for my node, ill have to use the .cer certificate (public key) from my node’s self-signed certificate PFX (has cn=node.domain.com) to encrypt credentials that I have in the configuration so that the node can decrypt the data.

When setting up the LCM configuration for the node to pull configuration, I use the same certificate (target node’s .cer, public key) to set the LCM remotely from Pull Server right?

Please correct me if I’m wrong, I’m by no means good at certificates.

Brgs

Bjørn Roalkvam

A pull server is just a Web server. The SSL certificate is installed in IIS, and the CN in the certificate must match whatever the clients are using to query the pull server. If they’re trying to query https://barney.funland.org, then that’s what needs to be the CN in the certificate. Nodes don’t get a copy of this any more than you get a copy of Amazon’s certificate ;). However, the nodes must TRUST the certificate, which means whatever CA issued it must be configured as a trusted root on the nodes.

Certificates used to encrypt credentials in a MOF are entirely different. I would focus first on getting your SSL certificate correct. But you’ve got the basic idea correct. However:

“I use the same certificate (target node’s .cer, public key) to set the LCM remotely from Pull Server right?”

I don’t know what that means. “set the LCM remotely from pull server” doesn’t compute for me.

Hi Don,

Thank you, that was clearly explained.

With the part:

I use the same certificate (target node's .cer, public key) to set the LCM remotely from Pull Server right?

I just meant that I’m logged onto the Pull Server and from there using cim to set the node’s LCM with:

$Session = New-CimSession –ComputerName "Server01" –Credential ACCOUNTS\PattiFuller
Set-DscLocalConfigurationManager -Path "C:\DSC\Configurations\" -CimSession $Session

But in the LCM configuration I have then used the public key that was exported from the target node’s PFX certificate. Is it recommended to encrypt LCM configurations this way?

brgs

Bjørn

Hmm. OK.

First of all, you don’t “remotely set the LCM from the Pull Server.” Yes, you can use Set-DscLocalConfigurationManager to remotely configure the LCM, but you can do that from any computer - it doesn’t have to be a pull server. In fact, it’s almost never the pull server. Here’s why: if you remotely log into the pull server (Enter-PSSession), then you’re going to have authentication problems reaching the node’s LCM. If you’re logging into the pull server’s console, or via RDP, then you are doing it wrong. You really shouldn’t be logging into servers that way. That’s why Nano doesn’t have a console or support RDP. So usually, you’re configuring the LCM remotely, either from a workstation, or from an orchestration solution. Or, you’re configuring it by means of MOF injection, talking to it through Hyper-V cmdlets, etc.

So. You’re currently bypassing the authentication problem by specifying credentials, but very honestly, this is a poor practice. There’s no reason this has to come from the pull server.

“But in the LCM configuration I have then used the public key that was exported from the target node’s PFX certificate. Is it recommended to encrypt LCM configurations this way?”

I’ve no idea why you would encrypt the LCM’s configuration, no. Yes, you would specify the node-local certificate that it will use to decrypt credentials within a MOF, but I don’t know what benefit you would have in encrypting the meta-MOF used to configure the LCM.

Hi Don,

Thanks for pointing that out about not running things from the Pull Server. I have to admit that while testing, I’ve been logged onto the Pull Server doing all operations.

I was uncertain about the point of using certificate to encrypt LCM meta. Thanks for clearing that up.

Brgs

Bjørn