Feb 082012
 

every once in a while i run into an issue where i have some log file on a microsoft sql server that has not been properly configured and is taking up a hundred gigs.

and inevitably, i end up spending the next 20 minutes to find a proper example of how to truncate the logs. so, instead of searching again, i am posting it on my site ;)

WARNING: don’t do this unless you have backups or you really, really don’t want to roll your database back. your deleting transaction logs, so while it won’t hurt your working database, it will prevent you from rolling back to yesterday. ye be warned.

in this case, i am running these commands on a microsoft sql server 2005 install, but i would presume it to work on sql 2008 or 2012, although i haven’t tested it.

here is the code:

-- specify database and show database & log statistics
USE dbname
EXEC sp_helpfile
 
-- truncate the log
USE dbname
GO
BACKUP LOG dbname WITH TRUNCATE_ONLY
GO
DBCC SHRINKFILE (dbname_log, 1)
GO
DBCC SHRINKFILE (dbname_log, 1)
GO
 
--show statistics after truncating
EXEC sp_helpfile

reference/disclaimer: this code is from http://www.sqlcleanup.com/2008/sql-2005-truncating-log-files-and-recovering-space/ and is not my work, i just can’t always find it in a pinch.

Apr 212010
 

i am working on a script to reboot computers in the middle of the day (sounds crazy, i know). the criteria is that the machines have to not been rebooted in the past 72 hours. why? i have some laptop users that never reboot their machines, just dock and undock their machines (heck, they never even log out), so they are not getting some patches and/or software updates.

while i was working on the script (i plan on posting it when i get done), i ran into some weird results. after digging around a bit, i found out that the problem was that the script was using dns to query the computer with wmi, but was getting multiple results on the dns query. for example, it would look for “computer_01″, and our dns server would give back an ip for the machine. the problem was if you queried “computer_01″ again, you would get a second, different ip address.

so when i went to our dns server, sure enough, there was duplicate entries for the same computer. and a lot of them. obviously this was going to be something i would have to fix before my script would work. after googling a bit, i found out about dns scavenging.

more or less, dns scavenging looks at the age of the dns record and purges it if it hasn’t been used in over x days. i found a great guide and explanation located here:
http://blogs.technet.com/networking/archive/2008/03/19/don-t-be-afraid-of-dns-scavenging-just-be-patient.aspx

more or less, i did three things:

  1. i set scavenging up for 7 days
  2. i enabled scavenging
  3. now, the most important step. i waited

three questions came to my mind as i was reading about scavenging:

  1. why isn’t it enabled by default?
  2. how did i miss enabling this in the first place? i had some help setting up this domain (it was my first one), but i never saw or heard anything mentioned that i can remember about enabling scavenging.
  3. are there any downsides to scavenging?

at this point, i have had it enabled a few weeks (again, be patient once you have enabled it) and things have been working great ad the scavenging has definately cleaned things up. for the record, i am running this on a ms windows server 2003 r2 dns server.

now, back to working on that reboot script ;)

Apr 202010
 

one thing we noticed in our install of microsoft office 2007 on our terminal servers was initially the user names and company name were not set correctly.

this didn’t seem like that big of a deal to me at first, but then i saw the value of this user name. if multiple users have access to the same shared folder and two people are trying to access the same file, the second user trying to modify the file with be told that they can only have read-only access because its being used by “user name”. so, in our case, initially everyone’s user name was set to our administrators name.

obviously the user can call us and ask “who is editing the file?” and we can find out, but fixing this keeps us from getting one more call and easier on the user, so i wrote a script that would set it at login.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
' office_2007_set_username.vbs
'
' This script sets the username and company name correctly for Office products.
' Written because all users using Terminal Services version of office were showing
' the same user name, which made it hard to track down locks on files.
'

Option Explicit 
 
Dim objShell, objNetwork
Dim strUserName, strCompanyName
Dim strNameRegKey, strCompanyRegKey
 
Set objShell = CreateObject( "WScript.Shell" )
Set objNetwork = CreateObject("Wscript.Network")
 
' Set your user string and company name
strUserName = objNetwork.UserName
strCompanyName = "Your Company Name"
 
' Registry key locations for user name and company name
strNameRegKey = "HKCU\Software\Microsoft\Office\Common\UserInfo\UserName"
strCompanyRegKey = "HKCU\Software\Microsoft\Office\Common\UserInfo\CompanyName"
 
On Error Resume Next
 
' If company name doesn't match the strCompanyName, change it
If objShell.RegRead(strCompanyRegKey) <> strCompanyName Then
	objShell.RegWrite strCompanyRegKey, strCompanyName, "REG_SZ"
End If
 
' If the user's name in office doesn't match their AD user name, change it
If objShell.RegRead(strNameRegKey) <> strUserName Then
	objShell.RegWrite strNameRegKey, strUserName, "REG_SZ"
End If

Mar 302010
 

