Mylmhost.psm1
#requires -version 5.0.0.0 #region Main Function Get-LmhostsEntry { [cmdletbinding(DefaultParameterSetName="Name")] Param( [Parameter(Position=0,Mandatory,ParameterSetName="Name")] [Alias("CN","Name")] [string]$Computername, [Parameter(Mandatory,ParameterSetName="IP")] [ValidatePattern("(\d{1,3}\.){3}\d{1,3}")] [string]$IPAddress, [Parameter(Mandatory,ParameterSetName="All")] [switch]$All, [switch]$Raw ) Begin { Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)" #display PSBoundparameters formatted nicely for Verbose output [string]$pb = ($PSBoundParameters | Format-Table -AutoSize | Out-String).TrimEnd() Write-Verbose "[BEGIN ] PSBoundparameters: `n$($pb.split("`n").Foreach({"$("`t"*4)$_"}) | Out-String) `n" if (-not (Test-Path $lmfile )) { Write-Warning "No file found at $lmfile. Use Set-LmhostsEntry to add an entry." $Verified = $False } else { $Verified = $True } } #begin Process { If ($Verified) { Write-Verbose "[PROCESS] Get entry by $($PSCmdlet.ParameterSetName)" Switch ($PSCmdlet.ParameterSetName) { "Name" { $find = $Computername } "IP" { $find = $IPAddress } Default { #get all entries } } #switch if ($all) { $data = Get-Content $lmfile | Select-String -pattern "^[^#.*]" if ($raw) { $IPv4Pattern.matches($data).value } else { #create an object for each entry $IPv4Pattern.matches($data).Captures | foreach { [pscustomobject]@{ Computername = $_.Groups["Computername"] IPAddress = $_.Groups["IP"] } } #foreach } } #get all else { Write-Verbose "[PROCESS] ...$find" $entry = Get-Content -Path $lmfile | Select-String -pattern $find -AllMatches if ($entry) { Write-Verbose "[PROCESS] Found one or more matching entries" if ($Raw) { Write-Verbose "[PROCESS] Writing raw results to the pipeline" #write the raw entry to the pipeline $entry } else { foreach ($item in $entry) { #split into parts and write a new object to the pipeline $m = $IPv4Pattern.Match($item) [pscustomobject]@{ Computername = $m.Groups["Computername"].value IPAddress = $m.Groups["IP"].value } } #foreach } #else } #if entry found else { Write-Warning "Entry for $($PSBoundParameters.values) not found." } } #else find single entry } #if verified }# process End { Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)" } #end } #close Get Function Remove-LmhostsEntry { [cmdletbinding(SupportsShouldProcess,DefaultParameterSetName="Name")] Param( [Parameter(Position=0,Mandatory,ParameterSetName="Name",ValueFromPipelineByPropertyName)] [Alias("CN","Name")] [string]$Computername, [Parameter(Mandatory,ParameterSetName="IP",ValueFromPipelineByPropertyName)] [ValidatePattern("(\d{1,3}\.){3}\d{1,3}")] [string]$IPAddress ) Begin { Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)" #display PSBoundparameters formatted nicely for Verbose output [string]$pb = ($PSBoundParameters | Format-Table -AutoSize | Out-String).TrimEnd() Write-Verbose "[BEGIN ] PSBoundparameters: `n$($pb.split("`n").Foreach({"$("`t"*4)$_"}) | Out-String) `n" if (-not (Test-Path $lmfile )) { Write-Warning "No file found at $lmfile. Use Set-LmhostsEntry to add an entry." $Verified = $False } else { $Verified = $True } } #begin Process { If ($Verified) { Write-Verbose "[PROCESS] Removing entry by $($PSCmdlet.ParameterSetName)" $findparams = @{Raw = $True} Switch ($PSCmdlet.ParameterSetName) { 'Name' { $findparams.Add("Computername",$PSBoundParameters.item("Computername")) } #computername 'IP' { $findparams.Add("IPAddress",$PSBoundParameters.Item("IPAddress")) } #IP } #switch Write-Verbose "Searching for entry" $entry = Get-LmhostsEntry @findparams if ($entry) { Write-Verbose "[PROCESS] Creating a backup file copy" Copy-Item -Path $lmfile -Destination $lmbackup $content = Get-Content -Path $lmfile Write-Verbose "[PROCESS] Removing $get" ($content -replace $entry,"") | Out-File -FilePath $lmfile -Encoding ascii } } #if verified }# process End { Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)" } #end } #close Remove Function Set-LmhostsEntry { [cmdletbinding(SupportsShouldProcess)] Param( [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [Alias("CN","Name")] [string]$Computername, [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [ValidatePattern("(\d{1,3}\.){3}\d{1,3}")] [string]$IPAddress, [switch]$Passthru ) Begin { Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)" if (-not (Test-Path $lmfile )) { Write-Verbose "[BEGIN ] Creating a new lmhosts file: $lmfile" Set-Content -Value "#lmhosts file for resolving NETBIOS names `n" -Path $lmfile -Encoding Ascii } } #begin Process { #display PSBoundparameters formatted nicely for Verbose output [string]$pb = ($PSBoundParameters | Format-Table -AutoSize | Out-String).TrimEnd() Write-Verbose "[PROCESS] PSBoundparameters: `n$($pb.split("`n").Foreach({"$("`t"*2)$_"}) | Out-String) `n" $entry = "$IPAddress $Computername" Write-Verbose "[PROCESS] Check for existing entry $entry" #There should only be one or at least we'll only process one $existing = Get-Content -Path $lmfile | Select-String $Computername | Select -last 1 if ($existing) { [string]$line = $existing.Line Write-Verbose "[PROCESS] Processing existing entry: $line" $m = $IPv4Pattern.Match($line) $OldComputername = $m.Groups["Computername"].value $oldIP = $m.Groups["IP"].value Write-Verbose "Existing Computername = $oldComputername" Write-Verbose "Existing IPAddress = $oldIP" if (($oldIP -eq $IPAddress) -and ($OldComputername -eq $Computername)) { Write-Host -foreground Green "The Computername and IP address matches the current entry. No changes needed." -ForegroundColor Magenta #exit Return } else { #modify the line $Replace = $True } } #if existing #create a backup copy of the file Write-Verbose "[PROCESS] Creating a backup file copy" Copy-Item -Path $lmfile -Destination $lmbackup #insert the line if ($Replace) { $content = Get-Content -Path $lmfile Write-Verbose "[PROCESS] Replacing $oldIP with $Ipaddress" ($content -replace $line,$entry) | Out-File -FilePath $lmfile -Encoding ascii } else { #insert at the end Write-Verbose "[PROCESS] Appending $entry" $entry | Out-File -FilePath $lmfile -Append -Encoding ascii } If ($Passthru) { Get-LmhostsEntry -Computername $Computername } } #process End { Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)" } #end } #close Set #endregion #define variables for internal use. These are not exported #path to lmhosts file $lmfile = "$env:windir\system32\drivers\etc\lmhosts" #define a backup file variable $lmbackup = "$env:windir\system32\drivers\etc\lmhosts.bak" #IPv4 Regex pattern [regex]$IPv4Pattern = "(?<IP>\b(\d{1,3}\.){3}\d{1,3}\b)\s+(?<Computername>\b\S+\b)" |