helpers/helpers.psm1
Function Get-NetworkIHV { param ( [string] $NetAdapterName, [string] $nodeName ) If ($PSBoundParameters.ContainsKey('nodeName')) { $driverName = Get-NetAdapter -Name $NetAdapterName -CimSession $nodeName | Select-Object DriverFileName } else { $driverName = Get-NetAdapter -Name $NetAdapterName | Select-Object DriverFileName } $thisIHV = $drivers.Where{$_.DriverFileName -eq $driverName[$driverName.Count - 1]}.IHV Return $thisIHV } Function Get-DCBClusterNodes { <# .Synopsis Gets a list of cluster nodes .DESCRIPTION Accepts input to retrieve the list of nodes in an existing cluster. Can accept multiple .EXAMPLE Get-DCBClusterNodes -Cluster 'S2DCluster01', 'S2DCluster02' #> Param ( [String[]] $Clusters ) $NodeList = foreach ( $Cluster in $Clusters ) { ( Get-ClusterNode -Cluster $Cluster ).Name } Return $NodeList } [DscLocalConfigurationManager()] Configuration DscMetaConfigs { param ( [Parameter(Mandatory=$True)] [String]$RegistrationUrl, [Parameter(Mandatory=$True)] [String]$RegistrationKey, [Parameter(Mandatory=$True)] [String[]] $ComputerName, [Int] $RefreshFrequencyMins = 30, [Int] $ConfigurationModeFrequencyMins = 15, [String] $ConfigurationMode = 'ApplyAndMonitor', [String] $NodeConfigurationName, [Boolean] $RebootNodeIfNeeded= $False, [String] $ActionAfterReboot = 'ContinueConfiguration', [Boolean] $AllowModuleOverwrite = $False, [Boolean] $ReportOnly ) # https://docs.microsoft.com/en-us/azure/automation/automation-dsc-onboarding#physicalvirtual-windows-machines-on-premises-or-in-a-cloud-other-than-azureaws If (!$NodeConfigurationName -or $NodeConfigurationName -eq '') { $ConfigurationNames = $null } else { $ConfigurationNames = @($NodeConfigurationName)} If ($ReportOnly){ $RefreshMode = 'PUSH' } else { $RefreshMode = 'PULL' } Node $ComputerName { Settings { RefreshFrequencyMins = $RefreshFrequencyMins RefreshMode = $RefreshMode ConfigurationMode = $ConfigurationMode AllowModuleOverwrite = $AllowModuleOverwrite RebootNodeIfNeeded = $RebootNodeIfNeeded ActionAfterReboot = $ActionAfterReboot ConfigurationModeFrequencyMins = $ConfigurationModeFrequencyMins } If (!$ReportOnly) { ConfigurationRepositoryWeb AzureAutomationStateConfiguration { ServerUrl = $RegistrationUrl RegistrationKey = $RegistrationKey ConfigurationNames = $ConfigurationNames } ResourceRepositoryWeb AzureAutomationStateConfiguration { ServerUrl = $RegistrationUrl RegistrationKey = $RegistrationKey } } ReportServerWeb AzureAutomationStateConfiguration { ServerUrl = $RegistrationUrl RegistrationKey = $RegistrationKey } } } Function Publish-Automation { Write-Output 'Beginning Deployment---' $AutomationAcctParams = @{ ResourceGroupName = $configData.NonNodeData.AzureAutomation.ResourceGroupName AutomationAccountName = $configData.NonNodeData.AzureAutomation.AutomationAccountName } $requiredModules = 'xHyper-V', 'NetworkingDSC', 'DataCenterBridging', 'VMNetworkAdapter' Write-Output "Verifying the required modules exist in Azure Automation" foreach ($module in $requiredModules) { $moduleAAAvailability = Get-AzureRmAutomationModule -Name $module @AutomationAcctParams -ErrorAction SilentlyContinue If (!($moduleAAAvailability)) { Write-Output "- $Module did not exist in the Azure Automation account" Write-Output "---Locating Repository Source Location for $Module" $moduleURI = Find-Module -Name $module -ErrorAction SilentlyContinue If ($moduleURI) { Write-Output "-----Importing $Module into the Azure Automation account" $moduleImport = Import-AzureRmAutomationModule -Name $module -ContentLinkUri "$($moduleURI.RepositorySourceLocation)/Package/$module" @AutomationAcctParams while(($moduleImport.ProvisioningState -ne 'Succeeded') -and ($module.ProvisioningState -ne 'Failed')) { Write-Output "-------Waiting for $Module to complete the import" Start-Sleep -Seconds 5 $moduleImport = Get-AzureRmAutomationModule -Name $module @AutomationAcctParams } If ($moduleImport.ProvisioningState -ne 'Succeeded') { throw { Write-Output "!!!Import of Module $module failed!!! Please review the Azure Automation portal for more information." Write-Output "Account Details:" Write-Output -InputObject $AutomationAcctParams } } Else { Write-Output "---------Import of $module Succeeded" } } else { Write-Error "Catastrophic Failure: $Module could not be found in one of the available repositories. Deployment cannot continue!" $failedImport = $true } } Else { Write-Output "Module: $module exists in the Azure Automation account" } } If ($failedImport) { break } Write-Output "Generating MOF for Azure Automation" NetworkConfig -OutputPath "$here\Results\MOFs" -ConfigurationData $configData | Out-Null Write-Output "Importing the DSC Node Configuration to Azure Automation" (Get-ChildItem -Path "$here\Results\MOFs").FullName | Foreach-Object { Import-AzureRmAutomationDscNodeConfiguration -Path $_ -ConfigurationName NetworkConfig -Force @AutomationAcctParams | Out-Null } $AARegistrationInfo = Get-AzureRmAutomationRegistrationInfo @AutomationAcctParams $configData.AllNodes.Role | Select-Object -Unique | ForEach-Object { $thisRole = $_ $Params = @{ RegistrationUrl = "$($AARegistrationInfo.Endpoint)" RegistrationKey = "$($AARegistrationInfo.PrimaryKey)" NodeConfigurationName = "NetworkConfig.$thisRole" ComputerName = $configData.AllNodes.Where{ $_.Role -eq $thisRole }.NodeName RefreshFrequencyMins = 30 ConfigurationModeFrequencyMins = 15 RebootNodeIfNeeded = $False AllowModuleOverwrite = $true ConfigurationMode = 'ApplyAndAutoCorrect' ActionAfterReboot = 'ContinueConfiguration' ReportOnly = $False } Write-Output "Configuring LCM to look at Azure Automation" DscMetaConfigs @Params -OutputPath $here\Results\Meta | Out-Null Set-DscLocalConfigurationManager -Path $here\Results\Meta -Verbose -Force $allNodesWithRole = $configData.AllNodes.Where{$_.Role -eq $thisRole}.NodeName 'Previous', 'Pending', 'Current' | ForEach-Object { Remove-DscConfigurationDocument -Stage $_ -Force -CimSession $allNodesWithRole } Update-DscConfiguration -Verbose -Wait -CimSession $allNodesWithRole } } |