DSCTools.psm1
#Requires -Version 4.0 ########################################################################################################################################## # DSCTools ########################################################################################################################################## # See README.md for additional information. # Github Repo: https://github.com/PlagueHO/Powershell/tree/master/DSCTools # Script Center: https://gallery.technet.microsoft.com/scriptcenter/DSC-Tools-c96e2c53 ########################################################################################################################################## # DSC Configurations for configuring DSC Pull Server and LCM # These sections are now containined in separate files found in the .\Configurations folder. # This is so that this module will load even if the configurations contain import-dscresource commands that import resources # That aren't available on the local computer. For example if the computer being used has not yet had the DSC Resource Kit Installed. ########################################################################################################################################## # Available Configuration Files # ----------------------------- # Configuration Config_SetLCMPullMode # Configuration Config_SetLCMPushMode # Configuration Config_EnablePullServerHTTP # Configuration Config_EnablePullServerSMB ########################################################################################################################################## ########################################################################################################################################## # Default Configuration Variables ########################################################################################################################################## # The DSCTools module contains some script variables that can be changed to allow the default properties # of the module to be changed. This helps reduce the number of parameters that need to be passed to each # DSCTools function if you want to configure your DSC system with parameters other than the default. # This is the name of the pull server that will be used if no pull server parameter is passed to functions # Setting this value is a lazy way of using a different pull server (rather than passing the pullserver parameter) # to each function that needs it. [System.String] $Script:DSCTools_DefaultPullServerName = 'localhost' # This is the protocol that will be used by the DSC machines to connect to the pull server. This must be HTTP or HTTPS. # If HTTPS is used then the HTTPS certificate on your Pull server must be trusted by all DSC Machines. # This can also be set to SMB to use a pull server SMB share. [System.String] $Script:DSCTools_DefaultPullServerProtocol = 'HTTP' # This is the default endpoint name a Pull server will be created as when it is installed by Enable-DSCPullServer. [System.String] $Script:DSCTools_DefaultPullServerEndpointName = 'PSDSCPullServer' # This is the default endpoint name a Compliance server will be created as when it is installed by Enable-DSCPullServer. [System.String] $Script:DSCTools_DefaultComplianceServerEndpointName = 'PSDSCComplianceServer' # This is the location of the powershell modules folder where all the resources can be found that will be # Installed into the pull server by the Publish-DscPullResources function. [System.String] $Script:DSCTools_DefaultResourcePath = "$($ENV:PROGRAMFILES)\WindowsPowerShell\Modules\All Resources\" # This is the default folder on your pull server where any resources will get copied to by the # Publish-DscPullResources function. This can be a UNC path to a network share if required. # This path may also be used by the Enable-DSCPullServer cmdlet as well. [System.String] $Script:DSCTools_DefaultPullServerResourcePath = "$($ENV:PROGRAMFILES)\WindowsPowerShell\DscService\Modules\" # This is the default folder where a DSC Pull Server will try and locate node configuraiton files. # This should usually be a local path accessebile by the DSC Pull Server. [System.String] $Script:DSCTools_DefaultPullServerConfigurationPath = "$($ENV:PROGRAMFILES)\WindowsPowerShell\DscService\Configuration\" # This is the path and svc name component of the uRL used to access the Pull server. [System.String] $Script:DSCTools_DefaultPullServerPath = 'PSDSCPullServer.svc' # This is the default folder where a new DSC Pull Server IIS Web Site will be installed. # This should always be a folder on the local DSC Pull Server. [System.String] $Script:DSCTools_DefaultPullServerPhysicalPath = "$($ENV:SystemDrive)\inetpub\wwwroot\PSDSCPullServer\" # This is the port the Pull server is running on. [System.Uint32] $Script:DSCTools_DefaultPullServerPort = 8080 # This is the default folder where a new DSC Compliance Server IIS Web Site will be installed. # This should always be a folder on the local DSC Pull Server. [System.String] $Script:DSCTools_DefaultComplianceServerPhysicalPath = "$($ENV:SystemDrive)\inetpub\wwwroot\PSDSCComplianceServer\" # This is the port the Compliance server is running on. [System.Uint32] $Script:DSCTools_DefaultComplianceServerPort = 8090 # This is the URL to download the current version of the DSC Resource Kit. # It may change when newer versions of the resource kit are released. [System.String] $Script:DSCTools_ResourceKitURL = "https://gallery.technet.microsoft.com/scriptcenter/DSC-Resource-Kit-All-c449312d/file/131371/4/DSC%20Resource%20Kit%20Wave%2010%2004012015.zip" # This is the default folder the functions Start-DSCPull, Start-DSCPush and Update-DSCNodeConfiguration functions will look for # MOF files for node configuration. In future they may also look for PS1 files that can be converted to MOF files. [System.String] $Script:DSCTools_DefaultNodeConfigSourceFolder = "$HOME\Documents\" # This is the version of PowerShell that the Configuration files should be built to use. # This is for future use when WMF 5.0 is available the LCM configuration files can be # written in a more elegant fashion. Currently this should always be set to 4.0 [Float] $Script:DSCTools_PSVersion = 4.0 ########################################################################################################################################## # Internal Module Variables/Constants ########################################################################################################################################## # Get the PS Version to a variable for easier access. [System.Uint32] $Script:PSVersion = $PSVersionTable.PSVersion.Major # This is the location the latest version of the DSCTools module can be downloaded from. [System.String] $Script:DSCTools_ModuleDownloadURL = 'https://github.com/PlagueHO/Powershell/raw/master/DSCTools/Package/DSCTools.zip' ########################################################################################################################################## ########################################################################################################################################## # Support Functions ########################################################################################################################################## function InitZip { # If PS is version 4 or less then we require the PSCX Module to unzip/zip files if ($Script:PSVersion -lt 5) { # Is the PSCX Module Available? if ( (Get-Module -ListAvailable PSCX | Measure-Object).Count -eq 0) { throw "PSCX Module is not available. Please download it from http://pscx.codeplex.com/" } # If Import-Module PSCX } # If } # function InitZip function UnzipFile ([System.String] $ZipFileName, [System.String] $DestinationPath) { if ($Script:PSVersion -lt 5) { Expand-Archive -Path $ZipFileName -OutputPath $DestinationPath -Force } else { Expand-Archive -Path $ZipFileName -DestinationPath $DestinationPath -Force } # If } # function UnzipFile function ZipFolder ([System.String] $ZipFileName, [System.String] $SourcePath) { if ($Script:PSVersion -lt 5) { Get-ChildItem -Path $SourcePath -Recurse | Write-Zip -IncludeEmptyDirectories -OutputPath $ZipFileName -EntryPathRoot $SourcePath -Level 9 } else { Compress-Archive -DestinationPath $ZipFileName -Path "$SourcePath\*" -CompressionLevel Optimal } # If } # function ZipFolder function IsLocalHost ([System.String] $Name) { Return (($Name -match 'localhost') -or ($Name -match '127.0.0.1') -or ("$Name." -match "$ENV:COMPUTERNAME\.")) } # function IsLocalHost ########################################################################################################################################## <# .SYNOPSIS Checks for updated versions of the DSCTools module and installs the udpated version if it is available. .DESCRIPTION This will look online for an updated version of the DSC Tools module and download it and install it if it is available. It currently always downloads and installs the latest version from the GitHub Repository: https://github.com/PlagueHO/Powershell/raw/master/DSCTools/Package/DSCTools.zip However, once the PowerShell Gallery is publicly available and if WMF 5.0 is installed then the Install-Module/Update-Module can be used. If PS 4 is used then this function requires the PSCX module to be available and installed on this computer. PSCX Module can be downloaded from http://pscx.codeplex.com/ .EXAMPLE Update-DSCTools Will update the DSCTools module. .LINK http://pscx.codeplex.com/ #> function Update-DSCTools { [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param () if ($pscmdlet.ShouldProcess($ENV:COMPUTERNAME, "Install the latest version of DSCTools module?")) { InitZip # Download the module zip file DSCTools.zip [System.String] $TempPath = Join-Path -Path $ENV:TEMP -ChildPath DSCTools.zip Write-Verbose -Message "Update-DSCTools: Downloading $Script:DSCTools_ModuleDownloadURL to $TempPath" try { Invoke-WebRequest $Script:DSCTools_ModuleDownloadURL -OutFile $TempPath } catch { throw } # Unzip the Module [System.String] $ModuleDest = Split-Path $PSScriptRoot Write-Verbose -Message "Update-DSCTools: Unzipping $TempPath to $ModuleDest" UnzipFile -ZipFileName $TempPath -DestinationPath $ModuleDest # Reload the module Write-Verbose -Message "Update-DSCTools: Unloading current DSCTools Module" Remove-Module DSCTools Write-Verbose -Message "Update-DSCTools: Loading new DSCTools Module" Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'DSCTools.psm1') Write-Verbose -Message "Update-DSCTools: Deleting Module Package $TempPath" Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'DSCTools.psm1') } } # function Update-DSCTools <# .SYNOPSIS Forces the LCM on the specified nodes to trigger a DSC check. .DESCRIPTION This function will cause the Local Configuration Manager on the nodes provided to trigger a DSC check. If a node is set for pull mode then the latest DSC configuration will be pulled down from the pull server. If a node is in push mode then the current DSC configuration will be used. The command is executed via a call to Invoke-Command on the destination computer's LCM which will be called via WinRM. Therefore WinRM must be enabled on the destination computer's LCM and the appropriate firewall ports opened. .PARAMETER ComputerName This parameter should contain a list of computers that will have the a DSC check triggered. .PARAMETER Nodes This must contain an array of hash tables. Each hash table will represent a node that a DSC check should be triggered. This parameter is provided to be consistent with the Start-DSCPullMode and Start-DSCPushMode functions. The hash table must contain the following entries (other entries will be ignored): Name = For example: @(@{Name='SERVER01'},@{Name='SERVER02'}) .PARAMETER SkipConnectionCheck Some machines will falsely return that they are not contactable when they are actually able to be contacted. This swtich causes the cmdlet to skip the connection test to each node and will always allow the check to be performed. .EXAMPLE Invoke-DSCCheck -ComputerName SERVER01,SERVER02,SERVER03 Causes the LCMs on computers SERVER01, SERVER02 and SERVER03 to repull DSC Configuration MOF files from the DSC Pull server. .EXAMPLE Invoke-DSCCheck -Nodes @(@{Name='SERVER01'},@{Name='SERVER02'}) Causes the LCMs on computers SERVER01 and SERVER02 to repull DSC Configuration MOF files from the DSC Pull server. #> function Invoke-DSCCheck { [CmdletBinding()] param ( [Parameter( ParameterSetName = 'ComputerName', ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true )] [String[]]$ComputerName, [Parameter( ParameterSetName = 'Nodes' )] [Array] $Nodes, [Switch] $SkipConnectionCheck = $false ) # Param Begin { } Process { if ($null -eq $ComputerName) { # Load all the nodes into the computername array. $ComputerName = @() foreach ($Node In $Nodes) { $ComputerName += $Node.Name } # foreach } # foreach foreach ($Computer In $ComputerName) { # If PS5 is installed then the Update-DscConfiguration command can be called -otherwise we need to # use Invoke-CimMethod on the remote host. if (IsLocalHost($Computer)) { if ($Script:PSVersion -lt 5) { Write-Verbose -Message "Invoke-DSCCheck: Invoking Method PerformRequiredConfigurationChecks on Localhost" # For some reason using the Invoke-CimMethod cmdlet with the -ComputerName parameter doesn't work # So the Invoke-Command is used instead to execute the command on the destination computer. Invoke-CimMethod ` -Namespace 'root/Microsoft/Windows/DesiredStateConfiguration' ` -ClassName 'MSFT_DSCLocalConfigurationManager' ` -MethodName 'PerformRequiredConfigurationChecks' ` -Arguments @{ Flags = [uint32]1 } } else { Write-Verbose -Message "Invoke-DSCCheck: Calling Update-DscConfigration on Localhost" Update-DscConfiguration } # If } else { if (($SkipConnectionCheck) -or (Test-Connection -ComputerName $Computer -Count 1 -Quiet)) { if ($Script:PSVersion -lt 5) { Write-Verbose -Message "Invoke-DSCCheck: Invoking Method PerformRequiredConfigurationChecks on node $Computer" # For some reason using the Invoke-CimMethod cmdlet with the -ComputerName parameter doesn't work # So the Invoke-Command is used instead to execute the command on the destination computer. Invoke-Command -ComputerName $Computer { ` Invoke-CimMethod ` -Namespace 'root/Microsoft/Windows/DesiredStateConfiguration' ` -ClassName 'MSFT_DSCLocalConfigurationManager' ` -MethodName 'PerformRequiredConfigurationChecks' ` -Arguments @{ Flags = [uint32]1 } } # Invoke-Command } else { Write-Verbose -Message "Invoke-DSCCheck: Calling Update-DscConfigration on node $Computer" Update-DscConfiguration -ComputerName $Computer } # If } else { Write-Error -Message "Invoke-DSCCheck: Error contacting $Computer. DSC check could not be triggered." } } # If } # foreach ($Computer In $ComputerName) } # Process End { } } # function Invoke-DSCCheck <# .SYNOPSIS Publishes DSC Resources to a DSC pull server. .DESCRIPTION This function takes a path where all the source DSC resources are contained in subfolders. These resources will then be zipped up and renamed based on the manifest version found in the resource. A checksum file will also be created for each resource zip. The resource zip and checksum will then be moved into the folder provided in the PullServerResourcePath paramater. If PS 4 is used then this function requires the PSCX module to be available and installed on this computer. PSCX Module can be downloaded from http://pscx.codeplex.com/ .PARAMETER ModulePath This is the path containing the folders containing all the DSC resources. If this is not passed the default path of "c:\program files\windowspowershell\modules\" will be used. .PARAMETER PullServerResourcePath This is the destination path to which the zipped resources and checksum files will be written to. The user running this command must have write access to this folder. If this parameter is not set the path will be set to: c:\Program Files\WindowsPowerShell\DscService\Modules .EXAMPLE Publish-DscPullResources -ModulePath 'c:\program files\windowspowershell\modules\all resources\a*' ` -PullServerResourcePath '\\DSCPullServer\c$\program files\windowspowershell\DSCService\Modules' This will cause all resources found in the c:\program files\windowspowershell\modules\all resources\ folder starting with the letter A to be zipped up and copied into the folder \\DSCPullServer\c$\program files\windowspowershell\DSCService\Modules A checksum file will also be created for each zipped resource. .EXAMPLE Publish-DscPullResources -ModulePath 'c:\program files\windowspowershell\modules\all resources\*' This will cause all resources found in the c:\program files\windowspowershell\modules\all resources\ folder to be zipped up and copied into the folder found in the default variable $Script:DSCTools_DefaultPullServerResourcePath. A checksum file will also be created for each zipped resource. .EXAMPLE 'c:\program files\windowspowershell\modules\all resources\','c:\powershell\modules\' | Publish-DscPullResources ` -PullServerResourcePath '\\DSCPullServer\c$\program files\windowspowershell\DSCService\Modules' This will cause all resources found in either the c:\program files\windowspowershell\modules\all resources folder or c:\powershell\modules\ folder to be zipped up and copied into the folder \\DSCPullServer\c$\program files\windowspowershell\DSCService\Modules A checksum file will also be created for each zipped resource. .LINK http://pscx.codeplex.com/ #> function Publish-DscPullResources { [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true)] [Alias('FullName')] [System.String[]] $ModulePath = $Script:DSCTools_DefaultResourcePath, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $PullServerResourcePath = $Script:DSCTools_DefaultPullServerResourcePath ) # Param Begin { InitZip # Check the Pull Server Resource Path exists. if ((Test-Path -Path $PullServerResourcePath -PathType Container) -eq $false) { throw "Folder $PullServerResourcePath could not be found." } } # Begin Process { foreach ($path in $ModulePath) { Write-Verbose -Message "Publish-DscPullResources: Examining $Path for Resource Folders" if (Test-Path -Path $path -PathType Container) { # This path in the source path array is a folder Write-Verbose -Message "Publish-DscPullResources: Folder $Path Found" # Get all the subfolders $resources = Get-ChildItem -Path $path -Attributes Directory foreach ($resource in $resources) { Write-Verbose -Message "Publish-DscPullResources: Possible Resource Folder $resource Found" # A folder was found inside the source path - does it contain a resource? $resourceName = Split-Path -Path $resource -Leaf $manifests = Get-ChildItem -Path $resource -Filter "$resourceName.psd1" -Recurse foreach ($manifest in $manifests) { $resourcePath = Split-Path -Path ($manifest.FullName) -Parent $dscResourcesFolder = Join-Path -Path $resourcePath -ChildPath 'DSCResources' if ((Test-Path -Path $resourcePath -PathType Container) -and (Test-Path -Path $dscResourcesFolder -PathType Container)) { Write-Verbose -Message "Publish-DscPullResources: Resource $resourceName in Resource Folder $resourcePath Found" # This folder appears to contain a valid DSC Resource # Get the version number out of the manifest file $manifestContent = Invoke-Expression -Command (Get-Content -Path $($manifest.FullName) -Raw) $moduleVersion = $manifestContent.ModuleVersion Write-Verbose -Message "Publish-DscPullResources: Resource $resourceName in Resource Folder $resourcePath is Version $moduleVersion" # Generate the Zip file name (including the destination to the pull server folder) $zipFileName = Join-Path -Path $PullServerResourcePath -ChildPath "$($resourceName)_$($moduleVersion).zip" # Zip up the resource straight into the pull server resources path if (Test-Path -Path $zipFileName) { Write-Verbose -Message "Publish-DscPullResources: Deleting Existing Resource File $zipFileName" Remove-Item -Path $zipFileName } Write-Verbose -Message "Publish-DscPullResources: Zipping $resourcePath to $zipFileName" ZipFolder -ZipFileName $zipFileName -SourcePath $resourcePath # Generate the checksum for the zip file $null = New-DSCCheckSum -ConfigurationPath $zipFileName -Force Write-Verbose -Message "Publish-DscPullResources: Checksum for Resource File $zipFileName Created" } # If } # foreach ($manifest in $manifests) } # foreach ($resource in $resources) } else { Write-Verbose -Message "Publish-DscPullResources: File $path Is Ignored" } # If } # foreach ($path in $modulePath) } # Process End { } } # function Publish-DscPullResources <# .SYNOPSIS Downloads and installs the DSC Resource Kit. It can also optionally publish the Resources to a pull server. .DESCRIPTION The DSC Resource Kit is a set of DSC Resources and other tools that are commonly used by DSC servers and nodes. It can be downloaded manually from the Microsoft Script Center Gallery. This function will attempt to download this file automatically and install it to the c:\program files\windows powershell\modules folder on this computer. If PS 4 is used then this function requires the PSCX module to be available and installed on this computer. PSCX Module can be downloaded from http://pscx.codeplex.com/ .PARAMETER ResourceKitURL This is the URL to use to download the DSC Resource Kit from. It defaults to the URL contained in $Script:DSCTools_ResourceKitURL. .PARAMETER ModulePath This optional parameter allows an alternate folder to install the DSC Resource Kit into. By default it will be installed into $($ENV:PROGRAMFILES)\windowspowershell\modules The Resouce Kit zip file contains a single folder called All Resources that will be created within the Modules folder. All Resources will be inside this folder. All other cmdlets default to using this folder. .PARAMETER Publish If this switch is set to $true the DSC Resorce Kit files will also be published using Publish-DscPullResources. .PARAMETER UseCache If this switch is set to $true then the DSC Resouce Kit File will not be redownloaded if one already exists in the temp folder. If one does not exist it will be downloaded and it will not be deleted after the cmdlet finishes. .PARAMETER PullServerResourcePath This is the destination path to which the zipped resources and checksum files will be written to. The user running this command must have write access to this folder. Note: If this is a SMB Pull Server then resources should be installed into the same folder as the configuration files. .EXAMPLE Install-DSCResourceKit -Publish .LINK http://pscx.codeplex.com/ #> function Install-DSCResourceKit { [CmdletBinding()] param ( [ValidateNotNullOrEmpty()] [System.String] $ResourceKitURL = $Script:DSCTools_ResourceKitURL, [ValidateNotNullOrEmpty()] [System.String] $ModulePath = "$($ENV:PROGRAMFILES)\windowspowershell\modules", [Switch] $Publish = $false, [Switch] $UseCache = $false, [ValidateNotNullOrEmpty()] [System.String] $PullServerResourcePath = $Script:DSCTools_DefaultPullServerResourcePath ) # Param InitZip if ($Publish) { # Check the Pull Server Resource Path exists. if ((Test-Path -Path $PullServerResourcePath -PathType Container) -eq $false) { throw "$PullServerResourcePath could not be found." } } # Attempt to download the Resource kit file to the temp folder. $TempPath = "$Env:TEMP\DSCResourceKit.zip" if ((Test-Path -Path $TempPath) -and ($UseCache)) { Write-Verbose -Message "Install-DSCResourceKit: Using Cached Resource Kit File $TempPath" } else { Write-Verbose -Message "Install-DSCResourceKit: Downloading $ResourceKitURL to $TempPath" try { Invoke-WebRequest $ResourceKitURL -OutFile $TempPath } catch { throw } } # Unzip the Resouce Kit File Write-Verbose -Message "Install-DSCResourceKit: Extracting $TempPath to $ModulePath" try { UnzipFile -ZipFileName $TempPath -DestinationPath $ModulePath } catch { throw } # try if ($Publish) { # Publish the Resources from the Resource Kit Write-Verbose -Message "Install-DSCResourceKit: Publishing Resources from $ModulePath to $PullServerResourcePath" Publish-DscPullResources -ModulePath (Join-Path -Path $ModulePath -ChildPath "All Resources") -PullServerResourcePath $PullServerResourcePath } # If if ($UseCache -eq $false) { Write-Verbose -Message "Install-DSCResourceKit: Deleting Resource Kit File $TempPath" Remove-Item -Path $TempPath } # If } # function Install-DSCResourceKit <# .SYNOPSIS Installs and configures one or more servers as a DSC Pull Servers. .DESCRIPTION This function will create a MOF file for configuring a Windows Server computer to be a DSC Pull Server and then force DSC to apply the MOF to the server. The name of as least one computer to install as a Pull Server is mandatory. Multiple computers can be specified to install more than one Pull Server. Important Note: The server that will be installed onto must contain the DSC module xPSDesiredStateConfiguration installed into the PowerShell Module path. This module is part of the DSC Resource kit found here: https://gallery.technet.microsoft.com/scriptcenter/DSC-Resource-Kit-All-c449312d The function will: 1. Create the node DSC Pull Server configuration MOF file for the server. 2. Execute the node DSC Pull Server configuration MOF on the server. If the Pull Server Protocol is set to SMB then the Ports, Endpoint, .PARAMETER Nodes Must contain an array of hash tables. Each hash table will represent a node that should be configured as a DSC Pull Server. The hash table must contain the following entries: Name = Name of the computer to install as a DSC Pull Server. Each hash entry can also contain the following optional items. If each item is not specified it will default. PullServerProtocol = The protocol the Pull Server will use. Defaults to $Script:DSCTools_DefaultPullServerProtocol. PullServerPort = The port the Pull Server will run on. Defaults to $Script:DSCTools_DefaultPullServerPort. ComplianceServerPort = The port the Complaince Server will run on. Defaults to $Script:DSCTools_DefaultComplianceServerPort. CertificateThumbprint = The certificate thumbprint to use if HTTPS should be used. Defaults to using HTTP. PullServerEndpointName = The endpoint name to use when creating the Pull Server web site. Defaults to $Script:DSCTools_DefaultPullServerEndpointName. PullServerResourcePath = The path the DSC Pull Server will look for resource files in. Defaults to $Script:DSCTools_DefaultPullServerResourcePath. PullServerConfigurationPath = The path the DSC Pull Server will use look for configuration (MOF) files in. Defaults to $Script:DSCTools_DefaultPullServerConfigurationPath. PullServerPhysicalPath = The local path to where the DSC Pull Server web site will be created. Defaults to $Script:DSCTools_DefaultPullServerPhysicalPath. ComplianceServerEndpointName = The endpoint name to use when creating the Compliance Server web site. Defaults to $Script:DSCTools_DefaultComplianceServerEndpointName. ComplianceServerPhysicalPath = The local path to where the DSC Compliance Server web site will be created. Defaults to $Script:DSCTools_DefaultComplianceServerPhysicalPath. Credential = Credentials to use to configure the DSC Pull Server using. Defaults to none. For example: @(@{Name='DSCPULLSRV01';},@{Name='DSCPULLSRV01';}) .PARAMETER ComputerName Name of the computer to install as a DSC Pull Server. .PARAMETER PullServerProtocol The protocol the Pull Server will use. Defaults to $Script:DSCTools_DefaultPullServerProtocol. .PARAMETER PullServerPort The port the Pull Server will run on. Defaults to $Script:DSCTools_DefaultPullServerPort. .PARAMETER ComplianceServerPort The port the Complaince Server will run on. Defaults to $Script:DSCTools_DefaultComplianceServerPort. .PARAMETER CertificateThumbprint The certificate thumbprint to use if HTTPS should be used. Defaults to using HTTP. .PARAMETER PullServerEndpointName The endpoint name to use when creating the Pull Server web site. Defaults to $Script:DSCTools_DefaultPullServerEndpointName. .PARAMETER PullServerResourcePath The path the DSC Pull Server will look for resource files in. Defaults to $Script:DSCTools_DefaultPullServerResourcePath. .PARAMETER PullServerConfigurationPath The path the DSC Pull Server will use look for configuration (MOF) files in. Defaults to $Script:DSCTools_DefaultPullServerConfigurationPath. .PARAMETER PullServerPhysicalPath The local path to where the DSC Pull Server web site will be created. Defaults to $Script:DSCTools_DefaultPullServerPhysicalPath. .PARAMETER ComplianceServerEndpointName The endpoint name to use when creating the Compliance Server web site. Defaults to $Script:DSCTools_DefaultComplianceServerEndpointName. .PARAMETER ComplianceServerPhysicalPath The local path to where the DSC Compliance Server web site will be created. Defaults to $Script:DSCTools_DefaultComplianceServerPhysicalPath. .PARAMETER Credential Credentials to use to configure the DSC Pull Server using. Defaults to none. .PARAMETER SkipConnectionCheck Some machines will falsely return that they are not contactable when they are actually able to be contacted. This swtich causes the cmdlet to skip the connection test to each node and will always allow the set up to be performed. .EXAMPLE Enable-DSCPullServer -Nodes @(@{Name='DSCPULLSRV01';},@{Name='DSCPULLSRV01';}) This command will install and configure a DSC Pull Server onto machines DSCPULLSRV01 and DSCPULLSRV02. .EXAMPLE Enable-DSCPullServer -ComputerName DSCPULLSRV01 This command will install and configure a DSC Pull Server onto machine DSCPULLSRV01 #> function Enable-DSCPullServer { [CmdletBinding(DefaultParameterSetName = 'ComputerName')] param ( [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $ComputerName = 'localhost', [Parameter(ParameterSetName = 'ComputerName')] [ValidateSet('HTTP', 'HTTPS', 'SMB')] [System.String] $PullServerProtocol, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.Uint32] $PullServerPort, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.Uint32] $ComplianceServerPort, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $CertificateThumbprint, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $PullServerEndpointName, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $PullServerResourcePath, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $PullServerConfigurationPath, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $PullServerPhysicalPath, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $ComplianceServerEndpointName, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $ComplianceServerPhysicalPath, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [PSCredential]$Credential, [Parameter(ParameterSetName = 'Nodes')] [Array] $Nodes, [Switch] $SkipConnectionCheck = $false ) # Set up a temporary path $TempPath = "$Env:TEMP\Enable-DSCPullServer" Write-Verbose -Message "Enable-DSCPullServer: Creating Temporary Folder $TempPath." $null = New-Item -Path $TempPath -ItemType 'Directory' -Force if (-not $Nodes) { $Nodes = @{ Name = $ComputerName; PullServerProtocol = $PullServerProtocol; PullServerPort = $PullServerPort; ComplianceServerPort = $ComplianceServerPort; CertificateThumbprint = $CertificateThumbprint; PullServerEndpointName = $PullServerEndpointName; PullServerResourcePath = $PullServerResourcePath; PullServerConfigurationPath = $PullServerConfigurationPath; PullServerPhysicalPath = $PullServerPhysicalPath; ComplianceServerEndpointName = $ComplianceServerEndpointName; ComplianceServerPhysicalPath = $ComplianceServerPhysicalPath; Credential = $Credential; } } # If foreach ($Node In $Nodes) { # Create the Pull Mode MOF that will configure the elements on this computer needed for Pull Mode [System.String] $NodeName = $Node.Name if (($NodeName -eq '') -or ($null -eq $NodeName)) { $NodeName = $ENV:COMPUTERNAME } # If # Get the Pull Server Protocol [System.String] $PullServerProtocol = $Node.PullServerProtocol if (($PullServerProtocol -eq '') -or ($null -eq $PullServerProtocol)) { $PullServerProtocol = $Script:DSCTools_DefaultPullServerProtocol } # if Write-Verbose -Message "Enable-DSCPullServer: Enabling $PullServerProtocol Pull Server $NodeName" # Get the credentials that need to be used to apply the DSC Config to the Pull Server [PSCredential]$Credential = $Node.Credential if ($PullServerProtocol -match 'http') { # An HTTP/HTTPS Pull Server is required [System.String] $CertificateThumbprint = $Node.CertificateThumbprint # Get the certificate thumbprint if (($CertificateThumbprint -eq '') -or ($null -eq $CertificateThumbprint)) { # If the pull server is HTTPS and no certificate thumbprint was provided then throw an error. if ($PullServerProtocol -match 'https') { throw "A certificate thumbprint must be provided if the Pull Server protocol is set to HTTPS" } $CertificateThumbprint = 'AllowUnencryptedTraffic' } # if # Get all the Pull Server properties from the node or use defaults. [System.Uint32] $PullServerPort = $Node.PullServerPort if (($PullServerPort -eq 0) -or ($null -eq $PullServerPort)) { $PullServerPort = $Script:DSCTools_DefaultPullServerPort } # if [System.Uint32] $ComplianceServerPort = $Node.ComplianceServerPort if (($ComplianceServerPort -eq 0) -or ($null -eq $ComplianceServerPort)) { $ComplianceServerPort = $Script:DSCTools_DefaultComplianceServerPort } # if [System.String] $PullServerEndpointName = $Node.PullServerEndpointName if (($PullServerEndpointName -eq '') -or ($null -eq $PullServerEndpointName)) { $PullServerEndpointName = $Script:DSCTools_DefaultPullServerEndpointName } # if [System.String] $PullServerResourcePath = $Node.PullServerResourcePath if (($PullServerResourcePath -eq '') -or ($null -eq $PullServerResourcePath)) { $PullServerResourcePath = $Script:DSCTools_DefaultPullServerResourcePath } # if [System.String] $PullServerConfigurationPath = $Node.PullServerConfigurationPath if (($PullServerConfigurationPath -eq '') -or ($null -eq $PullServerConfigurationPath)) { $PullServerConfigurationPath = $Script:DSCTools_DefaultPullServerConfigurationPath } # if [System.String] $PullServerPhysicalPath = $Node.PullServerPhysicalPath if (($PullServerPhysicalPath -eq '') -or ($null -eq $PullServerPhysicalPath)) { $PullServerPhysicalPath = $Script:DSCTools_DefaultPullServerPhysicalPath } # if [System.String] $ComplianceServerEndpointName = $Node.ComplianceServerEndpointName if (($ComplianceServerEndpointName -eq '') -or ($null -eq $ComplianceServerEndpointName)) { $ComplianceServerEndpointName = $Script:DSCTools_DefaultComplianceServerEndpointName } # if [System.String] $ComplianceServerPhysicalPath = $Node.ComplianceServerPhysicalPath if (($ComplianceServerPhysicalPath -eq '') -or ($null -eq $ComplianceServerPhysicalPath)) { $ComplianceServerPhysicalPath = $Script:DSCTools_DefaultComplianceServerPhysicalPath } # if try { Write-Verbose -Message "Enable-DSCPullServer: HTTP Pull Server MOF $TempPath\$NodeName.MOF for $NodeName Begin Creation" # Load the CreatePullServer Configuration into memory (dot source it) # The file should be in Configuration folder beneath the folder the module is in. . "$(Join-Path -Path $PSScriptRoot -ChildPath 'Configuration\Config_EnablePullServerHTTP.ps1')" $null = Config_EnablePullServerHTTP ` -NodeName $NodeName ` -Output $TempPath ` -PullServerPort $PullServerPort ` -ComplianceServerPort $ComplianceServerPort ` -CertificateThumbprint $CertificateThumbprint ` -PullServerEndpointName $PullServerEndpointName ` -PullServerResourcePath $PullServerResourcePath ` -PullServerConfigurationPath $PullServerConfigurationPath ` -PullServerPhysicalPath $PullServerPhysicalPath ` -ComplianceServerEndpointName $ComplianceServerEndpointName ` -ComplianceServerPhysicalPath $ComplianceServerPhysicalPath } catch { throw } # try Write-Verbose -Message "Enable-DSCPullServer: HTTP Pull Server MOF $TempPath\$NodeName.MOF for $NodeName Created Successfully" } else { [System.String] $PullServerConfigurationPath = $Node.PullServerConfigurationPath if (($PullServerConfigurationPath -eq '') -or ($null -eq $PullServerConfigurationPath)) { $PullServerConfigurationPath = $Script:DSCTools_DefaultPullServerConfigurationPath } [System.String] $PullServerEndpointName = $Node.PullServerEndpointName if (($PullServerEndpointName -eq '') -or ($null -eq $PullServerEndpointName)) { $PullServerEndpointName = $Script:DSCTools_DefaultPullServerEndpointName } try { Write-Verbose -Message "Enable-DSCPullServer: SMB Pull Server MOF $TempPath\$NodeName.MOF for $NodeName Begin Creation" # Load the CreatePullServer Configuration into memory (dot source it) # The file should be in Configuration folder beneath the folder the module is in. . "$(Join-Path -Path $PSScriptRoot -ChildPath 'Configuration\Config_EnablePullServerSMB.ps1')" $null = Config_EnablePullServerSMB ` -NodeName $NodeName ` -Output $TempPath ` -PullServerEndpointName $PullServerEndpointName ` -PullServerConfigurationPath $PullServerConfigurationPath } catch { throw } Write-Verbose -Message "Enable-DSCPullServer: SMB Pull Server MOF $TempPath\$NodeName.MOF for $NodeName Created Successfully" } # Apply the Pull Server MOF File to the Server if (IsLocalHost($NodeName)) { # Apply the Pull Server MOF File to the localhost if ($NodeName -match '\.') { Write-Warning "Enable-DSCPullServer: Warning Applying MOF $TempPath\$NodeName.MOF may fail because an FQDN name was used for Pull Server." } try { Write-Verbose -Message "Enable-DSCPullServer: Applying Pull Server MOF $TempPath\$NodeName.MOF to Localhost" Start-DSCConfiguration -Path $TempPath -Wait -Force Write-Verbose -Message "Enable-DSCPullServer: Pull Server MOF $TempPath\$NodeName.MOF Applied to Localhost Successfully" } catch { Write-Warning "Enable-DSCPullServer: Error Applying Pull Server MOF $TempPath\$NodeName.MOF to Localhost" throw } # try } else { # Apply the LCM MOF File to a remote node if (($SkipConnectionCheck) -or (Test-Connection -ComputerName $NodeName -Count 1 -Quiet)) { try { Write-Verbose -Message "Enable-DSCPullServer: Applying Pull Server MOF $TempPath\$NodeName.MOF to $NodeName" if ($Credential) { Start-DSCConfiguration -Path $TempPath -ComputerName $NodeName -Credential $Credential -Wait -Force } else { Start-DSCConfiguration -Path $TempPath -ComputerName $NodeName -Wait -Force } # If Write-Verbose -Message "Enable-DSCPullServer: Pull Server MOF $TempPath\$NodeName.MOF Applied to $NodeName Successfully" } catch { Write-Warning "Enable-DSCPullServer: Error Applying Pull Server MOF $TempPath\$NodeName.MOF to $NodeName" throw } # try } else { Write-Error -Message "Enable-DSCPullServer: Error contacting $NodeName. Push Mode Configuration was not applied." } # If } # If # Reove the LCM MOF File Remove-Item -Path "$TempPath\$NodeName.MOF" -Force Write-Verbose -Message "Enable-DSCPullServer: MOF $TempPath\$NodeName.MOF for $NodeName Deleted" } # foreach Remove-Item -Path $TempPath -Recurse -Force Write-Verbose -Message "Enable-DSCPullServer: Temporary Folder $TempPath Deleted" } # Enable-DSCPullServer <# .SYNOPSIS Enable/Disable DSC pull server logging on one or more DSC Pull Servers. .DESCRIPTION .PARAMETER Nodes Must contain an array of hash tables. Each hash table will represent a pull server node that should be configured with logging. The hash table must contain the following entries: Name = Name of the DSC Pull Server Each hash entry can also contain the following optional items. If each item is not specified it will default. AnalyticLog = a boolean value used to enable/disable Analytic logging. DebugLog = a boolean value used to enable/disable Debug logging. OperationalLog = a boolean value used to enable/disable Operational logging. For example: @(@{Name='DSCPULLSRV01';Analytic=$True;Debug=$False;Operational=$True;},@{Name='DSCPULLSRV01';Analytic=$True;Debug=$False;Operational=$True;}) .PARAMETER ComputerName Name of the computer to configure the DSC Pull Server logging on. .PARAMETER AnalyticLog A boolean value used to enable/disable Analytic logging. .PARAMETER DebugLog A boolean value used to enable/disable Debug logging. .PARAMETER OperationaLog A boolean value used to enable/disable Operational logging. .PARAMETER Credential Credentials to use to configure the DSC Pull Server using. Defaults to none. .EXAMPLE Set-DSCPullServerLogging -Nodes @(@{Name='DSCPULLSRV01';Analytic=$True;Debug=$False;Operational=$True;},@{Name='DSCPULLSRV01';Analytic=$True;Debug=$False;Operational=$True;}) This command will enable Analytic and Operational logging for DSC Pull Servers DSCPULLSRV01 and DSCPULLSRV02. .EXAMPLE Set-DSCPullServerLogging -ComputerName DSCPULLSRV01 -Analytic $True -Debug $False -Operational $True This command will enable Analytic and Operational logging for DSC Pull Server DSCPULLSRV01. #> function Set-DSCPullServerLogging { [CmdletBinding(DefaultParameterSetName = 'ComputerName')] param ( [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $ComputerName, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [PSCredential] $Credential, [System.Boolean] $AnalyticLog = $false, [System.Boolean] $DebugLog = $false, [System.Boolean] $OperationalLog = $false, [Parameter(ParameterSetName = 'Nodes')] [Array] $Nodes ) if ($ComputerName) { $Nodes = @{ Name = $ComputerName; Credential = $Credential; } } # If foreach ($Node In $Nodes) { # Create an array of additional parameters that will be added to the end of the command to set the log $Parameters = @{} # Was a computer name provided? [System.String] $NodeName = $Node.Name if (($NodeName -eq '') -or ($null -eq $NodeName) -or (IsLocalHost($NodeName))) { # None was provided or localhost was used. } else { $Parameters += @{ComputerName = $NodeName; } # Were credentials provided? if ($Node.Credential) { $Parameters += @{Credential = $Node.Credential; } } elseif ($Credential) { $Parameters += @{Credential = $Credential; } } } # If # Enable/Disable the Analytic Log if (($Node.AnalyticLog) -or ($AnalyticLog)) { try { Update-xDscEventLogStatus -Channel Analytic -Status Enabled @Parameters Write-Verbose -Message "Set-DSCPullServerLogging: Pull Server $NodeName Analytic Logging Enabled" } catch { Write-Error -Message "Set-DSCPullServerLogging: Error Enabling Analytic Logging on $NodeName" } } else { try { Write-Verbose -Message "Set-DSCPullServerLogging: Pull Server $NodeName Analytic Logging Disabled" Update-xDscEventLogStatus -Channel Analytic -Status Disabled @Parameters } catch { Write-Error -Message "Set-DSCPullServerLogging: Error Disabling Analytic Logging on $NodeName" } } # If # Enable/Disable the Debug Log if (($Node.DebugLog) -or ($DebugLog)) { try { Write-Verbose -Message "Set-DSCPullServerLogging: Pull Server $NodeName Debug Logging Enabled" Update-xDscEventLogStatus -Channel Debug -Status Enabled @Parameters } catch { Write-Error -Message "Set-DSCPullServerLogging: Error Enabling Debug Logging on $NodeName" } } else { try { Write-Verbose -Message "Set-DSCPullServerLogging: Pull Server $NodeName Debug Logging Disabled" Update-xDscEventLogStatus -Channel Debug -Status Disabled @Parameters } catch { Write-Error -Message "Set-DSCPullServerLogging: Error Disabling Debug Logging on $NodeName" } } # If # Enable/Disable the Operational Log if (($Node.OperationalLog) -or ($OperationalLog)) { try { Write-Verbose -Message "Set-DSCPullServerLogging: Pull Server $NodeName Operational Logging Enabled" Update-xDscEventLogStatus -Channel Operational -Status Enabled @Parameters } catch { Write-Error -Message "Set-DSCPullServerLogging: Error Enabling Operational Logging on $NodeName" } } else { try { Write-Verbose -Message "Set-DSCPullServerLogging: Pull Server $NodeName Operational Logging Disabled" Update-xDscEventLogStatus -Channel Operational -Status Disabled @Parameters } catch { Write-Error -Message "Set-DSCPullServerLogging: Error Disabling Operational Logging on $NodeName" } } # If } # foreach } # Set-DSCPullServerLogging <# .SYNOPSIS Updates the configuration for one or more nodes in a Pull Server. .DESCRIPTION This function will copy the node configuration MOF files to the pull server for the specified nodes. Note: The nodes should have already been successfully put into Pull Mode against the pull server using Start-DSCPullMode function. If any of these nodes are in push mode then the updated configuration will not be applied untill the node is switched into pull mode using the Start-DSCPullMode function. It will take an array of nodes in the nodes parameter which will list all nodes that should recieve updated MOF files. The function will: 1. Create the node DSC configuration MOF file if it is missing (and the configration .ps1 file is specified). 2. Copy the node DSC configuration MOF file and rename with GUID provided in the nodes array. 3. Create a node DSC configuration MOF checksum file. 4. Move the node DSC configration MOF and checksum file to the Pull server. .PARAMETER ComputerName This is the name of the computer that should be switched into Pull Mode. This parameter should not be set if Nodes are provided. .PARAMETER Guid This is the GUID that will be used to identify this computers configuration on the DSC Pull sever. This parameter should not be set if Nodes are provided. .PARAMETER MOFFile This is MOF file that contains the DSC Configuration for this computer. This parameter should not be set if Nodes are provided. .PARAMETER PullServerConfigurationPath This optional parameter contains the full path to where the Pull Server DSC Node configuration files should be written to. If this parameter is not passed it will be set to $Script:DSCTools_DefaultPullServerConfigurationPath For example: c:\program files\windowspowershell\DscService\configuration .PARAMETER NodeConfigSourceFolder This parameter is used to specify the folder where the node configration files can be found. If it is not passed it will default to the module variable $Script:DSCTools_DefaultNodeConfigSourceFolder. This value will be ignored for any node that has a MOFFile key value set. .PARAMETER Nodes Must contain an array of hash tables. Each hash table will represent a node that should be configured full DSC pull mode. The hash table must contain the following entries: Name = Each hash entry can also contain the following optional items. If each item is not specified it will default. Guid = If no guid is passed for this node a new one will be created MofFile = This is the path and filename of the MOF file to use for this node. If not provided the MOF file will default to the NodeConfigSourceFolder parameter plus NodeName CertificateThumbprint = This is the certificate thumbprint of the certificate that will be used to encrypt credentials passed to this node. If none are supplied then the certificate thuumbpring parameter is used unless it it not passed. For example: @(@{Name='SERVER01';Guid='115929a0-61e2-41fb-a9ad-0cdcd66fc2e7'}) .PARAMETER CertificateThumbprint This is the certificate thumbprint of the certificate that will be used to encrypt credentials contained in these configuration files. This is for future use and is not currently supported. .PARAMETER InvokeCheck If this switch is set it will cause Invoke-DSCCheck to be called after the node configuration is updated. This will cause the configuration change to be immediately applied. .EXAMPLE Update-DSCNodeConfiguration ` -Nodes @(@{Name='SERVER01';Guid='115929a0-61e2-41fb-a9ad-0cdcd66fc2e7'}) This command will upload a new confguration file for node SERVER01 to the Pull Server configuration folder specified in $Script:DSCTools_DefaultPullServerConfigurationPath. .EXAMPLE Update-DSCNodeConfiguration ` -Nodes @(@{Name='SERVER01';Guid='115929a0-61e2-41fb-a9ad-0cdcd66fc2e7'}) ` -PullServerConfigurationPath '\\MyPullServer\DSCConfiguration' This command will upload a new configuraton file for node SERVER01 to the Pull Server configuration folder '\\MyPullServer\DSCConfiguration' #> function Update-DSCNodeConfiguration { [CmdletBinding()] param ( [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $ComputerName, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.Guid] $Guid, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $MOFFile, [Parameter(ParameterSetName = 'Nodes')] [Array] $Nodes, [ValidateNotNullOrEmpty()] [System.String] $PullServerConfigurationPath = $Script:DSCTools_DefaultPullServerConfigurationPath, [ValidateNotNullOrEmpty()] [System.String] $NodeConfigSourceFolder = $Script:DSCTools_DefaultNodeConfigSourceFolder, [ValidateNotNullOrEmpty()] [System.String] $CertificateThumbprint, [Switch] $InvokeCheck ) if ($ComputerName) { $Nodes = @{ Name = $ComputerName; Guid = $Guid; MofFile = $MOFFile; } # $Nodes } # If foreach ($Node In $Nodes) { # Clear the node error flag [System.Boolean] $NodeError = $false # Get the Node parameters into variables and check them [System.String] $NodeName = $Node.Name if ($NodeName -eq '') { throw 'Node name is empty.' } # If [System.String] $NodeGuid = $Node.Guid if ($NodeGuid -eq '') { throw "Guid for node $NodeName is empty." } # If Write-Verbose -Message "Update-DSCNodeConfiguration: Updating $NodeName Guid $NodeGuid with Pull Mode configuration" # This is the certificate thumbrint that will be used to encrypt any credentials in this configuration. [System.String] $Cert = $Node.CertificateThumbprint if (($null -eq $Cert) -or ($Cert -eq '')) { $Cert = $CertificateThumbprint } # If # If the node doesn't have a specific MOF path specified then see if we can figure it out # Based on other parameters specified - or even create it. [System.String] $MofFile = $Node.MofFile if ($null -eq $MofFile) { $SourceMof = "$NodeConfigSourceFolder\$NodeName.mof" } else { $SourceMof = $MofFile } # If Write-Verbose -Message "Update-DSCNodeConfiguration: $NodeName Will Use Configuration MOF $SourceMof" # If the MOF doesn't throw an error? if (-not (Test-Path -PathType Leaf -Path $SourceMof)) { #TODO: Can we try to create the MOF file from the configuration? Write-Error -Message "Update-DSCNodeConfiguration: Node $NodeName Configuration MOF $SourceMof Could Not Be Found" $NodeError = $true } # If if (-not $NodeError) { # Create and/or Move the Node Configuration file to the Pull server $DestMof = Join-Path -Path $PullServerConfigurationPath -ChildPath "$NodeGuid.mof" Copy-Item -Path $SourceMof -Destination $DestMof -Force Write-Verbose -Message "Update-DSCNodeConfiguration: Node $NodeName Configuration MOF $SourceMof Copied to $DestMof" New-DSCChecksum -ConfigurationPath $DestMof -Force Write-Verbose -Message "Update-DSCNodeConfiguration: Node $NodeName Configuration MOF Checksum Created for $DestMof" if ($InvokeCheck) { Invoke-DSCCheck -ComputerName $NodeName } # If } # If Write-Verbose -Message "Update-DSCNodeConfiguration: Node $NodeName Pull Mode configuration update complete" } # foreach } # Update-DSCNodeConfiguration <# .SYNOPSIS Configures one or mode nodes for Pull Mode. .DESCRIPTION This function will create all configuration files required for a set of nodes to be placed into DSC Pull mode. It will take an array of nodes in the nodes parameter which will list all nodes that should be configured for pull mode. The function will: 1. Create the node DSC configuration MOF file if it is missing (and the configration file is noted in the Nodes array). 2. Copy the node DSC configuration MOF file and rename with GUID provided in the nodes array or to a new GUID if one is not provided in the nodes array. 3. Create a node DSC configuration MOF checksum file. 4. Move the node DSC configration MOF and checksum file to the Pull server. 5. Create the node LCM configuration MOF file to configure the LCM for pull mode. 6. Execute the node LCM configuration MOF on the node. .PARAMETER ComputerName This is the name of the computer that should be switched into Pull Mode. This parameter should not be set if Nodes are provided. .PARAMETER Guid This is the GUID that will be used to identify this computers configuration on the DSC Pull sever. This parameter should not be set if Nodes are provided. .PARAMETER MOFFile This is MOF file that contains the DSC Configuration for this computer. This parameter should not be set if Nodes are provided. .PARAMETER RebootIfNeeded This parameter controls whether the LCM is allowed to reboot the computer when applying configuration. If this value is also provided in any Nodes then the node value will be used instead. .PARAMETER ConfigurationMode This parameter specifies the configuration mode for the LCM. If this value is also provided in any Nodes then the node value will be used instead. .PARAMETER PullServerURL This is the URL that will be used by the Local Configuration Manager of the Node to pull the configuration files. If this parameter is not passed it is generated from the Module Variables: $($Script:DSCTools_DefaultPullServerProtocol)://$($Script:DSCTools_DefaultPullServerName):$($Script:DSCTools_DefaultPullServerPort)/$($Script:DSCTools_DefaultPullServerPath) For example: http://MyPullServer:8080/PSDSCPullServer.svc .PARAMETER PullServerConfigurationPath This optional parameter contains the full path to where the Pull Server DSC Node configuration files should be written to. If this parameter is not passed it will be set to $Script:DSCTools_DefaultPullServerConfigurationPath For example: c:\program files\windowspowershell\DscService\configuration .PARAMETER NodeConfigSourceFolder This parameter is used to specify the folder where the node configration files can be found. If it is not passed it will default to the module variable $Script:DSCTools_DefaultNodeConfigSourceFolder. This value will be ignored for any node that has a MOFFile key value set. .PARAMETER Nodes Must contain an array of hash tables. Each hash table will represent a node that should be configured full DSC pull mode. The hash table must contain the following entries: Name = Each hash entry can also contain the following optional items. If each item is not specified it will default. Guid = If no guid is passed for this node a new one will be created RebootIfNeeded = $false ConfigurationMode = 'ApplyAndAutoCorrect' MofFile = This is the path and filename of the MOF file to use for this node. If not provided the MOF file will default to the NodeConfigSourceFolder parameter plus NodeName Credential = These are node specific credentials that will be used to apply the LCM configuration. If none are supplied then the Credential parameter is used unless it it not passed. CertificateThumbprint = This is the certificate thumbprint of the certificate that will be used to encrypt credentials passed to this node. If none are supplied then the certificate thuumbpring parameter is used unless it it not passed. For example: @(@{Name='SERVER01';Guid='115929a0-61e2-41fb-a9ad-0cdcd66fc2e7'},@{Name='SERVER02';Guid='';RebootIfNeeded=$true;MofFile='c:\users\Administrtor\Documents\WindowsPowerShell\DSCConfig\SERVER02.MOF'}) .PARAMETER Credential These are the credentials (if required) that will be used to apply the LCM configuration to all nodes where a node specific credentials weren't supplied. .PARAMETER CertificateThumbprint This is the certificate thumbprint of the certificate that will be used to encrypt credentials passed to any of these nodes. .PARAMETER PullServerCredential These are the credentials (if required) that all nodes will need to use to pull the configuration from the Pull Server. .PARAMETER SkipConnectionCheck Some machines will falsely return that they are not contactable when they are actually able to be contacted. This swtich causes the cmdlet to skip the connection test to each node and will always allow the set up to be attempted. .EXAMPLE Start-DSCPullMode ` -Nodes @(@{Name='SERVER01';Guid='115929a0-61e2-41fb-a9ad-0cdcd66fc2e7'},@{Name='SERVER02';RebootIfNeeded=$true;MofFile='c:\users\Administrtor\Documents\WindowsPowerShell\DSCConfig\SERVER02.MOF'}) This command will cause the nodes SERVER01 and SERVER02 to be switched into Pull mode and the appropriate configration files uploaded to the Pull server specified in $Script:DSCTools_DefaultPullServerConfigurationPath. .EXAMPLE Start-DSCPullMode ` -Nodes @(@{Name='SERVER01';Guid='115929a0-61e2-41fb-a9ad-0cdcd66fc2e7'},@{Name='SERVER02';RebootIfNeeded=$true;MofFile='c:\users\Administrtor\Documents\WindowsPowerShell\DSCConfig\SERVER02.MOF'}) ` -PullServerConfigurationPath '\\MyPullServer\DSCConfiguration' This command will cause the nodes SERVER01 and SERVER02 to be switched into Pull mode and the appropriate configration files uploaded to the Pull server configration folder '\\MyPullServer\DSCConfiguration' #> function Start-DSCPullMode { [CmdletBinding()] param ( [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $ComputerName, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.Guid] $Guid, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $MOFFile, [Parameter(ParameterSetName = 'Nodes')] [Array] $Nodes, [Switch] $RebootIfNeeded = $false, [ValidateSet('ApplyAndAutoCorrect', 'ApplyAndMonitor', 'ApplyOnly')] [System.String] $ConfigurationMode = 'ApplyAndAutoCorrect', [ValidateNotNullOrEmpty()] [System.String] $PullServerURL = "", [ValidateNotNullOrEmpty()] [System.String] $PullServerConfigurationPath = $Script:DSCTools_DefaultPullServerConfigurationPath, [ValidateNotNullOrEmpty()] [System.String] $NodeConfigSourceFolder = $Script:DSCTools_DefaultNodeConfigSourceFolder, [ValidateNotNullOrEmpty()] [PSCredential]$Credential, [ValidateNotNullOrEmpty()] [System.String] $CertificateThumbprint, [ValidateNotNullOrEmpty()] [PSCredential]$PullServerCredential, [Switch] $SkipConnectionCheck = $false ) # Set up a temporary path $TempPath = "$Env:TEMP\Start-DSCPullMode" Write-Verbose -Message "Start-DSCPullMode: Creating Temporary Folder $TempPath" $null = New-Item -Path $TempPath -ItemType 'Directory' -Force if ($ComputerName) { $Nodes = @{ Name = $ComputerName; Guid = $Guid; MofFile = $MOFFile; } # $Nodes } # If # Figure out the Pull Server URL if it wasn't specified if (($PullServerURL -eq '') -or ($PullServerURL -eq $null)) { if ($Script:DSCTools_DefaultPullServerProtocol -match "SMB") { $PullServerURL = "\\$($Script:DSCTools_DefaultPullServerName)\$($Script:DSCTools_DefaultPullServerEndpointName)\" } else { $PullServerURL = "$($Script:DSCTools_DefaultPullServerProtocol)://$($Script:DSCTools_DefaultPullServerName):$($Script:DSCTools_DefaultPullServerPort)/$($Script:DSCTools_DefaultPullServerPath)" } } foreach ($Node In $Nodes) { # Clear the node error flag [System.Boolean] $NodeError = $false # Get the Node parameters into variables and check them [System.String] $NodeName = $Node.Name if ($NodeName -eq '') { throw 'Node name is empty.' } # If Write-Verbose -Message "Start-DSCPullMode: Configuring $NodeName for Pull Mode" [System.String] $NodeGuid = $Node.Guid if ($NodeGuid -eq '') { $NodeGuid = [System.Guid]::NewGuid() } # If [Switch] $Reboot = $Node.RebootIfNeeded if ($Reboot -eq $null) { $Reboot = $RebootIfNeeded } # If [System.String] $Mode = $Node.ConfigurationMode if (($Mode -eq $null) -or ($Mode -eq '')) { $Mode = $ConfigurationMode } # If Write-Verbose -Message "Start-DSCPullMode: $NodeName Will Use GUID $NodeGuid with Configuration Mode $Mode $(@{$true='and will Reboot If Needed';$false=''}[$RebootIfNeeded])" # Were credentials supplied to allow the LCM to be applied to the node? [PSCredential]$Cred = $Node.Credential if ($Cred -eq $null) { $Cred = $Credential } # If [System.String] $Cert = $Node.CertificateThumbprint if (($Cert -eq $null) -or ($Cert -eq '')) { $Cert = $CertificateThumbprint } # If # If the node doesn't have a specific MOF path specified then see if we can figure it out # Based on other parameters specified - or even create it. [System.String] $MofFile = $Node.MofFile if ($MofFile -eq $null) { $SourceMof = "$NodeConfigSourceFolder\$NodeName.mof" } else { $SourceMof = $MofFile } # If Write-Verbose -Message "Start-DSCPullMode: $NodeName Will Use Configuration MOF $SourceMof" # If the MOF doesn't throw an error? if (-not (Test-Path -PathType Leaf -Path $SourceMof)) { #TODO: Can we try to create the MOF file from the configuration? Write-Error -Message "Start-DSCPullMode: Node $NodeName Configuration MOF $SourceMof Could Not Be Found" $NodeError = $true } # If if (-not $NodeError) { # Create and/or Move the Node Configuration file to the Pull server $DestMof = Join-Path -Path $PullServerConfigurationPath -ChildPath "$NodeGuid.mof" Copy-Item -Path $SourceMof -Destination $DestMof -Force Write-Verbose -Message "Start-DSCPullMode: Node $NodeName Configuration MOF $SourceMof Copied to $DestMof" New-DSCChecksum -ConfigurationPath $DestMof -Force Write-Verbose -Message "Start-DSCPullMode: Node $NodeName Configuration MOF Checksum Created for $DestMof" # Create the LCM MOF File to set the nodes LCM to pull mode Write-Verbose -Message "Start-DSCPullMode: Node $NodeName LCM MOF $TempPath\$NodeName.MOF Start Creation" . "$(Join-Path -Path $PSScriptRoot -ChildPath 'Configuration\Config_SetLCMPullMode.ps1')" if ($PullServerCredential -eq $null) { $null = Config_SetLCMPullMode ` -NodeName $NodeName ` -NodeGuid $NodeGuid ` -RebootNodeIfNeeded $Reboot ` -ConfigurationMode $Mode ` -PullServerURL $PullServerURL ` -Output $TempPath } else { if ($Cert -eq $null) { throw "A Certificate Thumbprint must be provided for the node if a Pull Server credential is passed" } # If $null = Config_SetLCMPullMode ` -NodeName $NodeName ` -NodeGuid $NodeGuid ` -RebootNodeIfNeeded $Reboot ` -ConfigurationMode $Mode ` -PullServerURL $PullServerURL ` -CertificateId $Cert ` -Credential $PullServerCredential ` -Output $TempPath } # If Write-Verbose -Message "Start-DSCPullMode: Node $NodeName LCM MOF $TempPath\$NodeName.MOF Created Successfully" if (IsLocalHost($NodeName)) { # Apply the LCM MOF File to the local node try { Write-Verbose -Message "Start-DSCPullMode: Setting Localhost to use LCM MOF $TempPath" Set-DSCLocalConfigurationManager -Path $TempPath Write-Verbose -Message "Start-DSCPullMode: Node Localhost set to use LCM MOF $TempPath" } catch { Write-Error -Message "Start-DSCPullMode: Error Setting Localhost to use LCM MOF $TempPath" } # try } else { # Apply the LCM MOF File to a remote node if (($SkipConnectionCheck) -or (Test-Connection -ComputerName $NodeName -Count 1 -Quiet)) { try { Write-Verbose -Message "Start-DSCPullMode: Setting $NodeName to use LCM MOF $TempPath" if ($Cred) { Set-DSCLocalConfigurationManager -Path $TempPath -ComputerName $NodeName -Credential $Cred } else { Set-DSCLocalConfigurationManager -Path $TempPath -ComputerName $NodeName } # If Write-Verbose -Message "Start-DSCPullMode: Node $NodeName set to use LCM MOF $TempPath" } catch { Write-Error -Message "Start-DSCPullMode: Error Setting $NodeName to use LCM MOF $TempPath" } # try } else { Write-Error -Message "Start-DSCPullMode: Error contacting $NodeName. Pull Mode Configuration was not applied." } # If } # If # Reove the LCM MOF File Remove-Item -Path "$TempPath\$NodeName.meta.MOF" Write-Verbose -Message "Start-DSCPullMode: Node $NodeName LCM MOF $TempPath\$NodeName.meta.MOF Removed" } # If Write-Verbose -Message "Start-DSCPullMode: Node $NodeName Processing Complete" } # foreach Remove-Item -Path $TempPath -Recurse -Force Write-Verbose -Message "Start-DSCPullMode: Temporary Folder $TempPath Deleted" } # Start-DSCPullMode <# .SYNOPSIS Configures one or mode nodes for Push Mode. .DESCRIPTION This function will create all configuration files required for a set of nodes to be placed into DSC Push mode. It will take an array of nodes in the nodes parameter which will list all nodes that should be configured for push mode. The function will: 1. Create the node DSC configuration MOF file if it is missing (and the configration file is noted in the Nodes array). 2. Create the node LCM configuration MOF file to configure the LCM for push mode. 3. Execute the node LCM configuration MOF on the node. .PARAMETER ComputerName This is the name of the computer that should be switched into Push Mode. This parameter should not be set if Nodes are provided. .PARAMETER MOFFile This is MOF file that contains the DSC Configuration for this computer. This parameter should not be set if Nodes are provided. .PARAMETER RebootIfNeeded This parameter controls whether the LCM is allowed to reboot the computer when applying configuration. If this value is also provided in any Nodes then the node value will be used instead. .PARAMETER ConfigurationMode This parameter specifies the configuration mode for the LCM. If this value is also provided in any Nodes then the node value will be used instead. .PARAMETER NodeConfigSourceFolder This parameter is used to specify the folder where the node configration files can be found. If it is not passed it will default to the module variable $Script:DSCTools_DefaultNodeConfigSourceFolder. This value will be ignored for any node that has a MOFFile key value set. .PARAMETER Nodes Must contain an array of hash tables. Each hash table will represent a node that should be configured full DSC push mode. The hash table must contain the following entries: Name = Each hash entry can also contain the following optional items. If each item is not specified it will default. RebootIfNeeded = $false ConfigurationMode = 'ApplyAndAutoCorrect' MofFile = This is the path and filename of the MOF file to use for this node. If not provided the MOF file will be used For example: @(@{Name='SERVER01';},@{Name='SERVER02';RebootIfNeeded=$true;MofFile='c:\users\Administrtor\Documents\WindowsPowerShell\DSCConfig\SERVER02.MOF'}) .PARAMETER SkipConnectionCheck Some machines will falsely return that they are not contactable when they are actually able to be contacted. This swtich causes the cmdlet to skip the connection test to each node and will always allow the set up to be performed. .EXAMPLE Start-DSCPushlMode ` -Nodes @(@{Name='SERVER01'},@{Name='SERVER02';RebootIfNeeded=$true;MofFile='c:\users\Administrtor\Documents\WindowsPowerShell\DSCConfig\SERVER02.MOF'}) This command will cause the nodes SERVER01 and SERVER02 to be switched into Push mode. #> function Start-DSCPushMode { [CmdletBinding()] param ( [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $ComputerName, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.Guid] $Guid, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] $MOFFile, [Parameter(ParameterSetName = 'Nodes')] [Array] $Nodes, [Switch] $RebootIfNeeded = $false, [ValidateSet('ApplyAndAutoCorrect', 'ApplyAndMonitor', 'ApplyOnly')] [System.String] $ConfigurationMode = 'ApplyAndAutoCorrect', [System.String] $NodeConfigSourceFolder = $Script:DSCTools_DefaultNodeConfigSourceFolder, [Switch] $SkipConnectionCheck = $false ) # Set up a temporary path $TempPath = "$Env:TEMP\Start-DSCPushMode" Write-Verbose -Message "Start-DSCPushMode: Creating Temporary Folder $TempPath" $null = New-Item -Path $TempPath -ItemType 'Directory' -Force if ($ComputerName) { $Nodes = @{ Name = $ComputerName; MofFile = $MOFFile; } # $Nodes } # If foreach ($Node In $Nodes) { # Clear the node error flag $NodeError = $false # Get the Node parameters into variables and check them $NodeName = $Node.Name if ($NodeName -eq '') { throw 'Node name is empty.' } Write-Verbose -Message "Start-DSCPushMode: Configuring $NodeName for Push Mode" [Switch] $Reboot = $Node.RebootIfNeeded if ($null -eq $Reboot) { $Reboot = $RebootIfNeeded } # If [System.String] $Mode = $Node.ConfigurationMode if (($null -eq $Mode) -or ($Mode -eq '')) { $Mode = $ConfigurationMode } # If Write-Verbose -Message "Start-DSCPushMode: $NodeName set to Configuration Mode $Mode $(@{$true='and will Reboot If Needed';$false=''}[$RebootIfNeeded])" # If the node doesn't have a specific MOF path specified then see if we can figure it out # Based on other parameters specified - or even create it. $MofFile = $Node.MofFile if ($MofFile -eq $null) { $SourceMof = "$NodeConfigSourceFolder\$NodeName.mof" } else { $SourceMof = $MofFile } Write-Verbose -Message "Start-DSCPushMode: Node $NodeName Will Use Configuration MOF $SourceMof" # If the MOF doesn't throw an error? if (-not (Test-Path -PathType Leaf -Path $SourceMof)) { #TODO: Can we try to create the MOF file from the configuration? Write-Error -Message "Start-DSCPushMode: Node $NodeName Configuration MOF $SourceMof Could Not Be Found" $NodeError = $true } try { Start-DscConfiguration -ComputerName $NodeName -Path (Split-Path -Path $SourceMof) } catch { Write-Error -Message "Start-DSCPushMode: Node $NodeName Configuration MOF $SourceMof Could Not Be Applied because an Error Occurred" $NodeError = $true } if (-not $NodeError) { # Create the LCM MOF File to set the nodes LCM to push mode Write-Verbose -Message "Start-DSCPushMode: Node $NodeName LCM MOF $TempPath\$NodeName.MOF Start Creation" . "$(Join-Path -Path $PSScriptRoot -ChildPath 'Configuration\Config_SetLCMPushMode.ps1')" $null = Config_SetLCMPushMode ` -NodeName $NodeName ` -RebootNodeIfNeeded $RebootIfNeeded ` -ConfigurationMode $Mode ` -Output $TempPath Write-Verbose -Message "Start-DSCPushMode: Node $NodeName LCM MOF $TempPath\$NodeName.MOF Created Successfully" # Apply the LCM MOF File to the node if (IsLocalHost($NodeName)) { # Apply the LCM MOF File to the local node try { Write-Verbose -Message "Start-DSCPushMode: Setting Localhost to use LCM MOF $TempPath" Set-DSCLocalConfigurationManager -Path $TempPath Write-Verbose -Message "Start-DSCPushMode: Localhost set to use LCM MOF $TempPath" } catch { Write-Error -Message "Start-DSCPushMode: Error Setting Localhost to use LCM MOF $TempPath" } # try } else { # Apply the LCM MOF File to a remote node if (($SkipConnectionCheck) -or (Test-Connection -ComputerName $NodeName -Count 1 -Quiet)) { try { Write-Verbose -Message "Start-DSCPushMode: Setting $NodeName to use LCM MOF $TempPath" if ($Cred) { Set-DSCLocalConfigurationManager -Path $TempPath -ComputerName $NodeName -Credential $Cred } else { Set-DSCLocalConfigurationManager -Path $TempPath -ComputerName $NodeName } # If Write-Verbose -Message "Start-DSCPushMode: Node $NodeName set to use LCM MOF $TempPath" } catch { Write-Error -Message "Start-DSCPushMode: Error Setting $NodeName to use LCM MOF $TempPath" } # try } else { Write-Error -Message "Start-DSCPushMode: Error contacting $NodeName. Push Mode Configuration was not applied." } # If } # If # Reove the LCM MOF File Remove-Item -Path "$TempPath\$NodeName.meta.MOF" Write-Verbose -Message "Start-DSCPushMode: Node $NodeName LCM MOF $TempPath\$NodeName.meta.MOF Removed" } # If Write-Verbose -Message "Start-DSCPushMode: Node $NodeName Processing Complete" } # foreach Remove-Item -Path $TempPath -Recurse -Force Write-Verbose -Message "Start-DSCPushMode: Temporary folder $TempPath deleted" } # Start-DSCPushMode <# .SYNOPSIS Returns the DSC configuration for this machine or for a remote node. .DESCRIPTION The Get-xDscConfiguration cmdlet gets the current configuration of the node, if configuration exists. Specify computers by using CIM sessions or the ComputerName parameter. If you do not specify a target computer, the cmdlet gets the configuration from the local computer. .PARAMETER AsJob Runs the cmdlet as a background job. Use this parameter to run commands that take a long time to complete. The cmdlet immediately returns an object that represents the job and then displays the command prompt. You can continue to work in the session while the job completes. To manage the job, use the *-Job cmdlets. To get the job results, use the Receive-Job cmdlet. For more information about Windows PowerShell® background jobs, see about_Jobs. .PARAMETER CimSession Runs the cmdlet in a remote session or on a remote computer. Enter a computer name or a session object, such as the output of a New-CimSession or Get-CimSession cmdlet. The default is the current session on the local computer. .PARAMETER ComputerName Runs the cmdlet on a remote computer, forming a CIM session connection and then closing it after getting the configuration. .PARAMETER UseSSL Runs the cmdlet on a remote computer connecting with SSL. .PARAMETER Credemtial Uses these credentials to connect to the remote computer. .PARAMETER ThrottleLimit Specifies the maximum number of concurrent operations that can be established to run the cmdlet. If this parameter is omitted or a value of 0 is entered, then Windows PowerShell® calculates an optimum throttle limit for the cmdlet based on the number of CIM cmdlets that are running on the computer. The throttle limit applies only to the current cmdlet, not to the session or to the computer. .EXAMPLE PS C:\> Get-xDscConfiguration This command gets the current configuration for the local computer. .EXAMPLE PS C:\> Get-xDscConfiguration -ComputerName DSCSVR01 -Credential (Get-Credential) -UseSSL This example gets the current configuration from computer DSCSVR01, connecting to it via SSL and the credentials supplied. .INPUTS .OUTPUTS .LINK http://go.microsoft.com/fwlink/?LinkID=288760 #> function Get-xDscConfiguration { [CmdletBinding(PositionalBinding = $false)] param( [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] ${CimSession}, [System.Uint32] ${ThrottleLimit}, [Switch] ${AsJob}, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] ${ComputerName}, [Parameter(ParameterSetName = 'ComputerName')] [PSCredential] ${Credential}, [Parameter(ParameterSetName = 'ComputerName')] [Switch] ${UseSSL} ) begin { try { $outBuffer = $null if ($PSBoundParameters.tryGetValue('OutBuffer', [ref]$outBuffer)) { $PSBoundParameters['OutBuffer'] = 1 } # if $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Get-DscConfiguration', [System.Management.Automation.CommandTypes]::Function) if ($ComputerName) { $cimSessionParameters = @{} [Void]$PSBoundParameters.Remove('ComputerName') if ($UseSSL) { [Void]$PSBoundParameters.Remove('UseSSL') $cimSessionOption = New-CimSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -UseSsl $cimSessionParameters += @{SessionOption = $cimSessionOption} } # if if ($Credential) { [Void]$PSBoundParameters.Remove('Credential') $cimSessionParameters += @{Credential = $Credential} } # if Write-Verbose -Message "Get-xDscConfiguration: Connecting to $ComputerName" $cimSession = New-CimSession -ComputerName $ComputerName @CimSessionParameters Write-Verbose -Message "Get-xDscConfiguration: Calling Get-DscConfiguration" $scriptCmd = {& $wrappedCmd @PSBoundParameters -CimSession $cimSession } } else { $scriptCmd = {& $wrappedCmd @PSBoundParameters } } # if $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin) $steppablePipeline.Begin($PSCmdlet) } catch { throw } # try } # begin process { try { $steppablePipeline.Process($_) } catch { throw } # try } # process end { try { $steppablePipeline.End() if ($ComputerName -and $cimSession) { Write-Verbose -Message "Get-xDscConfiguration: Disconnecting from $ComputerName" Remove-CimSession -CimSession $cimSession } # if } catch { throw } # try } # end } # function Get-xDscConfiguration <# .SYNOPSIS Returns the DSC Local Configuration Manager configuration for this machine or for a remote node. .DESCRIPTION The Get-xDscLocalConfigurationManager cmdlet gets the current LCM configuration of the node, if configuration exists. Specify computers by using CIM sessions or the ComputerName parameter. If you do not specify a target computer, the cmdlet gets the configuration from the local computer. .PARAMETER AsJob Runs the cmdlet as a background job. Use this parameter to run commands that take a long time to complete. The cmdlet immediately returns an object that represents the job and then displays the command prompt. You can continue to work in the session while the job completes. To manage the job, use the *-Job cmdlets. To get the job results, use the Receive-Job cmdlet. For more information about Windows PowerShell® background jobs, see about_Jobs. .PARAMETER CimSession Runs the cmdlet in a remote session or on a remote computer. Enter a computer name or a session object, such as the output of a New-CimSession or Get-CimSession cmdlet. The default is the current session on the local computer. .PARAMETER ComputerName Runs the cmdlet on a remote computer, forming a CIM session connection and then closing it after getting the configuration. .PARAMETER UseSSL Runs the cmdlet on a remote computer connecting with SSL. .PARAMETER Credemtial Uses these credentials to connect to the remote computer. .PARAMETER ThrottleLimit Specifies the maximum number of concurrent operations that can be established to run the cmdlet. If this parameter is omitted or a value of 0 is entered, then Windows PowerShell® calculates an optimum throttle limit for the cmdlet based on the number of CIM cmdlets that are running on the computer. The throttle limit applies only to the current cmdlet, not to the session or to the computer. .EXAMPLE PS C:\> Get-xDscLocalConfigurationManager This command gets the current configuration for the local computer. .EXAMPLE PS C:\> Get-xDscLocalConfigurationManager -ComputerName DSCSVR01 -Credential (Get-Credential) -UseSSL This example gets the current configuration from computer DSCSVR01, connecting to it via SSL and the credentials supplied. .INPUTS .OUTPUTS .LINK http://go.microsoft.com/fwlink/?LinkID=288760 #> function Get-xDscLocalConfigurationManager { [CmdletBinding(PositionalBinding = $false)] param( [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] ${CimSession}, [System.Uint32] ${ThrottleLimit}, [Switch] ${AsJob}, [Parameter(ParameterSetName = 'ComputerName')] [ValidateNotNullOrEmpty()] [System.String] ${ComputerName}, [Parameter(ParameterSetName = 'ComputerName')] [PSCredential] ${Credential}, [Parameter(ParameterSetName = 'ComputerName')] [Switch] ${UseSSL} ) begin { try { $outBuffer = $null if ($PSBoundParameters.tryGetValue('OutBuffer', [ref]$outBuffer)) { $PSBoundParameters['OutBuffer'] = 1 } # if $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Get-DscLocalConfigurationManager', [System.Management.Automation.CommandTypes]::Function) if ($ComputerName) { $cimSessionParameters = @{} [Void]$PSBoundParameters.Remove('ComputerName') if ($UseSSL) { [Void]$PSBoundParameters.Remove('UseSSL') $cimSessionOption = New-CimSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -UseSsl $cimSessionParameters += @{SessionOption = $cimSessionOption} } # if if ($Credential) { [Void]$PSBoundParameters.Remove('Credential') $cimSessionParameters += @{Credential = $Credential} } # if Write-Verbose -Message "Get-xDscLocalConfigurationManager: Connecting to $ComputerName" $cimSession = New-CimSession -ComputerName $ComputerName @CimSessionParameters Write-Verbose -Message "Get-xDscLocalConfigurationManager: Calling Get-DscLocalConfigurationManager" $scriptCmd = {& $wrappedCmd @PSBoundParameters -CimSession $cimSession } } else { $scriptCmd = {& $wrappedCmd @PSBoundParameters } } # if $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin) $steppablePipeline.Begin($PSCmdlet) } catch { throw } # try } # begin process { try { $steppablePipeline.Process($_) } catch { throw } # try } # process end { try { $steppablePipeline.End() if ($ComputerName -and $cimSession) { Write-Verbose -Message "Get-xDscLocalConfigurationManager: Disconnecting from $ComputerName" Remove-CimSession -CimSession $cimSession } # if } catch { throw } # try } # end } # function Get-xDscLocalConfigurationManager Export-ModuleMember -function ` Invoke-DSCCheck, ` Publish-DscPullResources, ` Install-DSCResourceKit, ` Start-DSCPullMode, ` Start-DSCPushMode, ` Enable-DSCPullServer, ` Set-DSCPullServerLogging, ` Get-xDSCConfiguration, ` Get-xDSCLocalConfigurationManager, ` Update-DSCNodeConfiguration, ` Update-DSCTools ` -Variable ` DSCTools_Default*, ` DSCTools_PSVersion ########################################################################################################################################## |