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?