Archive for the ‘microsoft’ Category

Powershell Delete Old Files…….

Thursday, April 5th, 2012

Here’s something that would have been a royal pain in the butt to achieve under DOS. A simple quick script to remove old files from a directory. Makes use of the Get-ChildItems cmdlet which deals with all the for/each/to/next .etc .etc looping stuff for us.

Logic is pretty straightforward. Get the current date. Subtract the number of days to keep (in this example, 31 days to keep x1 month of files). Then compare the max age date against the modification date on each file in the directory. If the modification date falls after the max date permitted, delete the file.

#---this script purges any file over x days old from the target folder---#

$now = get-date

$daystokeep = "31"

$targetfolder = "C:\somefolder\"

$age = $now.adddays(-$daystokeep)

$files = get-childitem $targetfolder | where {$_.lastwritetime -le "$age"}

foreach ($file in $files)
{
if ($file -ne $null)
	{
	#write-host "deleting file $file"
	remove-item $file.fullname | out-null
	}
	else
	{
	write-host "done, no more files to delete"
	}
}

If you want to test without actually removing anything, you can comment out the remove-item line and un-commenting the line to make it output each file that qualifies for being old enough to delete.

If the folder contains sub directories, you can add a ‘-recurse’ argument to the $files = get-childitem… line before the ‘| where’.

You could also restrict the script to only consider files with a given file extension type by using -include “*.extension” in the files = get-childitem… line.

If you are going to run this as a job/task you will need to run the powershell executable and pass the script as an argument using the expected powershell syntax, something like this

C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -command "& 'c:\scripts\purgefolderitems.ps1'"

Happy Easter :op

Using Nagios NRPE To Monitor Windows User Accounts Via WMI…….

Wednesday, February 8th, 2012

My last post on the subject of using the Nagios NRPE plugin to monitor stuff on Windows. This time I want to be monitor some Window domain user accounts for lockout status.

We run some of our windows services using ordinary domain user accounts instead of the built in local service accounts. This is normally when the service in question needs to read or write to network shares on another server, the built in service accounts don’t seem to pass and username/password along with the request and so the connection fails. When you run the process under a domain account, the name and password are passed along with the connection request and as long as you have set your share and NFS permissions correctly it should work.

We recently had an application stop working and it turned out to be that the domain user account that the service ran under had become locked out.

So I decided it would be a good idea to get a heads up about this sort of thing sooner rather than later. The script needs to run on your AD domain controllers (x1 is probably fine as they all replicate user data, but more might allow detection a little quicker).

The code for the script is below.

' account name supplied as argument
strAccount = Wscript.Arguments.Item(0)

' bind to the MERCURY domain
Set objComputer = GetObject("WinNT://MYDOMAIN")

objComputer.Filter = Array("User")
' for each service compare it’s display name to the current one we are looking for
For each objUser in objComputer
    If objUser.Name = strAccount then
    	If ObjUser.IsAccountLocked <> 0 then
    		Wscript.echo "Account is locked out"
    		Wscript.Quit (2)
    	Else
    		Wscript.echo "Account is ok"
    		Wscript.Quit (0)
    	End if
    End if
Next

The script is using WMI to check the IsAccountLocked value of a user object. The user object has quite a lot of key pair values that you can monitor, basically all the fields and check boxes you see in the AD user dialogue box.

In this instance, I am only interested in the ‘Account is locked out’ check box. If it’s checked the value will be something other than 0 (1 in this case)and I want an alert, but if the value is still 0 then it’s not checked and the account is ok.

As with the prior checks I wrote about, the .vbs script file needs to be dropped into the ‘libexec’ folder, and a line like below needs to be added to the nrpe.cfg config file on the windows server.

command[check_windows_account]=cscript.exe //T:30 //NoLogo "C:\Program Files (x86)\NRPE_NT\libexec\check_windows_account.vbs" "$ARG1$"

On the Nagios server you need to add a command definition to the commands.cfg file.

# 'check_windows_account' command definition (using nrpe)
define command{
        command_name    check_windows_account
        command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -t 60 -p 5666 -c check_windows_account -a $ARG1$
}

