DSCResources/cChocoInstaller/cChocoInstaller.psm1
# Copyright (c) 2017 Chocolatey Software, Inc. # Copyright (c) 2013 - 2017 Lawrence Gripper & original authors/contributors from https://github.com/chocolatey/cChoco # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. function Get-TargetResource { [OutputType([hashtable])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "InstallDir")] param ( [parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $InstallDir, [parameter()] [string] $ChocoInstallScriptUrl = 'https://chocolatey.org/install.ps1' ) Write-Verbose 'Start Get-TargetResource' #Needs to return a hashtable that returns the current status of the configuration component $Configuration = @{ InstallDir = $env:ChocolateyInstall ChocoInstallScriptUrl = $ChocoInstallScriptUrl } Return $Configuration } function Set-TargetResource { [CmdletBinding(SupportsShouldProcess)] param ( [parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $InstallDir, [parameter()] [string] $ChocoInstallScriptUrl = 'https://chocolatey.org/install.ps1' ) Write-Verbose 'Start Set-TargetResource' $whatIfShouldProcess = $pscmdlet.ShouldProcess('Chocolatey', 'Download and Install') if ($whatIfShouldProcess) { Install-Chocolatey @PSBoundParameters } } function Test-TargetResource { [OutputType([bool])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "ChocoInstallScriptUrl")] param ( [parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $InstallDir, [parameter()] [string] $ChocoInstallScriptUrl = 'https://chocolatey.org/install.ps1' ) Write-Verbose 'Test-TargetResource' if (-not (Test-ChocoInstalled)) { Write-Verbose 'Choco is not installed, calling set' Return $false } ##Test to see if the Install Directory is correct. $env:ChocolateyInstall = [Environment]::GetEnvironmentVariable('ChocolateyInstall','Machine') if(-not ($InstallDir -eq $env:ChocolateyInstall)) { Write-Verbose "Choco should be installed in $InstallDir but is installed to $env:ChocolateyInstall calling set" Return $false } Return $true } function Test-ChocoInstalled { Write-Verbose 'Test-ChocoInstalled' $env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') Write-Verbose "Env:Path contains: $env:Path" if (Test-Command -command choco) { Write-Verbose 'YES - Choco is Installed' return $true } Write-Verbose "NO - Choco is not Installed" return $false } Function Test-Command { Param ( [string]$command = 'choco' ) Write-Verbose "Test-Command $command" if (Get-Command -Name $command -ErrorAction SilentlyContinue) { Write-Verbose "$command exists" return $true } else { Write-Verbose "$command does NOT exist" return $false } } #region - chocolately installer work arounds. Main issue is use of write-host function global:Write-Host { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "NoNewLine")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "ForegroundColor")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "BackgroundColor")] Param( [Parameter(Mandatory,Position = 0)] $Object, [Switch] $NoNewLine, [ConsoleColor] $ForegroundColor, [ConsoleColor] $BackgroundColor ) #Redirecting Write-Host -> Write-Verbose. Write-Verbose $Object } #endregion function Get-FileDownload { param ( [parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$url, [parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$file ) # Set security protocol preference to avoid the download error if the machine has disabled TLS 1.0 and SSLv3 # See: https://chocolatey.org/install (Installing With Restricted TLS section) # Since cChoco requires at least PowerShell 4.0, we have .NET 4.5 available, so we can use [System.Net.SecurityProtocolType] enum values by name. $securityProtocolSettingsOriginal = [System.Net.ServicePointManager]::SecurityProtocol [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::Tls11 -bor [System.Net.SecurityProtocolType]::Tls -bor [System.Net.SecurityProtocolType]::Ssl3 Write-Verbose "Downloading $url to $file" $downloader = new-object -TypeName System.Net.WebClient $downloader.DownloadFile($url, $file) [System.Net.ServicePointManager]::SecurityProtocol = $securityProtocolSettingsOriginal } Function Install-Chocolatey { [CmdletBinding()] param ( [parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $InstallDir, [parameter()] [string] $ChocoInstallScriptUrl = 'https://chocolatey.org/install.ps1' ) Write-Verbose 'Install-Chocolatey' #Set permanent EnvironmentVariable Write-Verbose 'Setting ChocolateyInstall environment variables' [Environment]::SetEnvironmentVariable('ChocolateyInstall', $InstallDir, [EnvironmentVariableTarget]::Machine) $env:ChocolateyInstall = [Environment]::GetEnvironmentVariable('ChocolateyInstall','Machine') Write-Verbose "Env:ChocolateyInstall has $env:ChocolateyInstall" #Download an execute install script $tempPath = Join-Path -Path $env:TEMP -ChildPath ([GUID]::NewGuid().ToString()) New-Item -Path $tempPath -ItemType Directory | Out-Null $file = Join-Path -Path $tempPath -ChildPath 'install.ps1' Get-FileDownload -url $ChocoInstallScriptUrl -file $file . $file #refresh after install Write-Verbose 'Adding Choco to path' $env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') if ($env:path -notlike "*$InstallDir*") { $env:Path += ";$InstallDir" } Write-Verbose "Env:Path has $env:path" #InstallChoco $InstallDir $Null = Choco Write-Verbose 'Finish InstallChoco' } Export-ModuleMember -Function *-TargetResource |