Having issue with dot-sourced DSC configuration

This topic contains 2 replies, has 2 voices, and was last updated by  Jim Bendtsen 2 months, 2 weeks ago.

  • Author
    Posts
  • #76780

    Jim Bendtsen
    Participant

    I've been trying to test and evaluate different methods of applying multiple configurations to a node, then audit them long term. I'm aware of different options including partial configurations, dot-sourcing, and composite configurations. I created 2 unique dsc configurations for a node, one installed sql, one installed the docker service, and applied them successfully. Perhaps not real world realistic, but just a test of dot-sourcing. I then wanted to audit the node for both groups of changes. I found that test-dscconfiguration only reads one .mof, the current.mof on the node (I know about -referenceconfiguration, but getting an audit of multiple applied configs would still require multiple passes). I wanted to both perform multiple, separate configurations, without having to combine everything into one large, monolithic configuration script, and also get be able to run one test-dscconfiguration command and return one audit result, without having to combine multiple test-dscconfiguration commands using -referenceconfiguration. I was unable to get partial-configurations to work, so I turned to dot-sourcing the separate dsc scripts within one, and removing the configuration and node separations in the lower level scripts. I found that the separate scripts worked fine standalone, but the sql script throws an error when dot-sourced.

    The docker service install script works fine, as standalone and in the dot-sourced script. The sql install script works fine standalone, but throws an error when dot-sourced.

    DSC script containing 2 dot-sourced scripts

    #DSC_install_docker-sql-test.ps1
    
    $Nodelist = get-content dsc_install_docker_and_SQL-nodelist.txt 
    $Config = 'DSC_install_docker_and_SQL_test'
    
    $dockersqlnodeconfigdata =
    @{
        AllNodes = @(
            @{
                NodeName 			= '*'
                PSDscAllowPlainTextPassword = $true
                PSDscAllowDomainUser	= $true 
                DomainAdminCredential    = (Get-Credential -message "Enter a Domain Admin ID for the Server Node")              
             }
        )
    }		
    
    ForEach ($Node in $Nodelist) 
    {
    
    	Configuration DSC_install_docker_and_SQL_test
    	{	
    		Import-DscResource –ModuleName 'PSDesiredStateConfiguration'
    		
    		node $node 
    			{ 
    				. ./dsc_install_docker-dotsourced.ps1
    				. ./dscconfig_sqlnodes_serial-dotsourced.ps1
    			}
    	}	
    write-output ".mof file should be in: $config"
    pause
    DSC_install_docker_and_SQL_test -configurationdata $dockersqlnodeconfigdata -outputpath "c:\PROGRAM FILES\WindowsPowerShell\DscService\Configuration\$Config"
    write-host "if you don't see the name of a .mof file here, one was not created"
    pause #good place to pause to verify $node.mof and/or $node.meta.mof file creation.
    }
    
    foreach ($node in $nodelist)
    {
    	$cimsession = ''
        $cimsession = new-cimsession -credential $DomainAdminCredential -computername $Node
        Start-DSCConfiguration -cimsession $cimsession -Path "c:\PROGRAM FILES\WindowsPowerShell\DscService\Configuration\$Config" -wait -Verbose -force 
        $sleepseconds  = 20
    	write-output "Sleeping $sleepseconds seconds before checking DSC Configuration Status...Please wait."
    	start-sleep -seconds $sleepseconds
        Get-DscConfigurationstatus -CimSession $cimsession | select pscomputername,startdate,type,status,mode,numberofresources | format-table -autosize
        (test-dscconfiguration -detailed -cimsession $cimsession).resourcesindesiredstate | select pscomputername,ResourceID,InDesiredState | format-table -autosize
    }     
    
    DSC sql install script standalone
    
    #DSCconfig_SQLNodes_serial.ps1
    
    $Nodelist = get-content dscconfig_sqlnodelist.txt 
    $Config = 'ConfigDSC_SQLNodes_Serial'
    $mofconfigpath = "c:\PROGRAM FILES\WindowsPowerShell\DscService\Configuration\$Config"
    $DomainAdminCredential = Get-Credential -username $env:userdomain\$env:username -message "Domain Administrator UserID and Password for module source, module destination, SQL source, and SQL install"
    $SourceCredential = $DomainAdminCredential
    $Module_Source = "\\se123456\dsc\module_storage"
    $Module_Destination = "c$\program files\windowspowershell\modules"
    
    get-cimsession | remove-cimsession
    $cimsessions = new-cimsession -ComputerName $Nodelist -Credential $SQLInstallCredential 
    
    get-smbmapping | Remove-SmbMapping -Force
    $source_userid = $Sourcecredential.username
    $source_password = $Sourcecredential.getnetworkcredential().password
    
    new-smbmapping -remotepath $module_source -username $source_userid -password $source_password
    
    $source_userid = ""
    $source_password = ""
    
    foreach ($Node in $Nodelist)
    {
        $DestinationCredential = $DomainAdminCredential
        $destination_userid = $destinationCredential.UserName
    	$destination_password = $destinationCredential.getnetworkcredential().password
    	new-smbmapping -remotepath "\\$Node\$module_destination" -username $destination_userid -password $destination_password
        $destination_userid = ""
    	$destination_password = ""
        
        if (-not (test-path "\\$Node\$module_destination\xSQLServer\7.1.0.0\")) 
        {
    	    copy-item -path "$module_source\xSQLServer\7.1.0.0\" -destination "\\$Node\$module_destination\xSQLServer\" -Recurse -Force
        }
        if (-not (test-path "\\$Node\$module_destination\xPSDesiredStateConfiguration\")) 
        {
    	    copy-item -path "$module_source\xPSDesiredStateConfiguration\" -destination "\\$Node\$module_destination\" -Recurse -Force
        }
        get-childitem "\\$Node\$module_destination\xSQLServer" | select fullname
    	get-childitem "\\$Node\$module_destination\xPSDesiredStateConfiguration" | select fullname
    }
    
    $sqlnodeconfigdata = @{
        AllNodes = @(
            @{
                NodeName = '*'
                PSDscAllowPlainTextPassword = $true
                PSDscAllowDomainUser 	= $true
                SQLInstallCredential 	= $DomainAdminCredential
                SQLAdminCredential 		= (Get-Credential -username SA -message "Enter SA credential")
                SourceCredential 		= $DomainAdminCredential
              }
        )  
    }
    
    ForEach ($Node in $Nodelist) 
    {
        $sqlnodeConfigData.AllNodes += @{
            NodeName = $Node
            }
    }
    
    configuration ConfigDSC_SQLNodes_Serial
    
    {    
        Import-DscResource -ModuleName PSDesiredStateConfiguration
        Import-DscResource -Name "xSQLServersetup" -ModuleName "xSQLServer" -ModuleVersion "7.1.0.0"
                
        Node $allnodes.nodename      	
        {     
            WindowsFeature DSC-Service 
            {
                Name    = "DSC-Service"
                Ensure  = "Present"
            }
            WindowsFeature RSAT 
            {
             	Name    = "RSAT"
             	Ensure  = "Present"
            }
            WindowsFeature NET-Framework-Core 
            {
             	Name    = "NET-Framework-Core"
             	Ensure  = "Present"
            }
    #========================================================================================
    
            File xPSDesiredStateConfiguration_Copy 
            {
                Ensure              = "Present"  
                Type                = "Directory" 
                DestinationPath     = "C:\Program Files\WindowsPowerShell\Modules\xPSDesiredStateConfiguration" 
            } 
            File xSQLServer_Add 
            {
                Ensure          = "Present"  
                Type            = "Directory" 
                DestinationPath = "C:\Program Files\WindowsPowerShell\Modules\xSQLServer\7.1.0.0" 
            } 
    #====================================================================        
            xSQLServerSetup  'InstallNamedInstance_IN01' 
            {
                DependsOn = "[File]xSQLServer_Add"
                InstanceName = 'IN01'
                Features = 'SQLENGINE,CONN,BC'
                SQLSYSADMINACCOUNTS = "DEVDOMAIN\Server_Local_Admins", "DEVDOMAIN\MSSQL_Admins"
                SetupCredential = $Node.SQLInstallCredential
                SECURITYMODE = "SQL"
                InstallSharedDir = 'F:\Program Files\Microsoft SQL Server'
                InstallSharedWOWDir = 'F:\Program Files (x86)\Microsoft SQL Server'
                InstanceDir = 'F:\Program Files\Microsoft SQL Server'
                InstallSQLDataDir = 'F:\Program Files\Microsoft SQL Server\MSSQL13.INST2016\MSSQL\Data'
                SourceCredential = $Node.SourceCredential
                SourcePath = "\\se123456\dsc\Sql2016x64Ent"
                UpdateEnabled = 'False'
                ForceReboot = $false
                BrowserSvcStartupType = 'Automatic'
                SAPwd = $Node.SQLAdminCredential
             }
        }
    
    }
    #================ Create .mof file for server/node ============================================
    $sqlnodeconfigdata.allnodes
    pause
    ConfigDSC_SQLNodes_Serial -configurationdata $sqlnodeconfigdata -outputpath $mofconfigpath
    
    foreach($Node in $Nodelist) 
    {
        $cimsession = new-cimsession -ComputerName $Node -Credential $SQLInstallCredential
        Start-DSCConfiguration -cimsession $cimsession -Path $mofconfigpath -wait -Verbose -force
    }
    write-output "Sleeping for 10 seconds before checking DSC Configuration Status for $node..."
    start-sleep -seconds 10
    
    foreach($Node in $Nodelist) 
    {
        Get-DscConfigurationstatus -CimSession $cimsession | select pscomputername,startdate,type,status,mode,numberofresources | format-table -autosize
        (test-dscconfiguration -detailed -computername $node).resourcesindesiredstate | select pscomputername,ResourceID,InDesiredState | format-table -autosize
        (test-dscconfiguration -detailed -computername $node).resourcesnotindesiredstate | select pscomputername,ResourceID,InDesiredState | format-table -autosize
    }
    
    DSC sql install script when dot-sourced in combined dsc script
    
    #DSCconfig_SQLNodes_serial-dotsourced.ps1
    
    $Nodelist = get-content dscconfig_sqlnodelist.txt 
    $Config = 'ConfigDSC_SQLNodes_Serial'
    $mofconfigpath = "c:\PROGRAM FILES\WindowsPowerShell\DscService\Configuration\$Config"
    $DomainAdminCredential = Get-Credential -username $env:userdomain\$env:username -message "Domain Administrator UserID and Password for module source, module destination, SQL source, and SQL install"
    $SourceCredential = $DomainAdminCredential
    $Module_Source = "\\se123456\dsc\module_storage"
    $Module_Destination = "c$\program files\windowspowershell\modules"
    
    get-cimsession | remove-cimsession
    $cimsessions = new-cimsession -ComputerName $Nodelist -Credential $SQLInstallCredential 
    
    get-smbmapping | Remove-SmbMapping -Force
    $source_userid = $Sourcecredential.username
    $source_password = $Sourcecredential.getnetworkcredential().password
    
    new-smbmapping -remotepath $module_source -username $source_userid -password $source_password
    
    $source_userid = ""
    $source_password = ""
    
    foreach ($Node in $Nodelist)
    {
        $DestinationCredential = $DomainAdminCredential
        $destination_userid = $destinationCredential.UserName
        $destination_password = $destinationCredential.getnetworkcredential().password
        new-smbmapping -remotepath "\\$Node\$module_destination" -username $destination_userid -password $destination_password
        $destination_userid = ""
        $destination_password = ""
        
        if (-not (test-path "\\$Node\$module_destination\xSQLServer\7.1.0.0\")) 
        {
    	    copy-item -path "$module_source\xSQLServer\7.1.0.0\" -destination "\\$Node\$module_destination\xSQLServer\" -Recurse -Force
        }
        if (-not (test-path "\\$Node\$module_destination\xPSDesiredStateConfiguration\")) 
        {
    	    copy-item -path "$module_source\xPSDesiredStateConfiguration\" -destination "\\$Node\$module_destination\" -Recurse -Force
        }
        get-childitem "\\$Node\$module_destination\xSQLServer" | select fullname
    	get-childitem "\\$Node\$module_destination\xPSDesiredStateConfiguration" | select fullname
    }
    
    $sqlnodeconfigdata = @{
        AllNodes = @(
            @{
                NodeName = '*'
                PSDscAllowPlainTextPassword = $true
                PSDscAllowDomainUser 	= $true
                SQLInstallCredential 	= $DomainAdminCredential
                SQLAdminCredential 		= (Get-Credential -username SA -message "Enter SA credential")
                SourceCredential 		= $DomainAdminCredential
              }
        )  
    }
    ForEach ($Node in $Nodelist) 
    {
        $sqlnodeConfigData.AllNodes += @{
            NodeName = $Node
            }
    }
    
        Import-DscResource -ModuleName PSDesiredStateConfiguration
        Import-DscResource -Name "xSQLServersetup" -ModuleName "xSQLServer" -ModuleVersion "7.1.0.0"          	
             
            WindowsFeature DSC-Service 
            {
                Name    = "DSC-Service"
                Ensure  = "Present"
            }
            WindowsFeature RSAT 
            {
             	Name    = "RSAT"
             	Ensure  = "Present"
            }
            WindowsFeature NET-Framework-Core 
            {
             	Name    = "NET-Framework-Core"
             	Ensure  = "Present"
            }
    #========================================================================================
    
            File xPSDesiredStateConfiguration_Copy 
            {
                Ensure              = "Present"  
                Type                = "Directory" 
                DestinationPath     = "C:\Program Files\WindowsPowerShell\Modules\xPSDesiredStateConfiguration" 
            } 
            File xSQLServer_Add 
            {
                Ensure          = "Present"  
                Type            = "Directory" 
                DestinationPath = "C:\Program Files\WindowsPowerShell\Modules\xSQLServer\7.1.0.0" 
            } 
    #====================================================================        
            xSQLServerSetup  'InstallNamedInstance_IN01' 
            {
                DependsOn = "[File]xSQLServer_Add"
                InstanceName = 'IN01'
                Features = 'SQLENGINE,CONN,BC'
                SQLSYSADMINACCOUNTS = "DEVDOMAIN\Server_Local_Admins", "DEVDOMAIN\MSSQL_Admins"
                SetupCredential = $Node.SQLInstallCredential
                SECURITYMODE = "SQL"
                InstallSharedDir = 'F:\Program Files\Microsoft SQL Server'
                InstallSharedWOWDir = 'F:\Program Files (x86)\Microsoft SQL Server'
                InstanceDir = 'F:\Program Files\Microsoft SQL Server'
                InstallSQLDataDir = 'F:\Program Files\Microsoft SQL Server\MSSQL13.INST2016\MSSQL\Data'
                SourceCredential = $Node.SourceCredential
                SourcePath = "\\se123456\dsc\Sql2016x64Ent"
                UpdateEnabled = 'False'
                ForceReboot = $false
                BrowserSvcStartupType = 'Automatic'
                SAPwd = $Node.SQLAdminCredential
            }
      
    

    Error when running dsc sql script as dot-sourced

    PS C:\Program Files\WindowsPowerShell\DscService\Configuration> .\dsc_install_docker-sql-test.ps1
    PSDesiredStateConfiguration\node : The term 'xSQLServer\xSQLServerSetup' is not recognized as the name of a cmdlet,
    function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the
    path is correct and try again.
    At C:\Program Files\WindowsPowerShell\DscService\Configuration\dsc_install_docker-sql-test.ps1:38 char:3
    + node $node
    + ~~~~
    + CategoryInfo : ObjectNotFound: (xSQLServer\xSQLServerSetup:String) [PSDesiredStateConfiguration\node],
    ParentContainsErrorRecordException
    + FullyQualifiedErrorId : CommandNotFoundException,PSDesiredStateConfiguration\node

    Compilation errors occurred while processing configuration 'DSC_install_docker_and_SQL_test'. Please review the errors
    reported in error stream and modify your configuration code appropriately.
    At
    C:\Windows\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:3917
    char:5
    + throw $ErrorRecord
    + ~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (DSC_install_docker_and_SQL_test:String) [], InvalidOperationException
    + FullyQualifiedErrorId : FailToProcessConfiguration

    PS C:\Program Files\WindowsPowerShell\DscService\Configuration>

    Does anyone have any advice on what the cause of the error could be, and how to resolve it?

  • #76785

    Geraldo
    Participant

    Well... line 38 is foreach ($node in $nodelist)
    So my quess is that either $nodelist or $node has an invalid value.....

    Any way you post the contents of dsc_install_docker_and_SQL-nodelist.txt?

    • #76888

      Jim Bendtsen
      Participant

      The values in dsc_install_docker_and_sql-nodelist.txt, dsc_install_docker_nodelist.txt, and dscconfig_sqlnodelist.txt are the same, one line containing "SE123456" no quotes (changed from actual), but same in all 3 files. I was only working against one server which had the dual DSC configs applied.

      When used in the dot-sourced script, it asks for credentials, then enters the SQL dot-sourced script to ask for credentials, then after getting them, fails.

      
      #DSC_install_docker-dotsourced.ps1
      
      $Config = 'DSC_Install_Docker'
      $Nodelist = get-content dsc_install_docker_nodelist.txt 
      
      $dockerconfigurationdata = @{ 
          AllNodes = @(
          	@{
          	    NodeName 			= '*'
                  PSDscAllowPlainTextPassword = $true
                  PSDscAllowDomainUser 	= $true
                 InstallCredential 		= (Get-Credential -message "Enter an Admin ID to Install Docker on Servers")               	
      	}	
          )  
      }
      
      ForEach ($Node in $Nodelist) 
      {
          $dockerconfigurationdata.AllNodes += @{
              NodeName 	= $Node
              }
          
          Import-DscResource -ModuleName PSDesiredStateConfiguration
                      
          
          	LocalConfigurationManager
          	{
          		RebootNodeIfNeeded = $true
          	}	        
              
              WindowsFeature Containers
              {
                  Name    	= 'Containers'
                  Ensure  	= 'Present'
              }     
          
          File Copy_NugetPackageManagement_Provider 
              {
              	Ensure					= 'Present'  
                  Type               		= 'File' 
              	PSDSCRunAsCredential	= $InstallCredential
                  SourcePath         		= "\\se131346\dsc\PackageManagement\ProviderAssemblies\nuget\2.8.5.208\Microsoft.PackageManagement.NuGetProvider.dll"
                  DestinationPath    		= "C:\Program Files\PackageManagement\ProviderAssemblies\nuget\2.8.5.208\Microsoft.PackageManagement.NuGetProvider.dll" 
              	MatchSource 			= $true
              	Force				= $true
              }     
              
          Script Register_Repositories
              {
              	DependsOn = '[File]Copy_NugetPackageManagement_Provider'     
                  GetScript =
                  {
                      $repository = (Get-PSRepository).name
                      return @{ 'Repository' = $repository }
                  }
      
                  SetScript =
                  {
                      register-psrepository -name "RBCDevRepository" -sourcelocation "http://se131348:81/nuget/rbcdevrepository" -installationpolicy trusted –packagemanagementprovider nuget
                      #register-psrepository -name "SMBRepository" -sourcelocation "\\se131346\psrepository" -installationpolicy trusted -packagemanagementprovider nuget
                  }
                  
                  TestScript = 
                  {
                      $CurrentRepository = (Get-PSRepository).name
                      $CorrectRepository = 'RBCDevRepository'
                      if ($CurrentRepository -eq $CorrectRepository)
                      {
                          Write-Verbose -Message "Correct Repository $CorrectRepository IS REGISTERED"
                          return $true
                      } else 
                      {
                          Write-Verbose -message "Correct Repository $CorrectRepository IS NOT REGISTERED"
                          return $false                     
                      }
                  }
              }
          
          Script Install_DockerMSFTProvider #don't need if doing manual install?
          	{
                  GetScript =
                  {
                      $PackageInstalled = (get-module -ListAvailable dockermsftprovider).name
                      return @{"DockerMsftProvider Package is installed" = ($PackageInstalled -eq "DockerMsftProvider")}                 
                  }
                
                  SetScript =
                  {
                      Install-Package -name 'dockermsftprovider' -source 'RBCDevrepository' -force
                  }
                  TestScript =
                  {
                      $PackageInstalled = (get-module -ListAvailable dockermsftprovider).name
                      if  ($PackageInstalled -eq "DockerMsftProvider")
                          {    
                              Write-Verbose "DockerMsftProvider IS INSTALLED"  
                              return $true                                      
                          } else 
                          {
                              Write-Verbose "DockerMsftProvider IS NOT INSTALLED"
                              return $false
                          }
                  }                       
              } 
         
          Script Install_Docker_Service
          {
                  GetScript =
                  {
                      $PackageSaved = (test-path "c:\program files\docker\dockerd.exe")
                      return @{"Docker Package is saved" = $PackageSaved}                 
                  }
                
                  SetScript =
                  {
                      save-package -name Docker-EE -requiredversion 17.3.0 -source rbcdevrepository -path "c:\temp" -force
                      if (! (test-path "c:\program files\docker")) {new-item -path "c:\program files\docker" -type directory} 
                      copy-item "c:\temp\docker-ee\17.3.0\docker*.exe" "c:\program files\docker\" 
                      start-process "c:\program files\docker\dockerd.exe" -argument '--register-service' -wait               
                  }
                  
                  TestScript =
                  {
                      $PackageSaved = (test-path "c:\program files\docker\dockerd.exe")
                      if  ($PackageSaved -eq "True")
                          {    
                              Write-Verbose "DockerPackage IS SAVED"  
                              return $true                                      
                          } else 
                          {
                              Write-Verbose "DockerPackage IS NOT SAVED"
                              return $false
                          }
                  }                       
          } 
      
          Service Set_and_Verify_Docker_Service
              {
                  DependsOn 		= '[Script]Install_Docker_Service'
                  BuiltInAccount 	= 'LocalSystem'
      	    StartupType 	= 'Automatic'
          	#State 			= 'Running' #possibly eliminate this if an issue? might not be able to check for running during install, but only during subsequent checks
          		Description 	= "Docker Container Service"
          		DisplayName 	= "Docker Engine"
          		Ensure 		= 'Present'
          		Path 		= '"c:\program files\docker\dockerd.exe" --run-service'   
          		Name		= 'Docker'         
              }    
      }	
      
      

You must be logged in to reply to this topic.