And finally a service check has to be created in the services.cfg file and a server to be checked needs to be added (in this example I’m checking the account ‘AppUser’ on the server Windows_Server_1.

define service{
        service_description     Check Windows User Account
        servicegroups           cust-windows
        host_name               windows_server_1
        check_command           check_windows_account!"AppUser"
        use                     generic-service
}

Hopefully these scripts have given you an idea of what you can do with the NRPE plugin. As long as you can write a script to check a known value of something, you can get Nagios to use it as a monitor and fire an alert. And it doesn’t have to be VBScript, Powershell, Perl, Python they all can be used. You can monitor WMI objects, or Windows Perfmon Counters, the list is vast.

Enjoy ;oD

Using Nagios NRPE To Monitor Windows Processes Via WMI…….

Tuesday, February 7th, 2012

Hot on the heels (well ok, Oct last year to be precise) of Using Nagios NRPE To Monitor Windows Services Via WMI comes Using Nagios NRPE To Monitor Windows Processes Via WMI.

Naturally, after providing work with a Nagios check to tell us when a named Windows service was not in a running state, the next question from their mouths was going to be


“can Nagios tell us when a program that is not a service has stopped running ?”

Well yes it can, and it’s not difficult. Instead of looking at the list of services, we need to read the list of processes running (like the list you can see in Task Manager) and look to see if our one is included in the list.

Task Manager Process List

The code to do this is below.

strComputer = "."
'list services to monitor, comma seperated, inside quotes
strProcess = Wscript.Arguments.Item(0)
'connect using standard monkier
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
'search for our process
Set colProcesses = objWMIService.ExecQuery ("Select * from Win32_Process Where Name = '" & strProcess & "'")
If colProcesses.Count > 0 Then
'If the process is running return exit code 0 = ok
	Wscript.Echo "SERVICE STATUS: OK"
	Wscript.Quit(0)
Else
	'otherwise return non 0 = error = fire alert hopefully
	Wscript.Echo "SERVICE STATUS: Critical"
	Wscript.Quit(2)
End If

Again, the walk through of this is quite simple. We call the program with x1 parameter/argument, a string containing the name of the process we are looking for (NOTE: this needs to be the full name including the ‘.exe’ or ‘.com’ and if it contains space characters the whole thing should be enclosed in quote marks).

We then bind to WMI and run a query to find our process in the list of running processes. The last part simply counts how many results were returned. If the count is larger than 0, the process must be running and we return a status code 0 for success, if not, we return a status code of 2 and Nagios fires a critical alert (if you prefer a warning rather than a critical then adjust to return a 1)

Note: The string search is not case sensitive, ‘OUTLOOK.EXE’ and ‘outlook.exe’ equate the same regardless of how the process actually looks in the list.

As with the previous check, the .vbs script file needs to be dropped into the ‘libexec’ folder, and a line like below needs to be added to the nrpe.cfg config file on the windows server.

command[check_windows_process]=cscript.exe //T:30 //NoLogo "C:\Program Files (x86)\NRPE_NT\libexec\check_windows_process.vbs" "$ARG1$"

On the Nagios server you need to add a command definition to the commands.cfg file.

# 'check_windows_process' command definition (using nrpe)
define command{
        command_name    check_windows_process
        command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -t 60 -p 5666 -c check_windows_process -a $ARG1$
}

And finally a service check has to be created in the services.cfg file and a server to be checked needs to be added (in this example I’m checking for ‘outlook.exe’ on the server Windows_Server_1.

define service{
        service_description     Check Windows Process
        servicegroups           cust-windows
        host_name               windows_server_1
        check_command           check_windows_service!"outlook.exe"
        use                     generic-service
}

The current script simply alerts if a process is found to be missing from the task list, but it could be modified. You could have it fire a warning if the number of processes is more than 5 but less than 10, and a critical is the number drops below 5 for example.

Could not load file or assembly ‘Microsoft.Office.Interop.Word

Saturday, February 4th, 2012

Someone at work wrote a .NET add-in for MS Word 2007 but when the test user tried to install it he got the following output in a dialogue window.


Could not load file or assembly 'Microsoft.Office.Interop.Word, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or one of its dependencies. The system cannot find the file specified.

************** Exception Text **************
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Office.Interop.Word, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or one of its dependencies. The system cannot find the file specified.
File name: 'Microsoft.Office.Interop.Word, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'
   at Microsoft.VisualStudio.Tools.Office.Word.Internal.IWordHostItemProviderProxy..ctor(IHostItemProviderExtendedContract hostItemProvider)
   at Microsoft.VisualStudio.Tools.Office.Word.Internal.IWordHostItemProviderProxy.GetProxy(IHostItemProviderExtendedContract contract)
   at Microsoft.VisualStudio.Tools.Office.Word.Internal.LocalWordServiceProvider.GetService(Type serviceType)
   at Microsoft.VisualStudio.Tools.Applications.Internal.LocalServiceProvider.System.IServiceProvider.GetService(Type serviceType)
   at Microsoft.VisualStudio.Tools.Office.EntryPointComponentBase.Microsoft.VisualStudio.Tools.Applications.Runtime.IEntryPoint.Initialize(IServiceProvider hostContext)
   at Microsoft.VisualStudio.Tools.Applications.AddInAdapter.ExecutePhase(ExecutionPhases executionPhases)
   at Microsoft.VisualStudio.Tools.Office.Internal.OfficeAddInAdapter.InitializeEntryPointsHelper()

************** Loaded Assemblies **************
mscorlib
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.3625 (GDR.050727-3600)
    CodeBase: file:///C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Office.Runtime.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Office.Runtime.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Office.Runtime.v9.0.dll
----------------------------------------
System
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.3624 (GDR.050727-3600)
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Core
    Assembly Version: 3.5.0.0
    Win32 Version: 3.5.30729.1 built by: SP
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Core/3.5.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.AddIn
    Assembly Version: 3.5.0.0
    Win32 Version: 3.5.30729.1 built by: SP
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.AddIn/3.5.0.0__b77a5c561934e089/System.AddIn.dll
----------------------------------------
System.AddIn.Contract
    Assembly Version: 2.0.0.0
    Win32 Version: 3.5.30729.1 built by: SP
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.AddIn.Contract/2.0.0.0__b03f5f7f11d50a3a/System.AddIn.Contract.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Applications.Hosting.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Applications.Hosting.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Applications.Hosting.v9.0.dll
----------------------------------------
System.Xml
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.3082 (QFE.050727-3000)
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Deployment
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.3053 (netfxsp.050727-3000)
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Deployment/2.0.0.0__b03f5f7f11d50a3a/System.Deployment.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Applications.Runtime.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Applications.Runtime.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Applications.Runtime.v9.0.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Applications.ServerDocument.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Applications.ServerDocument.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Applications.ServerDocument.v9.0.dll
----------------------------------------
System.Windows.Forms
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.3623 (GDR.050727-3600)
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.3053 (netfxsp.050727-3000)
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Office.Contract.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Office.Contract.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Office.Contract.v9.0.dll
----------------------------------------
Microsoft.Office.Tools.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.Office.Tools.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.Office.Tools.v9.0.dll
----------------------------------------
TemplateDragDrop
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/Documents%20and%20Settings/ian.rees/Local%20Settings/Apps/2.0/4VOQMJE5.Z0K/VN2BE36X.AMJ/temp..vsto_cf3a11357a4f8903_0001.0000_a8fd7b1b77cdebc4/TemplateDragDrop.DLL
----------------------------------------
Microsoft.VisualStudio.Tools.Office.Word.AddInAdapter.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Office.Word.AddInAdapter.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Office.Word.AddInAdapter.v9.0.dll
----------------------------------------
Microsoft.Office.Tools.Common.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.Office.Tools.Common.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.Office.Tools.Common.v9.0.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Office.AddInAdapter.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Office.AddInAdapter.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Office.AddInAdapter.v9.0.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Applications.AddInAdapter.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Applications.AddInAdapter.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Applications.AddInAdapter.v9.0.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Applications.Contract.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Applications.Contract.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Applications.Contract.v9.0.dll
----------------------------------------
Anonymously Hosted DynamicMethods Assembly
    Assembly Version: 0.0.0.0
    Win32 Version: 2.0.50727.3625 (GDR.050727-3600)
    CodeBase: file:///C:/WINDOWS/assembly/GAC_32/mscorlib/2.0.0.0__b77a5c561934e089/mscorlib.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Office.Word.HostAdapter.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Office.Word.HostAdapter.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Office.Word.HostAdapter.v9.0.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Office.HostAdapter.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Office.HostAdapter.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Office.HostAdapter.v9.0.dll
----------------------------------------
Microsoft.VisualStudio.Tools.Office.Word.AddInProxy.v9.0
    Assembly Version: 9.0.0.0
    Win32 Version: 9.0.30729.1
    CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualStudio.Tools.Office.Word.AddInProxy.v9.0/9.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Tools.Office.Word.AddInProxy.v9.0.dll
----------------------------------------

A few people examined the msg and the determined (kind of correctly) that a file must be missing. They then attempted repairing MS Office, and dragging various files to various locations.

By the time it got to me, a lot of options had been exhausted. Here’s a tip for this sort of thing:

If you are going to run .NET inside MS office, you will need to have the .NET Programmability Support installed for the application in question.

The screen shot below shows the option for Word, but there are also separate options for Excel and PowerPoint etc. etc.

This sort of thing also holds true under Linux systems when compiling applications instead of using pre-prepared packages. If you are trying to compile Apache with SSL and it’s failing at the SSL step, do have have SSL and it’s libraries installed ? Using pre-prepared packages deals with any missing dependencies (normally) so you don’t have to think about this stuff.

Windows Error “The application failed to initialize properly (0xc0000135)” Solved…….

Tuesday, October 11th, 2011

Thought I would add my own personal

“The application failed to initialize properly (0xc0000135). Click on OK to terminate the application”

story to the masses out there, seeing as mine was not what it seemed to be at first glance.

I guess it started as it did for many, something broke on a server. In my case it was some SQL DB dumps. I logged onto the server and tried to launch the SQL management console and got the following error. I then tried to run the mmc console on it’s own and got the same error.

I did a quick Google search and most posts seemed to be the .net framework either missing a file or not being installed at all. I figured it was as good a place as any to start, so I tried to repair or remove and reinstall the .net framework on the machine. But attempts failed and resulted in the same error msg popping up. I assumed from this the the installer app relied on .net (chicken and egg scenario ?) and thought a little more about the problem. I wondered if I could determine which file was missing or damaged and attempt to replace it directly.

In times of broken apps I tend to turn to SysInternals for salvation. In this case it was procmon to the rescue (Mark Russinovich, what a genius). I launched the app on the affected server desktop.

I then added a filter to only include stuff that was being caused by ‘mmc.exe’

The I launched ‘mmc.exe’ from the Windows ‘Run’ on the start menu.

The initial output was as below. Highlighted were some lines that caught my eye due to their result column not being ‘SUCCESS’.

I performed the same process on a working system so I had a frame of reference for what a working output looked like. The first few failures seemed normal even on a working system. But this entry was unique to the broken system.

It seemed to be complaining about a file, ‘COMCTL32.DLL’. Oddly, the file did exist in the Windows ‘system32′ folder. But the entry was complaining about a very specific location, in the WinSxS folder. Navigating to this folder did indeed show the file to be strangely absent.

Reading up a little on the WinSxS folder, it allows different versions of the same DLL library to exist on the machine at the same time without getting in the way of each other (read Windows DLL Hell).

The folder in question implied I wanted version 5.82.3790.3959. I wasn’t quite sure where this exact version of the file could be obtained from, but I figured I would start with the original install media and work up from there. I got lucky first time. I extracted the file to a temporary location, and then copied it into the WinSxS folder.

I then attempted to relaunch the mmc console and presto, problem solved.

Any time you have an odd problem it’s worth initially running procmon and seeing what’s happening a little under the hood. You should also be aware of the other tools and how they can help you too.

Using Nagios NRPE To Monitor Windows Services Via WMI Part 2…….

Friday, September 30th, 2011

Have realised my first attempt at using NRPE to monitor Windows services via WMI is in fact badly thought out and badly done. This is what happens when companies want everything yesterday and rush things :o(

Having thought about it, the following has come to mind:

The service string to check should not be hard coded into the script. Otherwise we would need x1 script per service to check (i.e. lots !). The service string should be a variable that we can pass to the script as an argument at run time.

And, we can only check one service at a time with this script. Therefore, placing the service name into an array is whaaaayyy overkill. Will simply replace the array with a single string variable.

This in mind, here’s the revised version of the check script

strComputer = "."
'list services to monitor, comma seperated, inside quotes
strService = Wscript.Arguments.Item(0)
'connect using standard monkier
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
'get an array containing all services
Set objItems = objWMIService.ExecQuery ("Select * from Win32_Service")
'for each service compare it’s display name to the current one we are looking for
For each objService in ObjItems
	'if we get a service display name match
	If objService.DisplayName = strService Then
		'display the current service along with it’s current state
		'wscript.echo "service name = " & objService.DisplayName & " currently :: " & objService.State
		If objService.State = "Running" Then
		'If the service is running return exit code 0 = ok
			Wscript.Echo "SERVICE STATUS: OK"
			Wscript.Quit(0)
		Else
		'otherwise return non 0 = error = fire alert hopefully
			Wscript.Echo "SERVICE STATUS: Critical"
			Wscript.Quit(2)
		End if
	End if
Next

And the command to add to the nrpe.cfg file will now need a parameter adding to the end like so (note the quote marks “” around the $ARG1$ parameter. This is in case our variable has spaces in it !!).

command[check_windows_service]=cscript.exe //T:30 //NoLogo "C:\Program Files (x86)\NRPE_NT\libexec\check_windows_service.vbs" "$ARG1$"

The command.cfg file will need a command definition in it like this

# 'check_windows_service' command definition (using NRPE)
define command{
	command_name	check_windows_service
	command_line	$USER1$/check_nrpe -H $HOSTADDRESS$ -t 60 -p 5666 -c check_windows_service -a $ARG1$
}

And finally, in services.cfg, a service check section using the command, like this

define service{
        service_description     Check Windows Awesome Service
        servicegroups           cust-windows
        host_name               windows_server_1
        check_command           check_windows_service!"Some Windows Service"
        use                     generic-service
}

But we can now use the same script to check other services like this

define service{
        service_description     Check Windows Awesome Service
        servicegroups           cust-windows
        host_name               windows_server_1
        check_command           check_windows_service!"Some Windows Service"
        use                     generic-service
}

define service{
        service_description     Check Windows Spooler Service
        servicegroups           cust-windows
        host_name               windows_server_1
        check_command           check_windows_service!"Print Spooler"
        use                     generic-service
}

Second time’s a charm. At least I got to go back and correct my horrible (but technically working) mistake !

Next stop, monitoring for running processes by their executable name in the process list…….

doh !

Using Nagios NRPE To Monitor Windows Services Via WMI…….

Wednesday, September 28th, 2011

If you are setting up Nagios from scratch, install the NSClient++ agent on your Windows servers and get the increased flexibility that it offers. My predecessor at my current work place has only installed the NRPE addon (the same guy who installed the core datacentre router with a duplex mismatch….that made my first week fun), which means I can’t use much of the cool check_nt stuff to monitor services and processes :o(

I needed a way to tell if a service had stopped on Windows server, but I could only use NRPE. First stop, a script to check the status of a given service.


strComputer = "."
'list services to monitor, comma seperated, inside quotes
arrServices = Array("Awesome Service")
For each strService in arrServices
	'connect using standard monkier
	Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
	'get an array containing all services
	Set objItems = objWMIService.ExecQuery ("Select * from Win32_Service")
	'for each service compare it’s display name to the current one we are looking for
	For each objService in ObjItems
		'if we get a service display name match
		If objService.DisplayName = strService Then
			'display the current service along with it’s current state
			'wscript.echo "service name = " & objService.DisplayName & " currently :: " & objService.State
			If objService.State = "Running" Then
			'If the service is running say so
				Wscript.Echo "SERVICE running"
			Else
			'otherwise it must not be runing
				Wscript.Echo "SERVICE not running"
			End if
		End if
	Next
Next

This script binds to WMI, searches for a service called Awesome Service and then echoes a statement to say if it’s running or not. Perfect, but Nagios can’t use this quite yet. We need the script to send some data back to the NRPE engine for this to work.

The Nagios plug-in dev guide tells you most of what you need to know, in this case we need to pass return codes back, which is covered here.

So the finished version now looks like this


strComputer = "."
'list services to monitor, comma seperated, inside quotes
arrServices = Array("Awesome Service")
For each strService in arrServices
	'connect using standard monkier
	Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
	'get an array containing all services
	Set objItems = objWMIService.ExecQuery ("Select * from Win32_Service")
	'for each service compare it’s display name to the current one we are looking for
	For each objService in ObjItems
		'if we get a service display name match
		If objService.DisplayName = strService Then
			'display the current service along with it’s current state
			'wscript.echo "service name = " & objService.DisplayName & " currently :: " & objService.State
			If objService.State = "Running" Then
			'If the service is running return exit code 0 = ok
				Wscript.Echo "SERVICE STATUS: OK"
				Wscript.Quit(0)
			Else
			'otherwise return non 0 = error = fire alert hopefully
				Wscript.Echo "SERVICE STATUS: Critical"
				Wscript.Quit(2)
			End if
		End if
	Next
Next

So if the service is running, we exit with return code 0 Wscript.Quit(0). But if it’s not, we exit with a non 0 return code. I need an alert to fire an SMS, so I have used Wscript.Quit(2) for critical, but if you only want a warning you can use Wscript.Quit(1).

Save the file in the NRPE scripts location (mine are located at C:\Program Files\NRPE_NT\libexec\

Final piece of the puzzle is to add the actual command to run the script to the NRPE config file. Mine is located at ‘C:\Program Files\NRPE_NT\bin\nrpe.cfg’, but your may vary.

At the end of the file are a list of demo commands, we just need to add in


command[check_awesome_service]=cscript.exe //T:30 //NoLogo "C:\Program Files\NRPE_NT\libexec\check_awesome_service.vbs"

Now add a command definition to the Nagios commands.cfg


# 'check_awesome_service' command definition (using nrpe)
define command{
        command_name    check_galaxy_service
        command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -t 60 -p 5666 -c check_awesome_service
        }

And finally in my Nagios services.cfg file an service definition that includes the command and the hosts to run this against


define service{
        host_name               windows_server_1
        service_description     Windows Awesome Service
        servicegroups           cust-windows
        check_command           check_awesome_service
        use                     generic-service
}

And that should be it. You need to restart Nagios to include the new commands and service definitions. And then test the monitor by stopping and the starting the service in question.

The next step would be to replace the service name in the .vbs script file with a variable. Then you can reuse the same script to monitor different services by passing the service name from Nagios to NRPE as a variable from the config file. :oD

Making Passwords for An Easier Life…….

Friday, September 16th, 2011

Hot on the heals of Companies Make VPN Easy For Yourselves……. comes another gem from the school of ‘kinda obvious if you think about it’ !

If you use the UK pound ‘£’ symbol in any passwords, at some point it will bite you in the ass when you are on an American keyboard (especially laptop keyboards).

With so many other non alphanumeric characters to choose from that are accepted in both UK and USA regions (ampersand, asterisk, exclamation mark, percent sign, carat) why run the risk of being unable to logon when not sat of your default location/system (this come from being unable to SU all bloody weekend on some Linux systems owing to my laptop be of the crappy USA keyboard variety….and yes I know about character map and such, but I couldn’t be bothered)

So from now on, I will never use pound ‘£’ or hash ‘#’ in my passwords just to be on the safe side (I guess some among you would consider this a security enhancement…….I suspect you are the same people who think obfuscation through DNS is also a security measure !)

DOH !

Powershell Create DNS Sub Domain…….

Friday, August 5th, 2011

I’ve been working on some Software as Service systems for the last few weeks. They offer a basic fixed configuration of our applications for a smaller price, but are not as customisable as a dedicated full application system.

Being of a fixed configuration means of course that admin process for creating instances was just ripe for scripting and automating. As the system was running on Windows server 2008R2, I decided to use Powershell as it would enable me to work with DNS, filesystem and IIS.

The first part of the process was to create internal DNS records. The platform requires x3 DNS records creating, x1 A record and x2 CNAME. The A record should be blank so it points to the sub domain itself and thereby assigns it an IP address. The CNAMEs should be ‘live’ and ‘preview’ and should point to te afore mentioned A record (they all come from the same IIS server and use host headers, so only the x1 IP address is needed)

The system main DNS namespace domain being ‘company.com’, each client should have the domain ‘client.company.com’ with the actual records created inside this sub domain. So the order of actions to my mind was

1) Create sub domain
2) Create A record in sub domain
3) Create x2 CNAME records in sub domain that point to the A record

First task, create the sub domain. Powershell command to do this ?

([WMIClass]"\\sandpit\root\MicrosoftDNS:MicrosoftDNS_Zone").CreateZone("subcompany.company.com", 0, $False)

Now previously when I had done this via the DNS admin GUI, the results looked something like this

However, what I got instead was this

While technically correct, a little untidy to look at. The command created the DNS subdomain folder as the same folder level of the parent DNS domain folder, and then created a delegated zone inside the main DNS domain folder (little greyed out bugger !)

Spent a little while trying various things, googling etc. etc. and got no-where. Decided to move and and proceed with the next part, to create actual host records. Again, powershell script for this was

([WMIClass]"\\sandpit\root\MicrosoftDNS:MicrosoftDNS_AType").CreateInstanceFromPropertyData(sandpit, company.com, subcompany.company.com, 1, 3600, 192.168.4.58)

The arguments in parenthesis can be explained here, but what came as a pleasant surprise was thay when I looked in the DNS admin console to check the details of teh A record I had just created, it appeared as shown below

Yup, it seems that the script, much like the admin console, will create any missing/required domain/subdomain folders necessary to hold DNS records that you try to create !

And they say there’s no such thing as a free lunch.

Default Windows 7 Partitioning Brakes WDS Imaging…….Kinda…….

Thursday, December 23rd, 2010

Another little Windows 7 nugget.

While installing Windows 7, I noticed that during the section for setting up the disk, some stuff was going on that I didn’t ask for (didn’t realise it at the time, took some trial and error to figure it out).

When you configure Windows 7 installation, the graphical section for configuring the disk will automatically create a 100MB primary partition for Bit Locker to use at a later stage. No matter what I did, I could not stop the GUI from doing this.

So I pressed on and agreed to the installation with the 100MB partition at the begining of the disk and the rest of the disk as a another primary partition.

Windows installs the *boot* files into the 100MB partition, and everything else into the second larger partition !

As I have mentioned before, I don’t think I am using WDS and imaging as Microsoft intended, but I essentially create a machine exactly how I want it and then sysprep and capture it using imagex. I can then reapply the image to another system of have it on the desktop in approx. 10-15mins all ready for use.

But this dual partition configuration breaks this. I believe to do it this way I would have to perform x2 sets of imagex capture and deploys :o( Not going to happen.

To get around this, I have to prepare the disk partitioning up front. The GUI disk section of the install will not alter the disk if it is already partitioned. I booted using a WINPE boot disk used ‘diskpart.exe /s ‘ and pass the following in a txt file as an argument

select disk 0
clean
create partition primary id=07
select partition 1
format fs=ntfs quick nowait
assign letter=c
active

This causes diskpart to select the first disk, wipe it clean and then create a primary partition using the whole disk, mark it as active and assign it drive letter C:

With the disk prepared in this way, I can now install Windows 7 (skipping over the GUI section of disk partitioning) and the boot files will be on the same partition as the system files. This can then be caught in a single image capture to .wim file which, when I then apply back to machines via WDS they will boot correctly.

Not sure of the implications this has should you then want to use Bitlocker at some later stage. Meh ! I don’t care, I don’t use Bitlocker right now :o)

Hope someone else finds this useful :o)