since we did a network overhaul (defined in detail shortly) 2 years ago, we have had zero incidents of malware/virus’/badware on any machines that we know of (i know i will probably walk into bedlam tomorrow morning after saying that ;). after a recent mailing list conversation, i thought i would share some stuff we have done in detail to help anyone else going about the same process. here we go.

the 30 thousand foot view is this:

  • we reformatted every workstation and every server in one weekend (yes, you read that correctly)
  • users given user only rights, no power users or administrators.
  • we leveraged ms gpo’s to hide the c drive, limit what type of files could be saved, and prevent applications from running unless specifically allowed (application whitelist), etc.
  • we utilized ms’s wsus to apply patches across the board, workstations and servers
  • we started using a gateway device that did web filtering and also implemented a squid proxy server with whitelists
  • a copy of advanced installer was purchased so we could create msi’s to push all software out via gpo’s (this is great for new versions of software, pulling back software, etc)
  • we used gpo’s to config the workstation so that it automatically logged into our terminal server farm via single sign on (sso), more or less creating a pseudo thin client out of cheap desktop machines

working motto’s:

  • if you want a user to do/not do something, don’t ask them. force them.
  • prevention is the best medicine

Continue reading »

Feb 262010
 

this morning on the way to work, i heard larry (from pauldotcom.com) talking about a script he used to pull the logs from a lot of machines. he mentioned a few things that he didn’t like about the script, and i actually had run into in a similar situation (and had similar dislikes). heres the details (and the solution):

for patching purposes and just good windows hygiene, i wanted to reboot all my workstations nightly.

i googled a bit, and found several ways to do this, but none that did it the way i pictured it.

the most frequent suggestion was to put a list of all the computers you wanted to be rebooted into a text file, then run a script against those computers using a wmi script or psshutdown. in my environment, i quickly found two problems with this:

  1. it was slow. because computers would sometimes be shutdown and the timeout was so long for powered down machines, rebooting hundreds of computers could take a long, long time if enough were shutdown
  2. laziness/forgetfulness. what are the chances of me and everyone i work with remembering to put new machines into the text file to be rebooted? maybe everyone else is better at this than we are, but i knew this had no shot of actually being kept current in our environment

so i set out to find a script that would reboot all computers in an AD OU, bypassing unavailable machines quickly, and not requiring any changes to the script if new machines were added or machines were removed.

here is what i came up with, see comments in the code for an explanation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
Dim strFilter, strAttrs, strScope, strDNSSuffix, strBase
Dim objConn, objRS, objShell,objExec,objFSO,objFile, fileName
 
Set objShell = CreateObject("Wscript.Shell")
 
' List out the OU's you want computers in to be rebooted. Remember, if you add an OU,
' increment the strRoot(x) in *both* places.
Dim strRoot(1)
strRoot(0) = "OU=warehouse,DC=domain,DC=local"
strRoot(1) = "OU=terminal_servers,OU=servers,DC=domain,DC=local"
 
' Set the filter for computers only
strFilter = "(objectclass=computer);"
strAttrs  = "name;"
strScope  = "subtree"
 
' Your domain name
strDNSSuffix = ".domain.local"
 
'This is your main loop, each time a different OU.
For i = 0 To UBound(strRoot)
     strBase   =  "<LDAP://" & strRoot(i) & ">;"
     Set objConn = CreateObject("ADODB.Connection")
     objConn.Provider = "ADsDSOObject"
     objConn.Open "Active Directory Provider"
     Set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope)
     objRS.MoveFirst
 
     'This is your inner loop, each time an individual PC found in the search of the base.
     While Not objRS.EOF
          If objRS.Bookmark Mod 1 = 0 Then
               ' Pause for two seconds (ran into issues if this moved too quick)
               WScript.Sleep 2000
          End If
          ' Call your shutdown computer sub to reboot the individual computers
          ShutDownComputer(objRS.Fields("name").Value & strDNSSuffix)
     Wend
 
     Set objConn = Nothing
     Set objRS = Nothing
 
Next
 
Sub ShutDownComputer(byval strComputer)
     Dim strShutDown,objShell
 
     ' Your psshutdown command with the following options: -r for reboot, -f for force, -c allow the user to cancel the shutdown, -t 300 to give the user
     ' 300 seconds (5 minutes) to close out of applications and save, -e for the error code (planned), and -m for the message the user will see
     strShutDown = "C:\some\path\psshutdown.exe -r -f -c -t 300 -e p:0:0 -m " & chr(34) & "Nightly restart of computer" & chr(34) & " \\" & strComputer
     Set objShell = CreateObject("WScript.Shell")
     objShell.Run strShutdown, 0, False
 
     Set objShell = Nothing
End Sub

psshutdown – http://technet.microsoft.com/en-us/sysinternals/bb897541.aspx
pauldotcom episode 187 notes – http://pauldotcom.com/wiki/index.php/Episode187

Feb 252010
 

