Public/Install-DSCPullServer.ps1

function Install-DSCPullServer {
    [CmdletBinding()]  
    param(
        [Parameter (Mandatory=$True)]
        [string]$VMName,

        [Parameter (Mandatory=$True)]
        [PSCredential]$Credential,

        [Parameter (Mandatory=$True)]
        [Version]$XPSDesiredStateConfigurationVersion,

        [int]$Attempts=1
    )
    try {
        $ErrorActionPreference = 'Stop'
        if (-not((Get-PackageProvider).name.contains('NuGet'))) {
            Install-PackageProvider -Name NuGet -Confirm:$false -Force | Out-Null
        }
        # save required DSC resources to host
        Save-Module 'xDHCPServer', 'xDNSServer', 'cDhcpServerDynamicUpdate' -Path "$env:temp\DSCPullServerLab" -Force
        Save-Module xPSDesiredStateConfiguration -RequiredVersion $XPSDesiredStateConfigurationVersion -Path "$env:TEMP\DSCPullServerLab" -Force

        # establish a remote session with DSCPullServer
        $Session = Wait-ForPSDirectSession -VMName $VMName -Credential $Credential -Attempts $Attempts

        # get temp and Program Files directory paths on DSCPullServer
        $VMDirs = Invoke-Command -Session $Session -ScriptBlock {$env:ProgramFiles,$env:TEMP}

        # copy DSC resources from host to DSCPullServer
        Get-ChildItem "$env:TEMP\DSCPullServerLab" | Copy-Item -ToSession $Session -Destination "$($VMDirs[0])\WindowsPowerShell\Modules" -Recurse -Force

        # get the DSCPullServer configuration and insert into a new ps1 file on host
        Get-DSCLabConfiguration | Set-Content "$env:TEMP\DSCPullServerLab\DSCLabConfiguration.ps1" -Force

        # copy ps1 configuration file to DSCPullServer
        Invoke-Command -Session $Session -ScriptBlock {New-Item -ItemType Directory -Path $env:temp\DSCPullServerLab -Force | Out-Null}
        Copy-Item "$env:TEMP\DSCPullServerLab\DSCLabConfiguration.ps1" -ToSession $Session -Destination "$($VMDirs[1])\DSCPullServerLab\DSCLabConfiguration.ps1" -Force

        # configure DSCPullServer
        Invoke-Command -Session $Session -ScriptBlock {
            . "$env:TEMP\DSCPullServerLab\DSCLabConfiguration.ps1"
            $ThumbPrint = Get-ChildItem -Path cert:\localMachine\my | Where-Object {$_.FriendlyName -like "$($env:COMPUTERNAME)Cert"} | 
            Select-Object -ExpandProperty ThumbPrint -ErrorAction 'SilentlyContinue'
            if (-not($Thumbprint)) {
                $ThumbPrint = New-SelfSignedCertificate -DnsName $env:COMPUTERNAME -FriendlyName "$env:COMPUTERNAME`Cert" -CertStoreLocation "cert:\LocalMachine\My" |
                Select-Object -ExpandProperty Thumbprint
            }
            New-Item -ItemType Directory -Path "$env:TEMP\DSCPullServerLab\MOF" -Force | Out-Null
            Sample_xDscWebService -certificateThumbPrint $ThumbPrint -OutputPath "$env:TEMP\DSCPullServerLab\MOF" | Out-Null
            Start-DscConfiguration -Path "$env:TEMP\DSCPullServerLab\MOF" -Wait -Verbose -Force
        }
    }
    catch [System.Net.Sockets.SocketException],
          [System.Management.Automation.Remoting.PSDirectException],
          [System.Management.Automation.Remoting.PSRemotingDataStructureException] {
        $Attempts--
        if ($Attempts -lt 1) {
            Get-PSSession | Remove-PSSession -ErrorAction 'SilentlyContinue'
            throw "Ran out of attempts while trying to configure $VMName as a pull server"
        }
        $params = @{VMName                              = $VMName
                    Credential                          = $Credential
                    XPSDesiredStateConfigurationVersion = $XPSDesiredStateConfigurationVersion
                    Attempts                            = $Attempts}
        Install-DSCPullServer @params
    }
    catch {
        $PSCmdlet.ThrowTerminatingError($_)
    }
    finally {
        Get-PSSession | Remove-PSSession -ErrorAction 'SilentlyContinue'
    }
}