public/Compile-AzureDSCConfig.ps1
function Compile-AzureDSCConfig { <# .SYNOPSIS Compiles new Azure DSC Configs. .DESCRIPTION Compiles new Azure DSC Configs. Config's and their associated files should be setup this way where the config name is ExampleDSC_config `.\somefolder\ExampleDSC_config.ps1 `.\somefolder\ExampleDSC_configData.psd1 `.\somefolder\ExampleDSC_params.ps1 `.\somefolder\ExampleDSC_config.ps1 # This file should contain the DSC configuration: Configuration ExampleDSC_config { Import-DscResource –ModuleName 'PSDesiredStateConfiguration' Node $AllNodes { Registry RegistryExample { Ensure = "Present" # You can also set Ensure to "Absent" Key = "HKEY_LOCAL_MACHINE\SOFTWARE\ExampleKey" ValueName = "TestValue" ValueData = "TestData" } } } `.\somefolder\ExampleDSC_configData.psd1 # This file should contain the Node configuration information @{ $AllNodes = @{ @{ NodeName = "Server-123" Role = "management" OS = "Windows NT" ExampleToPass = "Details" }, @{ NodeName = "Server-456" Role = "Web-Server" OS = "Windows NT" ExampleToPass = "OtherDetails" } } } `.\somefolder\ExampleDSC_params.ps1 # This file should contain a hastable of any parameters to pass into the compile process # If no params are needed just create an empty params.ps1 file. @{ Param1 = 'Value1'; Param2 = 'Value2' } .PARAMETER ResourceGroupName Input the Resource Group Name of the Azure Resource Group this DSC config will be published to. Get-AzureRmResourceGroup .PARAMETER AutomationAccountName Input the Automation Account Name of the Azure Automation account this DSC config will be published to. Get-AzureRmAutomationAccount .PARAMETER ConfigFullFilePath Input the full file path to the main DSC config. Ex. D:\somefolder\somebin\ExampleDSC_config.ps1 .EXAMPLE Compile-AzureDSCConfig -ResourceGroupName DSCExampleGroup -AutomationAccountName DSCExampleAccount -ConfigFullFilePath D:\somefolder\somebin\ExampleDSC_config.ps1 #> [cmdletbinding()] Param ( [Parameter(Mandatory=$true)] [string]$ResourceGroupName, [Parameter(Mandatory=$true)] [string]$AutomationAccountName, [Parameter(Mandatory=$true)] [ValidateScript({Test-path $_})] [string]$ConfigFullFilePath ) # check to see if local token exists (ran Login-AzureRMAccount) if (($null -eq (Get-AzureRmContext).Account)) { Write-Warning "Please run < Login-AzureRMAccount > first to create a session token...exiting." break } # Create file variables based on $configfilepath try { #get parent directory $ItemInfo = get-item $ConfigFullFilePath -ErrorAction Stop $ConfigPath = ($ItemInfo).Directory.FullName $ConfigName = ($ItemInfo).Name.Split(".")[0] $ConfigFileName = ($ItemInfo).Name $ConfigDataFileName = "$ConfigName" + "Data.psd1" $ConfigParamsFileName = $ConfigName.Split("_")[0] + "_params.ps1" Write-Verbose $ConfigPath Write-Verbose $ConfigName Write-Verbose $ConfigDataFileName Write-Verbose $ConfigParamsFileName } catch{ Throw ("Please verify the file name and path $ConfigFullFilePath is correct. This file seems to be inaccesible. `r `n" + "The root folder should contain files like this: `r `n" + "ExampleDSC_config.ps1 `r `n" + "ExampleDSC_configData.psd1 `r `n" + "ExampleDSC_params.ps1 `r `n" + $_.Exception.Message) break } #Setup and test vars for each portion of the config file try { if ((Test-Path ($ConfigPath + "\" + $ConfigDataFileName)) -eq $false){ throw "$($ConfigPath + "\" + $ConfigDataFileName) seems to be missing." } Write-Verbose ($ConfigPath + "\" + $ConfigDataFileName) } catch{ Throw ("Please verify the file name $ConfigDataFileName is correct. This file seems to be missing. `r `n" + "The folder $ConfigPath should contain these files based on your config name of $ConfigName : `r `n" + "$ConfigName.ps1 `r `n" + "$ConfigName" + "Data.psd1 `r `n" + $ConfigName.Split("_")[0] + "_params.ps1 `r `n" + $_.Exception.Message) break } try { if ((Test-Path ($ConfigPath + '\' + $ConfigParamsFileName)) -eq $false){ throw "$($ConfigPath + '\' + $ConfigParamsFileName) seems to be missing." } $ParamPath = ($ConfigPath + '\' + $ConfigParamsFileName) Write-Verbose $ParamPath if ((Get-Content $ParamPath).Length -ne 0){ $ConfigParameters = . $ParamPath }else{ $ConfigParameters = $null } } catch { Write-Error ("Please verify the file name $ConfigParamsFileName is correct. This file seems to be missing. `r `n" + "The folder $ConfigPath should contain files like this based on your config name of $ConfigName : `r `n" + "$ConfigName.ps1 `r `n" + "$ConfigName" + "Data.psd1 `r `n" + $ConfigName.Split("_")[0] + "_params.ps1 `r `n" + $_.Exception.Message) break } # build configLiteralPath Try { $ConfigLiteralPath = Get-ChildItem $ConfigPath -Include $ConfigFileName -Recurse -ErrorAction Stop -Verbose $ConfigLiteralPath = $ConfigLiteralPath.FullName } Catch { $error[0].Exception break } Try { $localconfig = Import-LocalizedData -BaseDirectory $ConfigPath -FileName $configdatafilename -ErrorAction Stop -Verbose } Catch { $error[0].Exception break } Try { Import-AzureRmAutomationDscConfiguration -SourcePath $ConfigLiteralPath -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -Published -Force -ErrorAction Stop -Verbose } Catch { $error[0].Exception break } Try { if ($null -eq $ConfigParameters) { $compile = Start-AzureRmAutomationDscCompilationJob -ConfigurationName $ConfigName -ConfigurationData $localconfig -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -Verbose -ErrorAction Stop } else { $compile = Start-AzureRmAutomationDscCompilationJob -ConfigurationName $ConfigName -ConfigurationData $localconfig -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -Parameters $ConfigParameters -Verbose -ErrorAction Stop } } Catch { $error[0].Exception break } Do { Try { $localcompilejob = Get-AzureRmAutomationDscCompilationJob -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -Id $compile.Id -ErrorAction Stop -Verbose Write-Verbose "Compilation job for $($compile.ConfigurationName) not complete." Write-Verbose "Status is $($localcompilejob.Status)" Start-Sleep -Seconds 5 -Verbose } Catch { $error[0].excetion break } } Until (($localcompilejob.Status -eq 'Completed') -or ($localcompilejob.Status -eq 'Suspended')) if (($localcompilejob.Status -eq 'Completed')) { return $localcompilejob } else { Write-Warning "Compilation job did not complete successfully and finished with status $($localcompilejob.Status) $($localcompilejob.Exception)" throw $localcompilejob } } |