Monitor whether a user is logged on or not
Hi,
As part of a Distributed Application I need to monitor whether a specific user is logged on a specific server or not.
Domain\AppUser is logged on AppServer -> OK
Domain\AppUser is NOT logged on AppServer -> Alert
How can this be done?
Please advice.
Best regards,BeachMan
December 9th, 2010 1:55pm
Hi,
There is a lot of things to say regarding logging of logins and the ACS feature of Ops Mgr. To display it in a dist app it needs to be a instance of a class. So you might need to create a new custom class for that.
The to see if the user is logged on there is two ways, at least, one is to look at event when the user logon = healthy and another event when the user loggs of that switch the monitor to unhealthy. The other way is to run a script or a WMI query to query
if the user is logged on to the machine or not.Anders Bengtsson | Microsoft PFE | blog at http://www.contoso.se
Free Windows Admin Tool Kit Click here and download it now
December 9th, 2010 2:21pm
Hi,
We are not using ACSBeachMan
December 9th, 2010 2:25pm
We have a script to see wheter a user is logged or not and on which computer he/she is logged on. Below you see the script, which you can add to SCOM to a rule or something. A requirement is that the homedir is filled in the AD properties of the user account
'__________________________________________________________________
'Script Function: Check which computer a user is logged into
'Script Version: v1.0
'Author: Joren Dirkse
'Date: 09-06-2008
'Date changed: 12-06-2008
'
'Usage: query_user.vbs /User:username
'__________________________________________________________________
Option Explicit
'On Error Resume Next
'Declare global variables and constants
'------------------------------------------------------------------
Dim objConnection
Dim objCommand
Dim objRecordSet
Dim objWMIService
Dim objItem
Dim objComp
Dim strBase
Dim strUser
Dim strHomeDir
Dim strFileSvr
Dim strSession
Dim strSessionUsr
Dim strSessionComp
Dim strCompName
Dim intHomeDir
Dim intCompare
Dim arrHomeDir
Dim arrSession
Dim colNamedArguments
Dim colItemsFileSvr
Dim colItemsComp
Dim strPcnaam
strBase = "LDAP://dc=domain,dc=name" ' Basepath to query for user accounts
Set colNamedArguments = WScript.Arguments.Named
strUser = colNamedArguments.Item("User")
' strUser = "test" ' for testing purposes
Const ADS_SCOPE_SUBTREE = 2 'Recursive descent
'------------------------------------------------------------------
'Check if commandline argument for user (strUser) is given
If strUser = "" Then
WScript.Echo "Syntax: query_user.vbs /User:<username>"
Quit
End If
' Connect to Active Directory
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 20000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
' Query Active Directory for homeDirectory Property
' of the specified user (strUser)
objCommand.CommandText = _
"SELECT homeDirectory FROM '" & strBase & "' WHERE objectCategory='user' " & _
"AND sAMAccountName='" & strUser & "'"
' Execute query and create record Set
Set objRecordSet = objCommand.Execute
' Check to see if the query returned anything
If objRecordSet.EOF And objRecordSet.BOF Then
strPcnaam = "User does not exist in the AD"
WScript.StdOut.Write strPcnaam
Quit
WScript.Quit
End If
'Get the name of the fileserver (strFileSvr) from the homeDirectory
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
strHomeDir = objRecordSet.Fields("homeDirectory").Value ' Write query output to String
If len(strHomeDir) > 0 Then
intHomeDir = Len(strHomeDir) - 2
strHomeDir = Right(strHomeDir,intHomeDir) ' Remove the first \\ from the String
arrHomeDir = Split(strHomeDir,"\") ' Split string to array using \ as delimiter
strFileSvr = arrHomeDir(0) ' The fileserver name is the first item in the Array
Else
strPcnaam = "User is not traceable, homedir is not filled in the AD"
WScript.StdOut.Write strPcnaam
Quit
WScript.Quit
End If
objRecordSet.MoveNext
Loop
' Connect to Fileserver using WMI
Set objWMIService = GetObject("winmgmts:\\" & strFileSvr & "\root\cimv2")
If Err.Number <> "0" Then
strPcnaam = "Fileserver is not accessible"
WScript.StdOut.Write strPcnaam
Err.Clear
Quit
WScript.Quit
End If
' Query all sessions on Fileserver
Set colItemsFileSvr = objWMIService.ExecQuery("SELECT * FROM Win32_SessionConnection")
' Check if the user has a session to the fileserver
strPcnaam = ""
For Each objItem In colItemsFileSvr
strSession = objItem.Dependent ' Usersession
arrSession = Split(strSession,"""") ' Split session into array for easy extraction
' of computer and username using " as delimiter
strSessionComp = arrSession(1) ' 2nd item in array is the IP address of the connecting computer
strSessionUsr = arrSession(5) ' 6th item in array is the authenticating user
intCompare = StrComp(strUser,strSessionUsr,vbTextCompare) ' Do a textcompare so that character case is ignored
If intCompare = 0 Then ' If 0, the user shown in the session and the given user are the same
'Convert from IP to hostname
Set objWMIService = GetObject("winmgmts:\\" & strSessionComp & "\root\cimv2")
Set colItemsComp = objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystem")
For Each objComp In colItemsComp
strCompName = objComp.Name
Next
'Check to see if the computer you want to add is already in the String
If InStr(strPcnaam, strCompName) = 0 Then
If strPcnaam = "" Then
strPcnaam = strCompName
Else
strPcnaam = strPcnaam & ", " & strCompName
End If
End If
End If
Next
Quit
If strPcnaam = "" Then
strPcnaam = " * * * User is not logged on to a system * * * "
End If
WScript.StdOut.Write strPcnaam
Sub Quit() ' Destroy global objects and quit
On Error Resume Next
Set colItems = Nothing
Set objWMIService = Nothing
Set objRecordSet = Nothing
Set objCommand = Nothing
Set objConnection = Nothing
End Sub
Certifications: MCSA 2003|MCSE 2003|MCTS(4*)| MCTIP:SA
Free Windows Admin Tool Kit Click here and download it now
December 9th, 2010 4:33pm
Thank's shadowman123!
Is it possible for you to provide me with som more info about how you use it, and how you created the rule running this script?
Brgds,BeachMan
December 10th, 2010 6:15am
Thank's shadowman123!
Is it possible for you to provide me with som more info about how you use it, and how you created the rule running this script?
Brgds,BeachMan
Free Windows Admin Tool Kit Click here and download it now
December 10th, 2010 6:15am
Hi Anders,
Is this the way to do it..? :-)
http://contoso.se/blog/?p=1980
Is it possible for you to be more spesific on how to do this: "target the monitor to a new customer class. The health model of the class will then be only this monitor, in other words the class instance health it will only
show the status of the account."
Kind regards,
BeachMan
December 16th, 2010 4:19pm
Hi, you need to create a new class in the authoring console. There are a number of examples at
http://www.authormps.com/dnn/Tutorials/tabid/101/Default.aspx for example the one named "Discover a single application based on the existence of a directory". It will show you
how to create a new class in the authoring console.Anders Bengtsson | Microsoft PFE | blog at http://www.contoso.se
Free Windows Admin Tool Kit Click here and download it now
December 19th, 2010 4:16am
Hi, you need to create a new class in the authoring console. There are a number of examples at
http://www.authormps.com/dnn/Tutorials/tabid/101/Default.aspx for example the one named "Discover a single application based on the existence of a directory". It will show you
how to create a new class in the authoring console.Anders Bengtsson | Microsoft PFE | blog at http://www.contoso.se
December 19th, 2010 4:16am
Hi,
I can't get this to work properly. I have created Timed Script Tow State Monitor which targets a group which is containing my testserver.
Unhealthy: Property[@Name='Status'] Does not equal OK
Healthy: Property[@Name='Status'] Does not equal OK
v - Generate alerts for this monitor
v - Automatically resolve the alert when the monitor returns to a healthy state
Schedule run every 2 min
I receive an alert when the user is not logged on, but I also receive an alert when the user IS logged on... Where have I gone wrong??
This is the Script:
Option Explicit
Dim objWMIService, objComputer, colComputer, strComputer, strTargetAccount, strAccount, oArgs, oAPI, oBag
strTargetAccount = "DOMAIN\user"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colComputer = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colComputer
IF objComputer.UserName = strTargetAccount Then
StrAccount = 1
End If
Next
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oBag = oAPI.CreatePropertyBag()
IF strAccount = 1 THEN
Call oBag.AddValue("Status","OK")
ELSE
Call oBag.AddValue("Status","BAD")
END IF
Call oAPI.Return(oBag)
BeachMan
Free Windows Admin Tool Kit Click here and download it now
December 21st, 2010 8:57pm
Hi,
I can't get this to work properly. I have created Timed Script Tow State Monitor which targets a group which is containing my testserver.
Unhealthy: Property[@Name='Status'] Does not equal OK
Healthy: Property[@Name='Status'] Does not equal OK
v - Generate alerts for this monitor
v - Automatically resolve the alert when the monitor returns to a healthy state
Schedule run every 2 min
I receive an alert when the user is not logged on, but I also receive an alert when the user IS logged on... Where have I gone wrong??
This is the Script:
Option Explicit
Dim objWMIService, objComputer, colComputer, strComputer, strTargetAccount, strAccount, oArgs, oAPI, oBag
strTargetAccount = "DOMAIN\user"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colComputer = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colComputer
IF objComputer.UserName = strTargetAccount Then
StrAccount = 1
End If
Next
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oBag = oAPI.CreatePropertyBag()
IF strAccount = 1 THEN
Call oBag.AddValue("Status","OK")
ELSE
Call oBag.AddValue("Status","BAD")
END IF
Call oAPI.Return(oBag)
BeachMan
December 21st, 2010 8:57pm
I have also tried to use another script, it fails with the following warning:
The process started at 15:08:59 failed to create System.PropertyBagData. Errors found in output:
C:\Program Files\System Center Operations Manager 2007\Health Service State\Monitoring Host Temporary Files 30\8448\CheckForLoggedOnUsers.vbs(7, 1) Microsoft VBScript runtime error: Subscript out of range
Command executed: "C:\Windows\system32\cscript.exe" /nologo "CheckForLoggedOnUsers.vbs"
Working Directory: C:\Program Files\System Center Operations Manager 2007\Health Service State\Monitoring Host Temporary Files 30\8448\
One or more workflows were affected by this.
Workflow name: UIGeneratedMonitorbc5eb78fa1f94dffbd3c4dcb75c51483
Instance name: TestGroup
Instance ID: {92DB929E-D6B0-A283-7E49-5BD6DA770E73}
Management group: Test-MG
***** Script*******
'Parameters
'----------
'1st parameter: Semicolon-separated list of users for which to search. Ex: "compuglobalhypermeganet\administrator;compuglobalhypermeganet\guest"
'Option Explicit
Dim aUsers, oArgs
Set oArgs = WScript.Arguments
aUsers = Split(oArgs(0), "DOMAIN\user;")
Call Main
Sub Main
Dim oAPI, oBag, oWMI, oItem, oColItems, oNetwork, sUser, sDomain, sUserToCheck, IsGood
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oBag = oAPI.CreateTypedPropertyBag(StateDataType)
Set oWMI = CreateObject("Scripting.FileSystemObject")
Set oNetwork = CreateObject("Wscript.Network" )
If oArgs.Count < 1 Then
Call oAPI.LogScriptEvent("CheckForLoggedOnUsers.vbs", 500, 0, "Script aborted. Not enough parameters provided.")
WScript.Quit -1
End If
Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
Set oColItems = oWMI.ExecQuery("Select * from Win32_LoggedOnUser",,48)
IsGood = True
For Each oItem in oColItems
sDomain = oItem.Antecedent
sDomain = Mid(sDomain, InStr(sDomain, "Domain=""") + 8)
sDomain = Left(sDomain, InStr(sDomain, """") - 1)
'WScript.Echo sDomain
sUser = oItem.Antecedent
sUser = Mid(sUser, InStr(sUser, "Name=""") + 6)
sUser = Left(sUser, InStr(sUser, """") - 1)
'WScript.Echo sUser
sUser = sDomain & "\" & sUser
'Wscript.Echo "UserName: " & sUser & " is logged in at this computer"
For Each sUserToCheck In aUsers
If LCase(sUserToCheck) = LCase(sUser) Then
IsGood = False
Exit For
End If
Next
If IsGood = False Then
Exit For
End If
Next
Set oItem = Nothing: Set oColItems = Nothing: Set oWMI = Nothing
If IsGood = True Then
Call oBag.AddValue("State","GOOD")
Else
Call oBag.AddValue("State","BAD")
End If
Call oAPI.Return(oBag)
End Sub
BeachMan
Free Windows Admin Tool Kit Click here and download it now
December 21st, 2010 9:24pm
I have also tried to use another script, it fails with the following warning:
The process started at 15:08:59 failed to create System.PropertyBagData. Errors found in output:
C:\Program Files\System Center Operations Manager 2007\Health Service State\Monitoring Host Temporary Files 30\8448\CheckForLoggedOnUsers.vbs(7, 1) Microsoft VBScript runtime error: Subscript out of range
Command executed: "C:\Windows\system32\cscript.exe" /nologo "CheckForLoggedOnUsers.vbs"
Working Directory: C:\Program Files\System Center Operations Manager 2007\Health Service State\Monitoring Host Temporary Files 30\8448\
One or more workflows were affected by this.
Workflow name: UIGeneratedMonitorbc5eb78fa1f94dffbd3c4dcb75c51483
Instance name: TestGroup
Instance ID: {92DB929E-D6B0-A283-7E49-5BD6DA770E73}
Management group: Test-MG
***** Script*******
'Parameters
'----------
'1st parameter: Semicolon-separated list of users for which to search. Ex: "compuglobalhypermeganet\administrator;compuglobalhypermeganet\guest"
'Option Explicit
Dim aUsers, oArgs
Set oArgs = WScript.Arguments
aUsers = Split(oArgs(0), "DOMAIN\user;")
Call Main
Sub Main
Dim oAPI, oBag, oWMI, oItem, oColItems, oNetwork, sUser, sDomain, sUserToCheck, IsGood
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oBag = oAPI.CreateTypedPropertyBag(StateDataType)
Set oWMI = CreateObject("Scripting.FileSystemObject")
Set oNetwork = CreateObject("Wscript.Network" )
If oArgs.Count < 1 Then
Call oAPI.LogScriptEvent("CheckForLoggedOnUsers.vbs", 500, 0, "Script aborted. Not enough parameters provided.")
WScript.Quit -1
End If
Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
Set oColItems = oWMI.ExecQuery("Select * from Win32_LoggedOnUser",,48)
IsGood = True
For Each oItem in oColItems
sDomain = oItem.Antecedent
sDomain = Mid(sDomain, InStr(sDomain, "Domain=""") + 8)
sDomain = Left(sDomain, InStr(sDomain, """") - 1)
'WScript.Echo sDomain
sUser = oItem.Antecedent
sUser = Mid(sUser, InStr(sUser, "Name=""") + 6)
sUser = Left(sUser, InStr(sUser, """") - 1)
'WScript.Echo sUser
sUser = sDomain & "\" & sUser
'Wscript.Echo "UserName: " & sUser & " is logged in at this computer"
For Each sUserToCheck In aUsers
If LCase(sUserToCheck) = LCase(sUser) Then
IsGood = False
Exit For
End If
Next
If IsGood = False Then
Exit For
End If
Next
Set oItem = Nothing: Set oColItems = Nothing: Set oWMI = Nothing
If IsGood = True Then
Call oBag.AddValue("State","GOOD")
Else
Call oBag.AddValue("State","BAD")
End If
Call oAPI.Return(oBag)
End Sub
BeachMan
December 21st, 2010 9:24pm
Couple of comments.
To model a specific user, you need to write a custom management pack that discovers when each user is logged into your app. Your app will have to provide the correct instrumentation to support knowing when the user logs into your application (not logs
into their workstation, which is why you cannot use the windows login event for this).
This requires you write a discovery that querys the app asking for which users are currently logged into the application (users can log into anything they want to from a computer perspective - you can prevent them from logging into specific computers with
the standard windows rights management featurs). This is probably the better approach if your goal is to prevent them from being logged into windows on a given set of computers - simply deny the group of users or individual users, login-locally rights
and you won't have to monitor what computer they log in.
If you have more than a few hundred users, this is not advised - since managing too many entities or polling the app too quickly to see the instantaneous list of users via the SCOM console is going to be a performance trade off. Every CPU cycle that
SCOM uses to do this denies those CPU cycles to the work that the application is designed to do.
Your script errors are simply that - errors in the program. Subscript out of range means your script logic is faulty. If you aren't a programmer, you need to get one to help you. Similarly, writing a custom management pack for this job
is pretty complex logic, and will require several scripts to work in tandem, as well as some pretty gnarly XML (SCOM expertise required).Microsoft Corporation
Free Windows Admin Tool Kit Click here and download it now
December 21st, 2010 9:50pm
Couple of comments.
To model a specific user, you need to write a custom management pack that discovers when each user is logged into your app. Your app will have to provide the correct instrumentation to support knowing when the user logs into your application (not logs
into their workstation, which is why you cannot use the windows login event for this).
This requires you write a discovery that querys the app asking for which users are currently logged into the application (users can log into anything they want to from a computer perspective - you can prevent them from logging into specific computers with
the standard windows rights management featurs). This is probably the better approach if your goal is to prevent them from being logged into windows on a given set of computers - simply deny the group of users or individual users, login-locally rights
and you won't have to monitor what computer they log in.
If you have more than a few hundred users, this is not advised - since managing too many entities or polling the app too quickly to see the instantaneous list of users via the SCOM console is going to be a performance trade off. Every CPU cycle that
SCOM uses to do this denies those CPU cycles to the work that the application is designed to do.
Your script errors are simply that - errors in the program. Subscript out of range means your script logic is faulty. If you aren't a programmer, you need to get one to help you. Similarly, writing a custom management pack for this job
is pretty complex logic, and will require several scripts to work in tandem, as well as some pretty gnarly XML (SCOM expertise required).Microsoft Corporation
December 21st, 2010 9:50pm
Hi Dan,
Thank's for the reply.
I don’t think that this should be so complicated. At least I hope so.. :-)
We are talking about one user that must be logged on to 4 different servers, ie not an application just on to the OS. We need to monitor this because it is a LOB application where a particular domain\user(for some reason), must be logged on to all the four
servers that are part of the LOB application for it to work properly.
So we need an alert if this domain\user is not logged on to one or more of these servers.
Brgds,BeachMan
Free Windows Admin Tool Kit Click here and download it now
December 21st, 2010 9:50pm
Hi Dan,
Thank's for the reply.
I don’t think that this should be so complicated. At least I hope so.. :-)
We are talking about one user that must be logged on to 4 different servers, ie not an application just on to the OS. We need to monitor this because it is a LOB application where a particular domain\user(for some reason), must be logged on to all the four
servers that are part of the LOB application for it to work properly.
So we need an alert if this domain\user is not logged on to one or more of these servers.
Brgds,BeachMan
December 21st, 2010 9:50pm
Hi BeachMan!
Have you solved this?
It's not an uncommon scenario (although not a very clever way of doing things :).
You need to create an MP.
For your LOB App role (which runs on those four servers) you need to create a ClassType (for instance, derived from Microsoft.Windows.ComputerRole).
For the LOB app, does it have any bits installed on the four servers?
Registry entries etc?
If so, you can use these to discover instances of the LOB ClassType you have created.
It would also be great if you
had a registry key containing the Username needed to be logged on for the app.
Then you can add a Property, to your ClassType, and populate that property with the Username.
Now, targeted at the LOB app ClassType, you can create a monitor which run a WMI script, querying Win32_LoggedOnUser
I'm no expert on the return from "SELECT Antecedent FROM Win32_LoggedOnUser but if it's sufficient to find the name of your logged on user in the returned data, it should not be too complicated to
create the script for the monitor.
/Roger
This posting is provided "AS IS" with no warranties, and confers no rights.
Free Windows Admin Tool Kit Click here and download it now
April 14th, 2011 5:34am