PKWmfInstall.psm1

#region Private Functions

Configuration PKWmfInstall {
    Import-DscResource -Module PSDesiredStateConfiguration,@{ModuleName='xWindowsUpdate';RequiredVersion='1.0'},@{ModuleName='xPendingReboot';RequiredVersion='0.1.0.2'}

    Node $ComputerName {

        LocalConfigurationManager {
            RebootNodeIfNeeded = $Reboot
            RefreshMode        = 'PUSH'
        }

        File TempDir {
            DestinationPath = 'c:\temp'
            Force           = $True
            Ensure          = 'Present'
            Type            = 'Directory'
        }

        File WMFSource {
            DestinationPath = "c:\temp\$File"
            Ensure          = 'Present'
            SourcePath      = $FullPath
            Type            = 'File'
            Force           = $True
            DependsOn       = '[File]TempDir'
        }

        if (!($CopyOnly)) {
            xHotFix WMFInstall {
                Id        = $KB
                Ensure    = 'Present'
                Path      = "c:\temp\$File"
                DependsOn = '[File]WMFSource'
            }

            if ($Reboot) {
                xPendingReboot WMFReboot {
                    Name      = 'RebootMe'
                    DependsOn = '[xHotFix]WMFInstall'
                }
            }
        }
    }
}

