Volume Health Checks in PowerShell
I was asked to write a script to monitor the health of the volumes for our web application farm. The original request was to monitor how much disk space was free on each volume, however I wanted the ability to monitor the integrity and fragmentation of the volume as well.
The first issue was we wanted to exclude the 100mb partition that Windows creates for the boot up process. This doesn't generally change and we didn't want it causing too much noise.
Checking the fragmentation status of a volume is available through WMI, through WMI you can easily ask Windows if that particular volume isfragment and get a True or False response.
File system integrity is a little different. NTFS has a dirty flag, which is used by check disk during boot to determine if it should perform a check on that volume. One annoying issue is there are two methods to check this flag, WMI or the CHKNTFS.EXE, WMI is considered to be more reliable, but there are many discussions on the Internet in regards to how reliable it is. CHKNTFS cannot run on a drive without a drive letter, so you need to be careful when scripting with it. In the end, my script will perform both tests where possible.
Using my usual template, the code below is for the body.
If you want to skip the 100mb system drives, set $thresholdexcludesystem to $true
Exporting the registry
When it comes to manipulating the registry, PowerShell gives you a truckload of options, personally, if its something as simple as backing up and restoring entries, nothing beats the proven old fashioned methods.
I needed to backup some registry keys recently, this will be running in my usual template as a scheduled task. I wanted to know if there was every an issue when trying the export.
My code looked like:
$key is the registry path you want to export, and $destfile is the resulting .reg file you want to export to.
Physical Disks, SMART and PowerShell
It is always nice to know when a physical hard disk is about to fail. The SMART status of a drive in Windows is the best way to know that there is potentially a problem comming up, SMART will often be the first sign of a drive failure, but Windows is yet to provide a great way of telling you what SMART is trying to tell it.
Another issue, is through Disk Manager and Device Manager, it can be difficult to get the serial number of a disk, leading to difficulty in identifying the disk that is failing when you do go to replace it.
I discovered that WMI actually can provide a very good interface with the SMART status, as well as a great mechanism for getting the serial number of a disk as well!
I created a script using my usual template, with the following in the body. I have scheduled this script to run hourly.
Web Application Warming
Original Issue: Web application is a bit unstable, restarting IIS seems to resolve issues for a few days.
Solution to original issue: Powershell script to restart application components including IIS in early hours of morning.
... A few weeks go by ...Users happy that application is significantly more stable during the day, however a small group of users complain about the performance of the application. Why is the performance suddenly dropping for those users?
First look at users issues: These users are always the first in the office, some appear not to sleep and decide to go to work at very early hours.
Root Cause: Now that we are restarting IIS, ASP.NET is recompiling the dynamic code when it is accessed for the first time, thus causing performance issues for first user hitting each part of the web site.
Solution 1: Use the Microsoft Web Application Warm up tool
Problem with Solution 1: Microsoft pulled the tool from their site
Solution 2: Write a script to handle this issue!
Writing a script for this solution was pretty easy:
- Get listing of all web pages which form application, put in file of format:
index.aspx
contact/contact_us.aspx
The reason to do this is the application resides in multiple SDLC environments with different base URLs but the same relative paths - Put the list from step 1 into a file
- Get the wget.exe from the gnuwin32 project. Why this and not the .net framework? Simply, put, from my experience the wget.exe was better at forcing all of the content to be loaded correctly in a manner a browser would. Go here for more info on the gnuwin32 project http://gnuwin32.sourceforge.net
- Based on the usual template:
Testing Ports are up
As usual, some more requests came to me, this time for soem monitoring, once again I took a look at the Script Centre and the Script Repositiory and found this very amazing cmdlet: http://gallery.technet.microsoft.com/scriptcenter/97119ed6-6fb2-446d-98d8-32d823867131
This is wonderful work as it allows you to not only test TCP ports, but also UDP ports. I will post up my monitoring script based upon this shortly.
FQDN to IP
I needed to make a script resolve an hostname (FQDN) to the IP address, my first stop for most of these sorts of scripts is the Microsoft Script repository, where I found a lovely function to do just that!
Check out Get-IPAddress at http://gallery.technet.microsoft.com/scriptcenter/44e9fef7-a04b-40b3-bb05-97659e56e27e
Cheers out to Ben Wilkinson for his great work!
Incomming! lots of Powershell!
I have a small fleet of scripts to post in the coming weeks.
I am not posting them in full as that will take too much space, I may put some of these up in the download section but need to clearance to do so first.
For all the posts I have used my standard template that I have discussed previously and is available for download (here).
When I post the code there will be two sections
Parameters:
If i needed to add extra parameters from the default ones, they will be listed here.
Body:
Code here is in the body of the script and does the work
Regular Expressions in Powershell
As part of a script I am working on, I needed to parse some web content which was stored on a remote server; in this case, I needed to scrap a particular set of web links of the page and report back.
The best way to get content of the internet from within a script is wget, which from within Windows you can make use of the GNUWin32 project. I will post about how useful this project is to Windows Scripting and administration later!
Back to the topic at hand.
After getting the content from the web and saving it as a file, I then put the content into a variable using Get-Content, from there, searching the content was pretty easy. First you need to make a RegularExpression.Regex object, and from there, you can feed any string into that object, and it will return the matches.
For Example: