sp_who_i15

I've seen numerous questions about the inability to use sp_who with iMIS 15 to see who's logged in.  iMIS 15 uses the equivalent of the 10.x SQL security model 3 (only), so there's not a SQL-login-per-user model available, which lent itself so nicely to using sp_who.  The reason for this is the iMIS 15 adoption of the ASP.NET Membership Provider as a single unified authentication store and the need to integrate it throughout iMIS, including the Desktop environment.

The Membership Provider tables have two helpful columns: aspnet_Users.LastActivityDate and aspnet_Membership.LastLoginDate.  Below is a stored procedure that searches the current iMIS database to list logged on users.  Run the script against the master database to create the stored procedure, then invoke it with "sp_who_i15".

This defaults to showing users with activity in the last 10 minutes, but you can pass in an alternate value, such as 30, which shows the users with activity in the last 30 minutes:

 sp_who_i15 30

The concept comes from the GetNumberOfUsersOnline method.  

Please post comments, issues, and suggestions - thanks!

CREATE PROCEDURE [dbo].[sp_who_i15] 
    @minutesBack int = 10
AS
BEGIN

SELECT au.[UserName], na.[LAST_FIRST], am.[Email], au.[LastActivityDate], am.[LastLoginDate], 'Type' =     
    CASE        
        WHEN us.[UserId] is null THEN 'Web User'        
        WHEN us.[IsCasualUser] = 0 THEN 'Full User'        
        WHEN us.[IsCasualUser] = 1 THEN 'Casual User'        
        ELSE 'Undefined'    
    END
FROM [aspnet_Users] au    
    INNER JOIN [aspnet_Membership] am ON au.[UserId] = am.[UserId]    
    INNER JOIN [aspnet_Applications] aa ON am.[ApplicationId] = aa.[ApplicationId]    
    INNER JOIN [UserMain] um ON CONVERT (VARCHAR(50), au.[UserId]) = UPPER(um.[ProviderKey])    
    FULL OUTER JOIN [Users] us ON au.[UserName] = us.[UserId]    
    INNER JOIN [Name] na ON na.[ID] = um.[ContactMaster]
WHERE ((au.[LastActivityDate] >= DATEADD (minute, -@minutesBack, GETDATE())    
    OR am.[LastLoginDate] >= DATEADD (minute, -@minutesBack, GETDATE())))    
    AND aa.[ApplicationName] = 'iMIS'
ORDER BY na.[LAST_FIRST]

END 
GO

USE master
GO

sp_MS_marksystemobject 'sp_who_i15' 
GO


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

How to attribute blocking?

One of the main reasons I use sp_who is to identify the source of blocking chains.  (E.G. spid 74 is blocking spid 92, which is blocking a dozen other users)  This is often vital information when diagnosing problems: knowing which user is causing the problem permits narrowing the problem down to a certain module, report or action.

Is there a way to associate a running spid with the user for whom it is executing? I know the SQL connections are pooled, so a solo user may use any or all spids in turn, but is there enough of a trail to spot who is using it right now?

--
Bruce Wilson
Director, Technical Services
RSM McGladrey, Inc.

I don't think you can map ASP.NET users to SPIDs...

...the SQL connections are pooled, as you note, and there's nothing available in the membership service to  indicate which connection is in use.  Looking at the last SQL in Activity Monitor may be the best available resource, limited though it is.  I did some looking around, and found this article:

http://www.4guysfromrolla.com/articles/041608-1.aspx

...which offers an approach to logging activity per user.  However, it's application level, and not SQL Server level, and requires additional code.  The article says:  "Unfortunately, the Membership system does not include any methods for returning a list of users that are logged in; nor does it provide any information as to what the currently logged in users are doing."

But if anyone does have an answer to this question, please post it.

 

create script updated...

...to mark the stored proc as system.  It was returning an error, "...[aspnet_Users] is not found", when created in the master db as originally posted; the db context wasn't switching to the current db as expected.