DSCResources/MSFT_xHostsFile/MSFT_xHostsFile.psm1
#region localizeddata if (Test-Path "${PSScriptRoot}\${PSUICulture}") { Import-LocalizedData -BindingVariable LocalizedData ` -Filename MSFT_xHostsFile.psd1 ` -BaseDirectory "${PSScriptRoot}\${PSUICulture}" } else { #fallback to en-US Import-LocalizedData -BindingVariable LocalizedData ` -Filename MSFT_xHostsFile.psd1 ` -BaseDirectory "${PSScriptRoot}\en-US" } #endregion function Get-TargetResource { [OutputType([System.Collections.Hashtable])] param( [Parameter(Mandatory = $true)] [System.String] $HostName, [Parameter(Mandatory = $false)] [System.String] $IPAddress, [Parameter(Mandatory = $false)] [System.String] [ValidateSet("Present","Absent")] $Ensure = "Present" ) Write-Verbose -Message ($LocalizedData.StartingGet -f $HostName) $hosts = Get-Content -Path "$env:windir\System32\drivers\etc\hosts" $allHosts = $hosts ` | Where-Object { [System.String]::IsNullOrEmpty($_) -eq $false -and $_.StartsWith('#') -eq $false } ` | ForEach-Object { $data = $_ -split '\s+' if ($data.Length -gt 2) { # Account for host entries that have multiple entries on a single line $result = @() for ($i = 1; $i -lt $data.Length; $i++) { $result += @{ Host = $data[$i] IP = $data[0] } } return $result } else { return @{ Host = $data[1] IP = $data[0] } } } | Select-Object @{ Name="Host"; Expression={$_.Host}}, @{Name="IP"; Expression={$_.IP}} $hostEntry = $allHosts | Where-Object { $_.Host -eq $HostName } if ($null -eq $hostEntry) { return @{ HostName = $HostName IPAddress = $null Ensure = "Absent" } } else { return @{ HostName = $hostEntry.Host IPAddress = $hostEntry.IP Ensure = "Present" } } } function Set-TargetResource { param( [Parameter(Mandatory = $true)] [System.String] $HostName, [Parameter(Mandatory = $false)] [System.String] $IPAddress, [Parameter(Mandatory = $false)] [System.String] [ValidateSet("Present","Absent")] $Ensure = "Present" ) $currentValues = Get-TargetResource @PSBoundParameters Write-Verbose -Message ($LocalizedData.StartingSet -f $HostName) if ($Ensure -eq "Present" -and $PSBoundParameters.ContainsKey("IPAddress") -eq $false) { $errorId = 'IPAddressNotPresentError' $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidArgument $errorMessage = $($LocalizedData.UnableToEnsureWithoutIP) -f $Address,$AddressFamily $exception = New-Object -TypeName System.InvalidOperationException ` -ArgumentList $errorMessage $errorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord ` -ArgumentList $exception, $errorId, $errorCategory, $null $PSCmdlet.ThrowTerminatingError($errorRecord) } if ($currentValues.Ensure -eq "Absent" -and $Ensure -eq "Present") { Write-Verbose -Message ($LocalizedData.CreateNewEntry -f $HostName) Add-Content -Path "$env:windir\System32\drivers\etc\hosts" -Value "`r`n$IPAddress`t$HostName" } else { $hosts = Get-Content -Path "$env:windir\System32\drivers\etc\hosts" $replace = $hosts | Where-Object { [System.String]::IsNullOrEmpty($_) -eq $false -and $_.StartsWith('#') -eq $false } | Where-Object { $_ -like "*$HostName" } $multiLineEntry = $false $data = $replace -split '\s+' if ($data.Length -gt 2) { $multiLineEntry = $true } if ($currentValues.Ensure -eq "Present" -and $Ensure -eq "Present") { Write-Verbose -Message ($LocalizedData.UpdateExistingEntry -f $HostName) if ($multiLineEntry -eq $true) { $newReplaceLine = $replace -replace $HostName, "" $hosts = $hosts -replace $replace, $newReplaceLine $hosts += "$IPAddress`t$HostName" } else { $hosts = $hosts -replace $replace, "$IPAddress`t$HostName" } } if ($Ensure -eq "Absent") { Write-Verbose -Message ($LocalizedData.RemoveEntry -f $HostName) if ($multiLineEntry -eq $true) { $newReplaceLine = $replace -replace $HostName, "" $hosts = $hosts -replace $replace, $newReplaceLine } else { $hosts = $hosts -replace $replace, "" } } $hosts | Set-Content -Path "$env:windir\System32\drivers\etc\hosts" } } function Test-TargetResource { [OutputType([System.Boolean])] param( [Parameter(Mandatory = $true)] [System.String] $HostName, [Parameter(Mandatory = $false)] [System.String] $IPAddress, [Parameter(Mandatory = $false)] [System.String] [ValidateSet("Present","Absent")] $Ensure = "Present" ) $currentValues = Get-TargetResource @PSBoundParameters Write-Verbose -Message ($LocalizedData.StartingTest -f $HostName) if ($Ensure -ne $currentValues.Ensure) { return $false } if ($Ensure -eq "Present" -and $IPAddress -ne $currentValues.IPAddress) { return $false } return $true } |