so you can probably guess from the title that we were having problems with some msi’s not being deployed correctly to “random” virtual servers. you can also probably guess by the quotes around random that it wasn’t random at all, and there was a very good reason. here are the details.

we use a msi creator called advanced installer (www.advancedinstaller.com) to create and deploy all of our applications to client workstations and servers.

what we noticed was that after trying to install a msi to a cluster of terminal servers, the msi was only getting installed correctly on a handful a machines. now, i say “machines”, but the interesting wrinkle was that all these machines are actually virtual, and they are spread across a vmware esx cluster.

when we would log onto the windows host to look at the logs and why the msi didn’t get installed, here is what we found:

so even though the clock on the OS was right (and we triple checked this), at logon when policies and gpo’s were being applied, the clock was wrong. in this picture, this error actually happend about 3 minutes before the picture was taken, even though it shows a time difference of almost 8 hours.

the one thing we uncovered was that every server that got the gpo and msi’s installed correctly were all located on one esx host. when we looked at the time settings in esx, we found that on the servers having problems, the esx hosts ntp service was stopped, or hadn’t been configured at all.

from there, it was pretty easy. we just went to every esx/esxi host and configured and enabled the ntp server, and viola, the gpo’s and msi’s installed without a hitch!

Feb 242010
 

i initially was just going to post a fix i had found (via google) to resolve a rediculous problem that adobe acrobat reader 9.x has in it. after reviewing my fix and seeing how ugly the code/logic was, i ended up rewriting the script.

so there are two lessons in this post
1.    adobe will never get their act together (at least with acrobat reader 9)

2.    the fear of peer code review is good, and it forced me to reevaluate some sloppy scripts that “just work”, but do it in a half-baked manor
so here we go, adobe acrobat reader 9.x and its issues with redirected application data on a server 2008 terminal server
so the real problem here is not that adobe writes crappy code. the real problem is that adobe wrote some crappy code and has not fixed it.

here is the problem: if you are running redirected folders in an AD environment and you redirect your application data folder, adobe acrobat reader 9 will give you a c++ runtime error if you are not an administrator. i have seen several people come up with fixes, one works for some, but not for others, so ymmv.

the three fixes i have seen have been:
1.    give list folder / read data permissions on the root level (applied to this folder only) of your users or homes share
2.    create the local low folder
3.    lastly, and the one that i use with a vbscript, is do delete a particular registry key
here was my original code:

1
2
3
4
5
6
7
Option Explicit
 
Dim objShell
Set objShell = WScript.CreateObject(“WScript.Shell”)
 
On Error Resume Next
 
objShell.RegDelete “HKCU\Software\Microsoft\Active Setup\Installed Components\{89820200-ECBD-11cf-8B85-00AA005B4340}\Version”

so, no error checking, and technically speaking it worked, but its ugly. i went back and fixed this to do some logic to see if the key existed before it tried to delete it, and came up with the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
On Error Resume Next
 
Const HKEY_CURRENT_USER = &H80000001
strComputer = “.”
 
Set objRegistry = GetObject(“winmgmts:\\” & strComputer & “\root\default:StdRegProv”)
strKeyPath = “Software\Microsoft\Active Setup\Installed Components\{89820200-ECBD-11cf-8B85-00AA005B4340}”
strValueName = “Version”
objRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath,strValueName,strValue
 
If (IsNull(strValue) = False) Then
     objRegistry.DeleteValue HKEY_CURRENT_USER, strKeyPath, strValueName
End If

for us, running server 2008 terminal servers, this fixed the problem. users are now successfully running the latest version of adobe acrobat reader 9 with no errors.

if you want to see details of the problem, or look at some of the other solutions (the root share permissions fix or the local low fix), you can look at some of the following threads/links. they go into a lot more detail and explain what is happening and what to try to fix it

http://support.microsoft.com/kb/955555/en-us
http://forums.adobe.com/thread/391738?tstart=0
http://forums.adobe.com/thread/303079

Feb 202010
 

i was trying to troubleshoot a remote server 2008 system that where the gui wasn’t responding, you couldn’t log into the machine, but the box was still responding to pings, wmi requests, etc.

my guess is some process is hogging the processor, but without being able to log in, i needed a remote way to do determine if cpu usage is actually the culprit. while there are a few ways that came to mind (wmic, vbscript, etc), i thought of mark russinovich’s pslist tool.

by default, pslist doesn’t show you the cpu usage (it shows cpu time), but with a few options it will spit out what you need. here is what i ended up running:

1
C:\>pslist.exe -s -r 10 -t \\remote_computer

this ran pslist in task manager mode (-s, that shows cpu usage in %), refreshed every 10 seconds (-r 10), and in a process tree (-t), which i find handy for certain situations, all against the remote computer (\\remote_computer).

obviously you will need to run this as a user that has domain rights that gives you enough rights to run this command, locally or remotely.

heres a link to the pslist sysinternals website for download or more detailed information: http://technet.microsoft.com/en-us/sysinternals/bb896682.aspx