I’m creating a script which;
- Creates a new VM
- Transfers metaconfig.mof to VM, which;
– Sets LCM to Pull mode and grabs GUID.mof which;
— Change hostname
— Change IP
— Dcpromo
Afterwards my script will do psremoting to this machine to create OU structure, install software et cetera.
I need to check if the VM is in the desired state before continuing. But when I grab the Node info from the pull server NodeComplaint equals True and Status equals 0 before the actual dcpromo ran. How can I programmatically wait for DSC to actually finish?
Setting the pull mode:
Configuration SetPullMode {
param(
[string]$guid,
[string]$computername
)
Node $Computername
{
LocalConfigurationManager
{
ConfigurationMode = 'ApplyAndAutoCorrect'
ConfigurationID = $guid
RefreshMode = 'Pull'
DownloadManagerName = 'WebDownloadManager'
DownloadManagerCustomData = @{
ServerUrl = 'http://172.20.20.1:8080/PSDSCPullServer.svc';
AllowUnsecureConnection = 'true'
}
RebootNodeIfNeeded = $True
}
}
}
$Guid = New-Guid SetPullMode -guid $guid -computername localhost
Generating MOF:
Configuration DC01 {
Param (
[PScredential]$Credential
)
Import-DscResource -Module xNetworking,xActiveDirectory,PSDesiredStateConfiguration,xComputerManagement
Node $AllNodes.NodeName {
xComputer ComputerName {
Name = 'DC01'
DependsOn = "[xIPAddress]IPAddress"
}
xIPAddress IPAddress {
InterfaceAlias = "Ethernet"
IPAddress = $AllNodes.IP
AddressFamily = "IPV4"
SubnetMask = $AllNodes.Mask
}
xDefaultGatewayAddress Gateway {
InterfaceAlias = "Ethernet"
AddressFamily = "IPV4"
Address = $AllNodes.Gateway
DependsOn = "[xIPAddress]IPAddress"
}
xDNSServerAddress DNSServer {
InterfaceAlias = "Ethernet"
AddressFamily = "IPV4"
Address = $AllNodes.IP
DependsOn = "[xIPAddress]IPAddress"
}
File ADFiles
{
DestinationPath = 'C:\NTDS'
Type = 'Directory'
Ensure = 'Present'
}
File Unattend
{
DestinationPath = "C:\unattend.xml"
Type = 'File'
Ensure = 'Absent'
}
File WindowsImage
{
DestinationPath = "C:\Convert-WindowsImageInfo.txt"
Type = 'File'
Ensure = 'Absent'
}
WindowsFeature ADDSInstall
{
Ensure = "Present"
Name = "AD-Domain-Services"
}
# Optional GUI tools
WindowsFeature ADDSTools
{
Ensure = "Present"
Name = "RSAT-ADDS"
}
WindowsFeature DotNet35
{
Ensure = "Present"
Name = "Net-Framework-Core"
}
# No slash at end of folder paths
xADDomain FirstDS
{
DomainName = $AllNodes.DomainName
DomainAdministratorCredential = $Credential
SafemodeAdministratorPassword = $Credential
DatabasePath = 'C:\NTDS'
LogPath = 'C:\NTDS'
DependsOn = "[WindowsFeature]ADDSInstall","[File]ADFiles","[xComputer]ComputerName"
}
File Done
{
DestinationPath = "C:\Temp"
Type = 'Directory'
Ensure = 'Present'
DependsOn = "[xADDomain]FirstDS","[WindowsFeature]DotNet35"
}
}
}
Prepare .mof for machine to pull:
$ConfigData = @{
AllNodes = @(
@{
NodeName = "localhost"
DomainName = "$DomainName"
RetryCount = 20
RetryIntervalSec = 30
PsDscAllowPlainTextPassword = $true
PSDscAllowDomainUser = $True
IP=$DC01
Mask=$MaskBits
Gateway=$Gateway
}
)
}
DC01 -ConfigurationData $ConfigData -Credential $DomainCredentials -Verbose
Rename-Item .\DC01\localhost.mof -NewName "$guid.mof"
New-DscChecksum .\DC01
Get-ChildItem .\DC01 | Move-Item -Destination "$env:ProgramFiles\WindowsPowerShell\DscService\Configuration"
After IP and hostname is set the machine reboots; the Pull server tells me:
ConfigurationId NodeCompliant LastComplianceTime StatusCode
372c6f01-c8df-4473-ac9e-c8de841a22d5 True 2016-01-23T12:51:35.3841422Z 0
But LCM is not done yet.
This all works fine if I wait a while but I need some way to check if this process is done before continuing.
I tried this, but that fails because the result looks like completion before the reboot after Dcpromo;
While ($nodeDone -eq $False) {
Write-Verbose "Testing Node compliance..."
$TestNode = (QueryNodeInformation).Value |
Where-Object -Property ConfigurationId -eq $Guid |
Where-Object -Property StatusCode -eq 0 |
Where-Object -Property NodeCompliant -eq $True
Start-Sleep -Seconds 5
If ($TestNode) {$NodeDone = $True}
}
Should I just:
Invoke-Command -ComputerName $DC -Credential $Cred -ScriptBlock {
Get-DscLocalConfigurationManager
}
… and take the errors for granted until .LCMState EQ ‘Idle’
Or am I missing something else?