Use-Config.ps1
function Use-Config { <# .Synopsis Applies a saved configuration .Description Applies a saved DSC configuration to the local machine, a remote machine, or an azure virtual machine .Example Use-Config MySavedConfig .Example Use-Config MySavedConfig -AzureVirtualMachine myAzureVM .Link Save-Config .Link Get-Config #> [OutputType([PSObject])] param( # The name of the configuration [Parameter(Mandatory=$true,ParameterSetName='ByName',Position=0, ValueFromPipelineByPropertyName=$true)] [String] $Name, # The parameters to the configuration [Parameter(Position=1,ValueFromPipelineByPropertyName=$true)] [Hashtable] $Parameter = @{}, # The name of a computer within your network [string] $ComputerName, # The credential used to run the DSC configuration [Management.Automation.PSCredential] $Credential, # The path to a DSC certificate [Alias('CertificateFile')] [string] $CertificatePath, # The name of an Azure Virtual Machine. Using this requires that you have the Azure PowerShell module installed. #|Options $aModule = Import-Module Azure -Global -Passthru -ErrorAction SilentlyContinue; if ($aModule) { Get-AzureVM | Select-Object -ExpandProperty Name } #|Multisele [Alias('AzureVM')] [string[]] $AzureVirtualMachine ) process { $theCfg = Get-Config -Name $Name if (-not $theCfg) { $foundConfig = $ExecutionContext.SessionState.InvokeCommand.GetCommand("$Name", "Configuration") if ($foundConfig) { Save-Config -Name $foundConfig -Force } else { return } } $progId = Get-Random if ($AzureVirtualMachine) { #region Azure Virutal Machine DSC Resource Use $azureModule = Import-Module Azure -Global -PassThru if (-not $azureModule) { return } Write-Verbose "Publish Started $([DateTime]::Now)" Write-Progress "Publishing Configuration" $theCfg.Path -Id $progId Publish-AzureVMDscConfiguration -ConfigurationPath $theCfg.Path -Force $vmcount = $AzureVirtualMachine.Length $startTime = [DateTime]::Now $progress = @{Id=$progId} $vmCount = 0 foreach ($VMName in $AzureVirtualMachine) { Write-Progress "Getting VM" $VMName @Progress if ($AzureVirtualMachine.Length -gt 1) { $progress.PercentComplete = $vmcount * 100 / $AzureVirtualMachine.Length } $vm = Get-AzureVM $VMName $Splat = @{ ConfigurationName=$theCfg.Name ConfigurationArchive = "$($theCfg.Name).config.ps1.zip" VM = $vm } if ($Parameter -and $Parameter.Count) { $splat.ConfigurationArgument = $Parameter } Write-Progress "Setting DSC Extension" $VMName @Progress $setDsc = Set-AzureVMDscExtension @splat if ($VerbosePreference -ne 'silentlycontinue') { Write-Verbose "DSC Set Result: $($setDsc | Out-String)" Write-Verbose "VM Updated $([DateTime]::Now)" } Write-Progress "Updating VM" $VMName @Progress $updateResult = $vm | Update-AzureVM if ($VerbosePreference -ne 'silentlycontinue') { Write-Verbose "DSC Update Result: $($updateResult | Out-String)" } $vmcount++ } $progress.Remove('PercentComplete') $vmStatus = $null $vmFinishedCount = 0 do { if ($vmStatus) { Start-Sleep -Seconds 1 } foreach ($vmName in $AzureVirtualMachine) { $v = Get-AzureVM $vmName $vmStatus = Get-AzureVMDscExtensionStatus -VM $v -WarningAction SilentlyContinue if ($vmStatus -and $vmStatus.Timestamp -gt $startTime) { Write-Progress "$($vmStatus.Status) " "$($vmStatus.StatusMessage) " @Progress } else { Write-Progress "Waiting for DSC" " " @Progress } if ($vmStatus.Timestamp -gt $startTime -and 'Success', 'Error' -contains $vmStatus.Status) { $vmFinishedCount++ $vmStatus } } } while ($vmFinishedCount -ne $AzureVirtualMachine.Length) Write-Verbose "DSC Complete on VM $([DateTime]::Now)" Write-Progress "$($vmStatus.Status) " "$($vmStatus.StatusMessage) " @Progress -Completed #endregion Azure Virutal Machine DSC Resource Use return } . $theCfg $theRealCfg = $ExecutionContext.SessionState.InvokeCommand.GetCommand($Name, 'Configuration') $dataPath = Join-Path (Join-Path $env:ProgramData "Start-Automating") "cFg" $Splat = $Parameter + @{ OutputPath = "$(Join-Path $dataPath "$Name--$([DateTime]::Now.ToString('o').Replace(':','-'))")" } if ($CertificatePath) { $rp = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($CertificatePath) if (-not $rp) { return } $splat.ConfigurationData = @{ AllNodes = @( @{ NodeName = '*' PSDscAllowPlainTextPassword = $True CertificateFile = "$rp" } @{ NodeName = if ($ComputerName) { $ComputerName } else { 'localhost' } } ) } } $cfgResult = & $theRealCfg @splat if ($cfgResult -and "$($cfgResult.Directory)") { $splat2 = @{ Path = $cfgResult.Directory } if ($ComputerName) { $splat2.ComputerName = $splat2 } if ($credential) { $splat2.Credential = $Credential } Start-DscConfiguration @Splat2 -Wait -Force } } } |