I’ve been working through a process of cleaning and optimising the C drives on a lot of VMs recently. Over time they build up with lots of junk that, when put together with hundreds of VMs, requires a significant amount of extra primary VM storage, backup storage, and increases backup times. These files also take up space within the VM that can cause security and anti-malware updates to fail, and lead to application or logging failures. The reduced free space also leads to increased file fragmentation, which then means more IOs to and from your storage.

So the first step in my process is to run this script, which deletes various unnecessary bits and pieces from the Windows folder and user profiles, and empties recycle bins and deletes various other folders that some of my colleagues have a tendency to put onto the C drive (e.g. 5GB of SQL Server install media, which is available for them on the network).

It copes with various flavours of OS, I’ve been using it on 2003 through 2008 R2 so far. You can add paths to the array at the beginning. For paths within the Users (or Documents and Settings) folder it will search through each user profile, excluding the local administrator or any service accounts (which in my organisation all contain “svc” in the name.

I’m toying with the idea of removing the $hf_mig$ folder on 2003 now that there will be no more security updates, likewise SoftwareDistribution, but I’ve not fully looked into the implications of this yet. There’s probably lots of other places where stuff can be safely deleted from too. Another one I’ve just thought of would be *.log from the Windows folder.

The wildcards rely on the handling within the Remove-Item cmdlet, so if you’re not sure what it’ll do, it’s easy to try it manually on a test folder first.

DO NOT run this without understanding what it does, and knowing what data your applications store where, and how your users work. I AM NOT responsible if you run this and trash your server(s)! Look very carefully at the paths that I’m using and see if each one is something you feel happy with or not. That said, it hasn’t caused me any problems yet – I’ve run it on about 30 different servers so far.

This uses a FileSystemWatcher object and its WaitForChanged method, which is rather nifty way to not use much resource to keep track of file system changes. What we’re NOT doing here is polling the folder contents.

I’m then trying a couple of different methods to try and work out, if possible, the user responsible for the changes. This doesn’t always work, but it’s not too bad. You’ll get better info about the user if the folder is being accessed remotely via an SMB share thanks to the Get-SmbOpenFile cmdlet, otherwise I try and get the file owner, or don’t bother at all. Get-SmbOpenFile needs elevated privileges so you’ll need to run this “as administrator”.

I’m a big fan of the built-in Windows Disk Cleanup utility, cleanmgr.exe. Since the extra features added to the Vista & Server 2008 version it has become a great way to recover sometimes quite substantial amounts of space from your system (OS) drive though its Windows Update Cleanup feature.

Here’s an example run on one of my Server 2008 R2 VMs:
Nearly 8GB back? Thank you very much! Here’s another:

I’ll get nearly 12GB back on this server, installed in 2010.

If the Windows Update Cleanup option doesn’t show its because no space can be freed by that method (or you ran it once with that option and haven’t rebooted yet, see below). Or you didn’t run it “as administrator”.

Note that on a desktop OS such as Windows 7 or 8.x Disk Cleanup is always present. I recovered about 5GB on my Windows 7 laptop.

Disk Cleanup is actually a very powerful utility, hidden behind a fairly basic GUI. You can write your own custom cleanup tasks, either using the built-in DataDrivenCleaner COM object, or by writing you own (go on, you know you want to!). The DataDrivenCleaner can be used to search for (e.g.) files with a specific file extension in a certain folder that are older than a certain number of days.

Note that on Windows 7 and 2008 R2 (and probably Vista & Server 2008 too) you have to manually reboot after doing the Windows Update Cleanup, you won’t be prompted.

As the computer is shutting down, you then get a “Configuring Windows Updates” briefly, then as it starts back up you’ll get it again, and it might sit at 100% for a while:

Then it’ll reboot again (automatically), and on the way up will sit at “Cleaning up.”:

This might take a while too. The whole process could take half an hour or more, depending on how fast your CPU and disk are and how much stuff it found to tidy up. Once it finishes you’ll have the space back.

Note that if you run the script on a domain controller, you need to be running PowerShell “As Administrator” or you’ll get an “Access is denied” error. If you run the script from elsewhere you just need permission to create the accounts.

Another quickie. The requirement was to get an email alert when CPU usage reached over 90%. This is achievable via PerfMon Data Collector Set alerts, EventLog task triggers and a script to send an email (unless you’re on pre-Server 2012 when you could send an email as an event log trigger directly – why was that option removed?).

But that’s a load of faff, whereas this script is tiny and easy to schedule to start via Task Scheduler. Or just run it when you log on (though you never log on to the console of a server do you…?).

It demonstrates how easy it is to get values out of the performance counters without having to resort to WMI.

Rate this:

Last week a Juniper SRX firewall was put in to replace an older internal firewall. This week a load of Windows Servers dropped out of Active Directory DNS. The scavenging period in AD DNS was configured to be 7 days. Coincidence? I think not.

But what was going on, and why? DNS queries were working from the affected servers, and servers not behind the new SRX firewall were unaffected. I ran Wireshark on an affected server and on the primary DNS server it was configured to talk to.

There were indeed UDP packets going back and forth quite happily between the affected server and the DNS server, originating on a high port within the range 49152 – 65535 and going to port 53 on the DNS server. So I knew that it wasn’t a firewall port rule thing – DDNS uses the same ports as any other DNS traffic.

DNS traffic contains a set of flags that tell the DNS server what type of operation it should do with the rest of the data in the communication. For a standard DNS query the flags are 0x0100. These were being sent and received as normal: I could see the DNS transaction IDs matching up on both the affected server and the DNS server.

However, a DDNS update is distinguished by having the flags set to 0x2800, and for these all I could see was the dynamic update data being sent out of the affected server but this was never received at the DNS server. The effected server’s DNS Client service would keep sending the data for a while and then give up and a warning event 8015 in the System Event Log:

So something was eating the Dynamic DNS update data as it went over the network, but was not eating regular DNS queries. Whatever it was was looking at the flags inside the DNS data and only blocking dynamic update DNS traffic.

So I did a bit of searching and found that this was a known problem with Juniper SRX firewalls due to the ALG (Application Layer Gateway). I spoke to my SRX expert who assured me that ALG was switched off. After a few more hours of testing he discovered that ALG was in fact not switched off after all, and after disabling it for DNS everything is working normally again. It seems that ALG defaults are generally not ideal anyway when it comes to DNS.