function Copy-PKResource {

[CmdletBinding()]
param(
    [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
    [string[]]$ComputerName,

    [string[]]$Module
)

    PROCESS {

        foreach ($Computer in $ComputerName) {

            if ($Computer -ne $env:COMPUTERNAME -and $Computer -ne 'localhost' -and $Computer -ne '.') {

                foreach ($Mod in $Module) {

                    Copy-Item "$Env:ProgramFiles\WindowsPowerShell\Modules\$Mod" "\\$Computer\C$\Program Files\WindowsPowerShell\Modules\" -Recurse -Force

                }
            }
        }
    }
}

function New-PKWmfConfiguration {

[CmdletBinding(SupportsShouldProcess,ConfirmImpact='Medium')]
param(
    [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
    [string[]]$ComputerName,

    [bool]$Reboot = $false,
    [bool]$CopyOnly = $false
)

    BEGIN {
        $Config = Get-Content (Join-Path (Split-Path $Script:MyInvocation.MyCommand.Path) 'config.json') | ConvertFrom-Json
        $FullPath = Join-Path $Config.WMFUncPath $Config.W2K12R2
        $File = $Config.W2K12R2

        if (!(Test-Path $FullPath)) {
            Write-Warning "File not found $FullPath"
            break
        }

        $KB = $File.Split('-') | Where-Object {$_ -match 'KB'}
        Write-Verbose $KB

        $Working = (Get-Location).Path
        Set-Location (Split-Path $Script:MyInvocation.MyCommand.Path)
    }

    PROCESS {

        foreach ($Computer in $ComputerName) {

            if ($PSCmdlet.ShouldProcess($Computer)) {

                PKWmfInstall

            }
        }
    }

    END {
        Set-Location $Working
    }
}

#endregion


function New-PKWmfShare {

[CmdletBinding(SupportsShouldProcess,ConfirmImpact='High')]
param(
    [string]$FolderPath = 'C:\',
    [string]$FolderName = 'WMFInstall'
)

    PROCESS {

        $WMFUncPath = "\\$env:COMPUTERNAME\$FolderName\"
        $Path = Join-Path $FolderPath $FolderName

        if (!(Test-Path $WMFUncPath)) {

            if ($PSCmdlet.ShouldProcess($WMFUncPath)) {

                if (!(Test-Path $Path)) {
                    New-Item -Path $FolderPath -Name $FolderName -Type Directory | Out-Null
                    Write-Verbose "Created $Path"
                }

                New-SmbShare -ReadAccess Everyone -Path $Path -Name $FolderName | Out-Null
                Write-Verbose "Shared $WMFUncPath"
            }
        }

        $Config = New-Object PSObject
        $Config | Add-Member -NotePropertyName WMFUncPath -NotePropertyValue $WMFUncPath


        #$OperatingSystem = 'W2K8R2','W2K12','W2K12R2'
        $OperatingSystem = 'W2K12R2'

        $ConfirmationPage = "http://www.microsoft.com/en-us/download/$(((Invoke-WebRequest 'http://aka.ms/wmf5latest' -UseBasicParsing).Links | Where-Object Class -eq 'mscom-link download-button dl').href)"

        foreach ($OS in $OperatingSystem) {
            $URL = ((Invoke-WebRequest $ConfirmationPage -UseBasicParsing).Links | Where-Object Class -eq 'mscom-link' | Where-Object href -match $OS).href[0]
            Write-Verbose "Url $URL"

            $File = $URL.Split('/')[-1]

            Invoke-WebRequest $URL -OutFile (Join-Path $Path $File)
            Write-Verbose "Downloaded $File"

            $Config | Add-Member -NotePropertyName $OS -NotePropertyValue $File
        }

        $Config | ConvertTo-Json | Out-File (Join-Path (Split-Path $Script:MyInvocation.MyCommand.Path) 'config.json')
    }
}


function Start-PKWmfInstall {

[CmdletBinding(SupportsShouldProcess,ConfirmImpact='High')]
param(
    [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
    [string[]]$ComputerName,

    [switch]$Reboot,
    [switch]$CopyOnly
)

    BEGIN {
        if (!(Test-Path (Join-Path (Split-Path $Script:MyInvocation.MyCommand.Path) 'config.json'))) {
            Write-Warning 'Please run New-PKWmfShare'
            break
        }

        if ($Reboot) {
            [bool]$Reboot = $true
        } else {
            [bool]$Reboot = $false
        }

        if ($CopyOnly) {
            [bool]$CopyOnly = $true
        } else {
            [bool]$CopyOnly = $false
        }
    }

    PROCESS {

        $Path = Join-Path (Split-Path $Script:MyInvocation.MyCommand.Path) PKWmfInstall
        Write-Verbose $Path

        foreach ($Computer in $ComputerName) {

            if ($Computer -eq 'localhost' -or $Computer -eq '.') {
                Write-Warning "Please use computer name instead of $Computer"
                continue
            }

            if ($PSCmdlet.ShouldProcess($Computer)) {

                $Files = New-PKWmfConfiguration -ComputerName $Computer -Reboot $Reboot -CopyOnly $CopyOnly
                $Files | ForEach-Object { Write-Verbose "Created $_" }

                #Set-NetFirewallRule -CimSession $Computer -DisplayGroup "File and Printer Sharing" -Profile Domain -Enabled True

                Copy-PKResource -ComputerName $Computer -Module xWindowsUpdate,xPendingReboot

                Set-DscLocalConfigurationManager -Path "$Path" -Verbose

                Start-DscConfiguration -Path "$Path" -ComputerName $Computer -Wait -Verbose -Force
            }
        }
    }
}


function Get-PKWmfInstall {

[CmdletBinding()]
param(
    [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
    [string[]]$ComputerName
)

    PROCESS {

        foreach ($Computer in $ComputerName) {

            if (!(Test-WSMan $Computer -ea SilentlyContinue)) {
                Write-Warning "Connection denied $Computer"
                continue
            }

            $Version = Invoke-Command -ComputerName $Computer -ScriptBlock { "$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)" }

            try {
                Get-DscConfiguration -CimSession $Computer -ea Stop | Out-Null
                $Removed = $false
            } catch {
                $Removed = $true
            }

            [PSCustomObject]@{
                ComputerName=$Computer
                PowerShell=$Version
                ConfigRemoved=$Removed
            }
        }
    }
}

function Clear-PKWmfConfiguration {
    $Path = Join-Path (Split-Path $Script:MyInvocation.MyCommand.Path) PKWmfInstall

    try {
        Remove-Item "$Path" -Recurse -Force -ea Stop
    } catch {
        Write-Warning "Nothing to clear in $Path"
    }
}

function Remove-PKWmfConfiguration {

[CmdletBinding(SupportsShouldProcess,ConfirmImpact='High')]
param(
    [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
    [string[]]$ComputerName
)

    PROCESS {

        foreach ($Computer in $ComputerName) {

            if ($PSCmdlet.ShouldProcess($Computer)) {

                Invoke-Command -ComputerName $Computer -ScriptBlock {
                    Remove-Item 'C:\windows\system32\configuration\*.mof'
                    Remove-Item 'C:\Program Files\WindowsPowerShell\Modules\[xc]*' -Recurse -Force
                }
            }
        }

        Get-PKWmfInstall -ComputerName $Computer
    }
}