Editing hosts file with startup script through GPO

by i255d at 2012-12-06 14:11:39

I have 2003 Domain Controllers and a significant group of users logging in through Citirx desktops. My Citrix desktops are pushed out through a single image. When Citrix users logoff, they get a new base image next time they login with customization preserved through roaming profiles and GPO. A group of our users need access to specific sites, through one of our apps. For the short term, we have decided to add an entry to their hosts files. Management is suggesting I do this through GPO, a bat file as a logon script. He gave me this script, a batch file. I would like to see if I can do the same thing with PowerShell. My Citrix desktops are Windows 7 x64.

Can I user PowerShell for startup scripts?

Can I create a script in Power shell to do the same thing as this scrit:


:: Script to update Host Files for GPATrust Think Client Mexico

type %windir%\system32\drivers\etc\hosts | findstr /i "222.107.111.162" | findstr /i "gpaturst.georgiatrust.com"

if "%ERRORLEVEL%"=="1" (echo 222.107.111.162 gpaturst.georgiatrust.com >> %windir%\system32\drivers\etc\hosts)

type %windir%\system32\drivers\etc\hosts | findstr /i "222.107.111.173" | findstr /i "gpaturst-uat.georgiatrust.com"

if "%ERRORLEVEL%"=="1" (echo 222.107.111.173 gpaturst-uat.georgiatrust.com >> %windir%\system32\drivers\etc\hosts)

type %windir%\system32\drivers\etc\hosts | findstr /i "222.107.111.177" | findstr /i "gpaturst-stg.georgiatrust.com"

if "%ERRORLEVEL%"=="1" (echo 222.107.111.177 gpaturst-stg.georgiatrust.com >> %windir%\system32\drivers\etc\hosts)
by powerschill at 2012-12-06 14:43:52
I think the code below is what you need. In your code you use findstr to find the line with the IP address and then if that IP exists you also makes sure that line contains the DNS address. I did not include that second test because you probably don’t want to add a new record if the original IP address exists for any host.

$HostFile = "$($env:windir)\system32\Drivers\etc\hosts"

$Hosts = Get-Content -Path $HostFile
If (! ( $Hosts -match "222.107.111.162" ) ) { Add-Content -Path $HostFile -Value "222.107.111.162 gpaturst.georgiatrust.com" }
If (! ( $Hosts -match "222.107.111.173" ) ) { Add-Content -Path $HostFile -Value "222.107.111.173 gpaturst-uat.georgiatrust.com " }
If (! ( $Hosts -match "222.107.111.177" ) ) { Add-Content -Path $HostFile -Value "222.107.111.177 gpaturst-stg.georgiatrust.com" }
by nohandle at 2012-12-07 05:05:10
The hosts file has restricted access by default.
If the users are not given appropriate permissions, you hit the Access Denied wall.
To work around it should be possible to create a scheduled task that triggers on logon of members of certain AD group, has embedded admin account and uses the above script to apply the changes.
Hope I am not over complicating it.
by i255d at 2012-12-07 06:31:05
Ok, lets start with powerschill: I get everything except the "!". Isn’t that saying -not? So it reads If the file doesn’t contain this IP, then add this line of content? I guess I answered my own question.

nohandle, so are you saying that if this script was run from a NETLOGON share triggered by under logon script in GPO, it will be run with the credentials of the user logging on not system credentials, so it will fail?
I don’t think anyone answered: can I run PowerShell scripts from 2003 domain controllers that don’t contain .net or PowerShell. The Citrix desktops are Windows 7 and have a group policy to restrict running unsigned PowerShell Scripts.

Lastly, I ran the PowerShell script on my computer to see if it worked and now I have added one of these lines to my hosts file. Is there a way to delete that line or specific strings from my hosts file within PowerShell?
by i255d at 2012-12-07 06:49:03
I guess I don’t really know what this is either:

$($env:windir)

What is the first $ for?

What is the second $ for?

Evn is the drive where the environment variables are stored.

windir is the variable for C:\Windows on my box.

PS Env:>
by i255d at 2012-12-07 07:39:52
Sorry, one correction: this is a computer startup script, not a user logon script from GPO.
by nohandle at 2012-12-08 03:13:36
Thinking about, it why is not using cname DNS record an option?

[quote="i255d"]Sorry, one correction: this is a computer startup script, not a user logon script from GPO.[/quote]
Ah, that is totally different story.
1) yes ! is -not
2) $($env:windir) - $() marks subexpression, it is used in strings enclosed in quotes (" ") to mark part of the string that should be executed before the string is returned. if you want date returned you cant just do "get-date returns get-date" and anticipate poweshell knowing you want to expand only the second get-date. You must do "Get-date returns $(get-date)"
also if you want to show basename property of file object stored in $file varible. you cannot do just "filename is $file.basename" because only the $file would get expanded and the .filename would not. You have to mark it whole as expression "name is $($file.basename)".

the second $ marks you access the $env variable. you can use the env drive either like a drive and like a variable.

3) to remove line from the file load it to a variable, pipe the variable to where and let pass all the lines that don’t contain the text you want to remove. save the output to variable and save it to file or do it all directly.

get-content <add params here> | where {$_ -notmatch "10.0.0.0"} | out-file <add params here>
Btw Mark missed escaping the dots. ‘.’ means any character in regex so the previous example should also match 222a107b111c162 with the previous example.
-like operator is maybe better option because it does not use regex.