First real crack at DSC… I’ve created an Active Directory server, and a CA using push configurations since those seem to be the requirements for a HTTPS Pull Server. I am running into an issue attempting to request a certificate in the same configuration that creates the pull server.
The CertReq resource works perfectly to request the certificate, but populating the Thumbprint from that certificate to the xDSCWebService resource is very challenging. I’m trying to acquire the thumbprint programatically with the following :
CertificateThumbPrint = (Get-ChildItem 'Cert:\LocalMachine\My\' | Where-Object { $_.Subject -eq 'CN=Pull01'}).Thumbprint.ToString()
PSDesiredStateConfiguration\Node : You cannot call a method on a null-valued expression.Presumably because the certificate does not exist yet.
I know I can request the certificate via command line and feed the proper values to the script, but I’d love to be able to do everything directly inside the script, thus creating a single DSC configuration file for each host, and I can recreate my environment.
Is there any way to request the certificate and provide the proper values from that certificate?
Full DSC Configuration file below… Thanks in advance!
Configuration Build-Pull01 {
Param (
[Parameter(Mandatory)]
[pscredential]$CredDomain,
[ValidateNotNullOrEmpty]
[string]$CertificateFile,
#[ValidateNotNullOrEmpty]
#[string]$DSCCertThumbprint,
[ValidateNotNullOrEmpty]
[string]$DSCRegistration
)
Import-DscResource -ModuleName xPSDesiredStateConfiguration
Import-DscResource -ModuleName ComputerManagementDsc
Import-DscResource -ModuleName NetworkingDsc
Import-DscResource -ModuleName PSDscResources
Import-DscResource -ModuleName CertificateDsc
Node localhost {
LocalConfigurationManager {
ActionAfterReboot = 'ContinueConfiguration'
ConfigurationMode = 'ApplyOnly'
RebootNodeIfNeeded = $true
}
NetIPInterface EnableDHCP {
InterfaceAlias = $Node.IPInterfaceAlias
AddressFamily = $Node.IPAddressFamily
Dhcp = 'Enabled'
}
DnsServerAddress NewDnsAddress {
InterfaceAlias = $Node.IPInterfaceAlias
AddressFamily = $Node.IPAddressFamily
Validate = $true
DependsOn = '[NetIPInterface]EnableDHCP'
}
Computer JoinDomain {
Name = $Node.ComputerName
DomainName = $Node.IPDomainName
Credential = $CredDomain
DependsOn = '[DnsServerAddress]NewDnsAddress'
}
WindowsFeature DSCServiceInstall {
Ensure = 'Present'
Name = 'DSC-Service'
DependsOn = '[Computer]JoinDomain'
}
WaitForCertificateServices WaitForADCS {
CAServerFQDN = 'Cert01.dummydomain.local'
CARootName = 'dummydomain-CERT01-CA'
DependsOn = '[WindowsFeature]DSCServiceInstall'
}
CertReq PullCert {
Credential = $CredDomain
Subject = 'Pull01'#'CN=Pull01, OU=IT, O=dummydomain, L=City, S=CA, C=US'
KeyLength = 2048
CAServerFQDN = 'Cert01.dummydomain.local'
CARootName = 'dummydomain-CERT01-CA'
ProviderName = '"Microsoft RSA SChannel Cryptographic Provider"'
AutoRenew = $true
Exportable = $true
FriendlyName = 'PullServerCert'
KeyUsage = '0xa0'
RequestType = 'PKCS10'
KeyType = 'RSA'
CertificateTemplate = 'WebServer'
DependsOn = '[WaitForCertificateServices]WaitForADCS'
}
xDSCWebService PullServer {
Ensure = 'Present'
EndpointName = 'Pull01'
CertificateThumbPrint = (Get-ChildItem 'Cert:\LocalMachine\My\' | Where-Object { $_.Subject -eq 'CN=Pull01'}).Thumbprint.ToString()
Port = 8080
State = 'Started'
PhysicalPath = $Node.DSCPhysicalPath
ModulePath = $Node.DSCModulePath
ConfigurationPath = $Node.DSCConfigurationPath
RegistrationKeyPath = $Node.DSCRegistrationKeyPath
UseSecurityBestPractices = $true
DependsOn = '[CertReq]PullCert'
}
File RegistrationKeyFile {
Ensure = 'Present'
Type = 'File'
DestinationPath = $Node.FileDSCRegistrationPath
Contents = $DSCRegistration
DependsOn = '[xDSCWebService]PullServer'
}
}
}
$ConfigData = @{
AllNodes = @(
@{
NodeName = ‘localhost’
IPInterfaceAlias = ‘Ethernet0’
IPAddressFamily = ‘IPv4’
IPDomainName = ‘dummydomain.local’
ComputerName = ‘Pull01’
DSCPhysicalPath = “$env:SystemDrive\inetpub\PullServer”
DSCModulePath = “$env:PROGRAMFILES\WindowsPowerShell\DscService\Modules”
DSCConfigurationPath = “$env:PROGRAMFILES\WindowsPowerShell\DscService\Configuration”
DSCRegistrationKeyPath = “$env:PROGRAMFILES\WindowsPowerShell\DscService”
FileDSCRegistrationPath = “$env:ProgramFiles\WindowsPowerShell\DscService\RegistrationKeys.txt”
PSDScAllowDomainUser = $true
PSDscAllowPlainTextPassword = $true
}
)
}
$CredDomain = Get-Credential -Message ‘Enter Domain Credentials’ -UserName ‘dummydomain\administrator’
$DSCRegistration = (New-Guid).ToString()
Build-Pull01 -ConfigurationData $ConfigData -Verbose -CredDomain $CredDomain -DSCRegistration $DSCRegistration -CertificateFile $CertificateFile
Start-DscConfiguration -Wait -Force -Path 'c:\Build-Pull01' -Verbose