none
Need to expire out all cached domain logon credentials over 30 days old RRS feed

  • Question

  • We need a script to prevent anyone from logging into offline XP laptops using cached
    credentials if the laptops have not connected with our domain controllers for more than 30 days.

    I have thought of having a VB script run as a scheduled task that checks the modified 
    date of something that always gets updated whenever there is a domain connection and if the age is over 30 days old, it logs any user out and changes the value of 
    HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Current Version\Winlogon\ CachedLogonsCount
    to a value of 0.
    That would prevent anyone from logging in with cached domain user credentials from that point on. 

    We would then have a Group Policy that changes the CachedLogonsCount
    value back to a value of 1 and updates the modified date of the file the script checks when the machine is next connected to the domain.

    We would also like to have a warning message pop up on the screen every day 
    starting 2 days before the registry value is changed.

    Can this be done with vbscript?

    Can you think of another method that will disable XP laptops
    if they don't connect with our domain on a set schedule?

    Wednesday, March 24, 2010 5:56 PM

Answers

  • Hey

    So here is an initial script for you to test out. Worked for me in my vmware lab. I set the "threshold" variable to 60 seconds just for testing purposes and the warning to 40 seconds. In production you would apply the logon script to all users, change the warning variable to 28 (days), the threshold variable to 30 (days) and set the DateDiff statement to:

    If DateDiff("d", lastCachedLogon, currentDateTime) >= warning Then

    As for forcing your users to bring their laptops...You can lead a horse to water but you can't make it drink...In my experience it's hard enough to get users to read messages without getting them to actually obey what they've read...so good luck with that part! As the user's don't have administrative privellages it makes it problematic to enforce as they won't have permissions at logon to change registry keys in HKLM to stop RDP access for example or disable the network interfaces (forcing them to bring the laptop in). Hopefully though this should help you out with the logic of atleast informing them.

    Cheers Matt :)

    '---------------------------------------------------------------------------------
    'Script Name : CheckLogonType.vbs
    'Author      : Matthew Beattie
    'Created     : 27/03/10
    'Description : This script determines if the user has logged on using cached 
    '            : credentials and writes the date time to the users registry profile 
    '            : if the registry key doesn't exist. If it does exist it compares the 
    '            : previous date time to the current date time. If the difference 
    '            : between the dates is greater than or equal to 30 days the user
    '            : will be prompted to bring their laptop into work and logon to the domain.
    '---------------------------------------------------------------------------------
    'Initialization  Section   
    '---------------------------------------------------------------------------------
    Option Explicit  
    Dim objFSO, wshShell, wshNetwork, logonServer, domainName, scriptBaseName
    On Error Resume Next
       Set objFSO     = CreateObject("Scripting.FileSystemObject")  
       Set wshShell   = CreateObject("Wscript.Shell")
       Set WshNetwork = WScript.CreateObject("WScript.Network")
       scriptBaseName = objFSO.GetBaseName(Wscript.ScriptFullName)
       logonServer    = Replace(wshShell.ExpandEnvironmentStrings("%logonserver%"), "\\", "")
       domainName     = wshNetwork.UserDomain
       If Err.Number <> 0 Then
          Wscript.Quit
       End If
    On Error Goto 0
    '---------------------------------------------------------------------------------
    'Main Processing Section   
    '---------------------------------------------------------------------------------
    On Error Resume Next
       ProcessScript
       If Err.Number <> 0 Then  
          Wscript.Quit
       End If
    On Error Goto 0
    '---------------------------------------------------------------------------------
    'Functions Processing Section
    '---------------------------------------------------------------------------------
    'Name       : ProcessScript -> Primary Function that controls all other script processing.   
    'Parameters : None          ->   
    'Return     : None          ->   
    '---------------------------------------------------------------------------------
    Function ProcessScript
       Dim lastCachedLogon, cachedLogon, currentDateTime
       Dim regKey, threshold, warning, difference
       cachedLogon     = False
       warning         = 40
       threshold       = 60
       regKey          = "HKCU\System\" & domainName & "\" & scriptBaseName & "\CachedLogonDateTime"
       currentDateTime = IsoDateTimeString(Now)
       lastCachedLogon = ReadRegistry(regKey)
       '------------------------------------------------------------------------------
       'Request an ICMP response from the logon server. If a reply is not recieved then it's likely to be a cached logon.
       '------------------------------------------------------------------------------
       If Not CheckConnection(logonServer) Then
          cachedLogon = True
       End If
       '------------------------------------------------------------------------------
       'Ensure the registry values are updated and user is prompted if their cached credentials have expired.
       '------------------------------------------------------------------------------
       On Error Resume Next
          If cachedLogon Then
             '------------------------------------------------------------------------
             'If the Registry key is a valid date then ensure the user is prompted 
             '------------------------------------------------------------------------
             If IsDate(lastCachedLogon) Then
                difference = DateDiff("s", lastCachedLogon, currentDateTime)
                If difference >= warning Then
                   If difference >= threshold Then
                      MsgBox "You credentials have expired. Please reconnect your laptop to the " & _
                              domainName & " Domain or contact your systems administrator.", vbCritical, scriptBaseName
                      Exit Function
                   Else
                      MsgBox "Your credentials will expire in " & (threshold - difference) & " seconds. " & _
                             "Please reconnect your laptop to the " & domainName & " domain or " & _
                             "contact your systems administrator.", vbExclamation, scriptBaseName
                      Exit Function
                   End If
                Else
                   MsgBox "Have fun with your cached credentials", vbInformation, scriptBaseName
                End If
             End If
             '------------------------------------------------------------------------
             'Write the "CachedLogonDateTime" Registry key as the user has logged on with cached credentials.
             '------------------------------------------------------------------------
             If lastCachedLogon = "" Then
                wshShell.RegWrite regKey, currentDateTime, "REG_SZ"
                If Err.Number <> 0 Then
                   Exit Function
                End If
             End If
          Else
             '------------------------------------------------------------------------
             'Remove the "CachedLogonDateTime" Registry key as the user has logged onto the domain again.
             '------------------------------------------------------------------------
             wshShell.RegDelete regKey
             If Err.Number <> 0 Then
                Exit Function
             End If
          End If
       On Error Goto 0
    End Function
    '---------------------------------------------------------------------------------
    'Name       : CheckConnection -> Checks a remote host using WMI ping.
    'Parameters : hostName        -> Hostname of computer system to verify network connectivity with.
    'Return     : Boolean         -> True if hostname replies. False otherwise.
    '---------------------------------------------------------------------------------
    Function CheckConnection(hostName)
       Dim ping, response, replied
       Set ping = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
                           ("select * from Win32_PingStatus where address = '" & hostName & "'")
       For each response in ping
          replied = Not IsNull(response.StatusCode) And response.StatusCode = 0
       Next
       CheckConnection = replied
    End Function
    '---------------------------------------------------------------------------------
    'Name       : ReadRegistry -> Read the value of a registry key or value.
    'Parameters : key          -> Name of the key (ending in "\") or value to read.
    'Return     : ReadRegistry -> Value of key or value read from the local registry (blank is not found).
    '---------------------------------------------------------------------------------
    Function ReadRegistry(ByVal key)
       Dim result
       If StrComp (Left (key, 4), "HKU\", vbTextCompare) = 0 Then
          Key = "HKEY_USERS" & Mid (key, 4)
       End If
       On Error Resume Next
          ReadRegistry = WshShell.RegRead (key)
          If Err.Number <> 0 Then
             ReadRegistry = ""
          End If
       On Error Goto 0
    End Function
    '---------------------------------------------------------------------------------
    'Name       : IsoDateTimeString -> Generate an ISO date and time string from a date/time value.
    'Parameters : dateValue         -> Input date/time value.
    'Return     : IsoDateTimeString -> Date and time parts of the input value in "yyyy-mm-dd hh:mm:ss" format.
    '---------------------------------------------------------------------------------
    Function IsoDateTimeString(dateValue)
       IsoDateTimeString = IsoDateString (dateValue) & " " & IsoTimeString (dateValue)
    End Function
    '---------------------------------------------------------------------------------
    'Name       : IsoDateString -> Generate an ISO date string from a date/time value.
    'Parameters : dateValue     -> Input date/time value.
    'Return     : IsoDateString -> Date part of the input value in "yyyy-mm-dd" format.
    '---------------------------------------------------------------------------------
    Function IsoDateString(dateValue)
       If IsDate(dateValue) Then
          IsoDateString = Right ("000" &  Year (dateValue), 4) & "-" & _
                          Right (  "0" & Month (dateValue), 2) & "-" & _
                          Right (  "0" &   Day (dateValue), 2)
       Else
          IsoDateString = "0000-00-00"
       End If
    End Function
    '---------------------------------------------------------------------------------
    'Name       : IsoTimeString -> Generate an ISO time string from a date/time value.
    'Parameters : dateValue     -> Input date/time value.
    'Return     : IsoTimeString -> Time part of the input value in "hh:mm:ss" format.
    '---------------------------------------------------------------------------------
    Function IsoTimeString(dateValue)
       If IsDate(dateValue) Then
          IsoTimeString = Right ("0" &   Hour (dateValue), 2) & ":" & _
                          Right ("0" & Minute (dateValue), 2) & ":" & _
                          Right ("0" & Second (dateValue), 2)
       Else
          IsoTimeString = "00:00:00"
       End If
    End Function
    '---------------------------------------------------------------------------------
    Saturday, March 27, 2010 2:44 AM
    Moderator
  • My apologies in my earlier post; I did not really read your query through its entirety so I came up with a lousy answer. =)

    You can use SubInACL.exe (from the Support Tools, iirc) to grant normal users rights on specific registry keys. Alternatively, you can make use of the RegSetKeySecurity function (say, through a VB app) to modify the permissions on a specific registry key.

    Hat's off to Matt for that helluva script he came up with, btw. =)

    Regards,

    Salvador Manaois III
    MCSE MCSA MCTS MCITP C|EH CIWA
    ----------------------------------------------------------------------------
    Bytes & Badz: http://badzmanaois.blogspot.com
    My Passion: http://www.flickr.com/photos/badzmanaois
    My Scripting Blog: http://sgwindowsgroup.org/blogs/badz

    Monday, March 29, 2010 1:57 PM
    Moderator

All replies

  • Why not disable the inactive accounts instead when the 30 days threshold (too short?) is reached? Here's a script from the ScriptCenter which does this (only that the threshold in the example is 60 days to disable, 90 days to delete the computer object in AD):

    http://gallery.technet.microsoft.com/ScriptCenter/en-us/bdb2a16c-5f02-44c3-8c6f-bc0f0f41f56f

    Regards,

    Salvador Manaois III
    MCSE MCSA MCTS MCITP C|EH CIWA
    ----------------------------------------------------------------------------
    Bytes & Badz: http://badzmanaois.blogspot.com
    My Passion: http://www.flickr.com/photos/badzmanaois
    My Scripting Blog: http://sgwindowsgroup.org/blogs/badz

    Friday, March 26, 2010 5:29 AM
    Moderator
  • It doesn't sound like you understood the problem.  The laptops are offline and using cached credentials.

    What we want to is limit how long cached credentials work the laptops, so the users must connect the laptops to our domain at least once per month. 

    The users use remote desktop to connect to other computers on the domain, so their user accounts are not inactive.  We need to enforce our requirement that the users physically bring the laptops to our LAN every month for software updates that cannot be done remotely.

    Friday, March 26, 2010 5:56 AM
  • Hi

    Okay so this is just an idea for you to see what you think before i invest time scripting something up...Perhaps you could implement a logon script which expands the local enironment variable string for "logon server" (the resulting value of typing "set l" for "%logonserver%" at the command prompt when logged onto to domain) and test the value (hostname) for an ICMP response. If the DC doesn't respond then it is most likely user has logged on with cached credentials so you could then write a value (current date time) to the user's registry profile. Something similar to this maybe?

    http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/14aba23e-cf9d-4a00-a568-30f6c301ae93/#4f3e9170-4a28-4114-ba92-267a8bdb617f

    (Minus the function to enumerate the workgroup and the "ScriptBaseName" variable as within the registry key to write to)

    EG HKCU\System\Scripts\CheckCachedCredentials\LastLogon

    You could compare the date of the last logon using cached credentials using the "DateDiff" function to the current date and if it's greater than 28 days then prompt a message asking the user to bring the laptop into the office. If the user logs onto the domain and the DC responds to ICMP then reset the "lastlogon" value to nothing. The issue with enabling this regkey:

    HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

    is that the user will NOT have permissions to write this value at logon but (unless they have administrative privellages...hopefully not!)

    So perhaps an alternative would be to use this instead?

    http://support.microsoft.com/kb/242536/

    HKCU\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon\ReportDC

    Let me know if you think the idea could work for you and I'll see what I can script up.

    Cheers Matt :)

    Friday, March 26, 2010 7:23 AM
    Moderator
  • Hi

    Okay so this is just an idea for you to see what you think before i invest time scripting something up...Perhaps you could implement a logon script which expands the local enironment variable string for "logon server" (the resulting value of typing "set l" for "%logonserver%" at the command prompt when logged onto to domain) and test the value (hostname) for an ICMP response. If the DC doesn't respond then it is most likely user has logged on with cached credentials so you could then write a value (current date time) to the user's registry profile. Something similar to this maybe?

    http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/14aba23e-cf9d-4a00-a568-30f6c301ae93/#4f3e9170-4a28-4114-ba92-267a8bdb617f

    (Minus the function to enumerate the workgroup and the "ScriptBaseName" variable as within the registry key to write to)

    EG HKCU\System\Scripts\CheckCachedCredentials\LastLogon

    You could compare the date of the last logon using cached credentials using the "DateDiff" function to the current date and if it's greater than 28 days then prompt a message asking the user to bring the laptop into the office. If the user logs onto the domain and the DC responds to ICMP then reset the "lastlogon" value to nothing. The issue with enabling this regkey:

    HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

    is that the user will NOT have permissions to write this value at logon but (unless they have administrative privellages...hopefully not!)

    So perhaps an alternative would be to use this instead?

    http://support.microsoft.com/kb/242536/

    HKCU\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon\ReportDC

    Let me know if you think the idea could work for you and I'll see what I can script up.

    Cheers Matt :)

    Friday, March 26, 2010 7:23 AM
    Moderator
  • Most of the remote users have limited rights, so we would need a method that doesn't require them to have administrator privileges.  So, I'd like to try your suggested method.  Maybe we can try testing it with it set to 30 minutes with a 10 minute warning instead of 30 days with a 2 day warning at first so we can test it without needing to wait a month to verify that it works. 

    Friday, March 26, 2010 2:09 PM
  • Hey

    So here is an initial script for you to test out. Worked for me in my vmware lab. I set the "threshold" variable to 60 seconds just for testing purposes and the warning to 40 seconds. In production you would apply the logon script to all users, change the warning variable to 28 (days), the threshold variable to 30 (days) and set the DateDiff statement to:

    If DateDiff("d", lastCachedLogon, currentDateTime) >= warning Then

    As for forcing your users to bring their laptops...You can lead a horse to water but you can't make it drink...In my experience it's hard enough to get users to read messages without getting them to actually obey what they've read...so good luck with that part! As the user's don't have administrative privellages it makes it problematic to enforce as they won't have permissions at logon to change registry keys in HKLM to stop RDP access for example or disable the network interfaces (forcing them to bring the laptop in). Hopefully though this should help you out with the logic of atleast informing them.

    Cheers Matt :)

    '---------------------------------------------------------------------------------
    'Script Name : CheckLogonType.vbs
    'Author      : Matthew Beattie
    'Created     : 27/03/10
    'Description : This script determines if the user has logged on using cached 
    '            : credentials and writes the date time to the users registry profile 
    '            : if the registry key doesn't exist. If it does exist it compares the 
    '            : previous date time to the current date time. If the difference 
    '            : between the dates is greater than or equal to 30 days the user
    '            : will be prompted to bring their laptop into work and logon to the domain.
    '---------------------------------------------------------------------------------
    'Initialization  Section   
    '---------------------------------------------------------------------------------
    Option Explicit  
    Dim objFSO, wshShell, wshNetwork, logonServer, domainName, scriptBaseName
    On Error Resume Next
       Set objFSO     = CreateObject("Scripting.FileSystemObject")  
       Set wshShell   = CreateObject("Wscript.Shell")
       Set WshNetwork = WScript.CreateObject("WScript.Network")
       scriptBaseName = objFSO.GetBaseName(Wscript.ScriptFullName)
       logonServer    = Replace(wshShell.ExpandEnvironmentStrings("%logonserver%"), "\\", "")
       domainName     = wshNetwork.UserDomain
       If Err.Number <> 0 Then
          Wscript.Quit
       End If
    On Error Goto 0
    '---------------------------------------------------------------------------------
    'Main Processing Section   
    '---------------------------------------------------------------------------------
    On Error Resume Next
       ProcessScript
       If Err.Number <> 0 Then  
          Wscript.Quit
       End If
    On Error Goto 0
    '---------------------------------------------------------------------------------
    'Functions Processing Section
    '---------------------------------------------------------------------------------
    'Name       : ProcessScript -> Primary Function that controls all other script processing.   
    'Parameters : None          ->   
    'Return     : None          ->   
    '---------------------------------------------------------------------------------
    Function ProcessScript
       Dim lastCachedLogon, cachedLogon, currentDateTime
       Dim regKey, threshold, warning, difference
       cachedLogon     = False
       warning         = 40
       threshold       = 60
       regKey          = "HKCU\System\" & domainName & "\" & scriptBaseName & "\CachedLogonDateTime"
       currentDateTime = IsoDateTimeString(Now)
       lastCachedLogon = ReadRegistry(regKey)
       '------------------------------------------------------------------------------
       'Request an ICMP response from the logon server. If a reply is not recieved then it's likely to be a cached logon.
       '------------------------------------------------------------------------------
       If Not CheckConnection(logonServer) Then
          cachedLogon = True
       End If
       '------------------------------------------------------------------------------
       'Ensure the registry values are updated and user is prompted if their cached credentials have expired.
       '------------------------------------------------------------------------------
       On Error Resume Next
          If cachedLogon Then
             '------------------------------------------------------------------------
             'If the Registry key is a valid date then ensure the user is prompted 
             '------------------------------------------------------------------------
             If IsDate(lastCachedLogon) Then
                difference = DateDiff("s", lastCachedLogon, currentDateTime)
                If difference >= warning Then
                   If difference >= threshold Then
                      MsgBox "You credentials have expired. Please reconnect your laptop to the " & _
                              domainName & " Domain or contact your systems administrator.", vbCritical, scriptBaseName
                      Exit Function
                   Else
                      MsgBox "Your credentials will expire in " & (threshold - difference) & " seconds. " & _
                             "Please reconnect your laptop to the " & domainName & " domain or " & _
                             "contact your systems administrator.", vbExclamation, scriptBaseName
                      Exit Function
                   End If
                Else
                   MsgBox "Have fun with your cached credentials", vbInformation, scriptBaseName
                End If
             End If
             '------------------------------------------------------------------------
             'Write the "CachedLogonDateTime" Registry key as the user has logged on with cached credentials.
             '------------------------------------------------------------------------
             If lastCachedLogon = "" Then
                wshShell.RegWrite regKey, currentDateTime, "REG_SZ"
                If Err.Number <> 0 Then
                   Exit Function
                End If
             End If
          Else
             '------------------------------------------------------------------------
             'Remove the "CachedLogonDateTime" Registry key as the user has logged onto the domain again.
             '------------------------------------------------------------------------
             wshShell.RegDelete regKey
             If Err.Number <> 0 Then
                Exit Function
             End If
          End If
       On Error Goto 0
    End Function
    '---------------------------------------------------------------------------------
    'Name       : CheckConnection -> Checks a remote host using WMI ping.
    'Parameters : hostName        -> Hostname of computer system to verify network connectivity with.
    'Return     : Boolean         -> True if hostname replies. False otherwise.
    '---------------------------------------------------------------------------------
    Function CheckConnection(hostName)
       Dim ping, response, replied
       Set ping = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
                           ("select * from Win32_PingStatus where address = '" & hostName & "'")
       For each response in ping
          replied = Not IsNull(response.StatusCode) And response.StatusCode = 0
       Next
       CheckConnection = replied
    End Function
    '---------------------------------------------------------------------------------
    'Name       : ReadRegistry -> Read the value of a registry key or value.
    'Parameters : key          -> Name of the key (ending in "\") or value to read.
    'Return     : ReadRegistry -> Value of key or value read from the local registry (blank is not found).
    '---------------------------------------------------------------------------------
    Function ReadRegistry(ByVal key)
       Dim result
       If StrComp (Left (key, 4), "HKU\", vbTextCompare) = 0 Then
          Key = "HKEY_USERS" & Mid (key, 4)
       End If
       On Error Resume Next
          ReadRegistry = WshShell.RegRead (key)
          If Err.Number <> 0 Then
             ReadRegistry = ""
          End If
       On Error Goto 0
    End Function
    '---------------------------------------------------------------------------------
    'Name       : IsoDateTimeString -> Generate an ISO date and time string from a date/time value.
    'Parameters : dateValue         -> Input date/time value.
    'Return     : IsoDateTimeString -> Date and time parts of the input value in "yyyy-mm-dd hh:mm:ss" format.
    '---------------------------------------------------------------------------------
    Function IsoDateTimeString(dateValue)
       IsoDateTimeString = IsoDateString (dateValue) & " " & IsoTimeString (dateValue)
    End Function
    '---------------------------------------------------------------------------------
    'Name       : IsoDateString -> Generate an ISO date string from a date/time value.
    'Parameters : dateValue     -> Input date/time value.
    'Return     : IsoDateString -> Date part of the input value in "yyyy-mm-dd" format.
    '---------------------------------------------------------------------------------
    Function IsoDateString(dateValue)
       If IsDate(dateValue) Then
          IsoDateString = Right ("000" &  Year (dateValue), 4) & "-" & _
                          Right (  "0" & Month (dateValue), 2) & "-" & _
                          Right (  "0" &   Day (dateValue), 2)
       Else
          IsoDateString = "0000-00-00"
       End If
    End Function
    '---------------------------------------------------------------------------------
    'Name       : IsoTimeString -> Generate an ISO time string from a date/time value.
    'Parameters : dateValue     -> Input date/time value.
    'Return     : IsoTimeString -> Time part of the input value in "hh:mm:ss" format.
    '---------------------------------------------------------------------------------
    Function IsoTimeString(dateValue)
       If IsDate(dateValue) Then
          IsoTimeString = Right ("0" &   Hour (dateValue), 2) & ":" & _
                          Right ("0" & Minute (dateValue), 2) & ":" & _
                          Right ("0" & Second (dateValue), 2)
       Else
          IsoTimeString = "00:00:00"
       End If
    End Function
    '---------------------------------------------------------------------------------
    Saturday, March 27, 2010 2:44 AM
    Moderator
  • Hey

    So here is an initial script for you to test out. Worked for me in my vmware lab. I set the "threshold" variable to 60 seconds just for testing purposes and the warning to 40 seconds. In production you would apply the logon script to all users, change the warning variable to 28 (days), the threshold variable to 30 (days) and set the DateDiff statement to:

    If DateDiff("d", lastCachedLogon, currentDateTime) >= warning Then

    As for forcing your users to bring their laptops...You can lead a horse to water but you can't make it drink...In my experience it's hard enough to get users to read messages without getting them to actually obey what they've read...so good luck with that part! As the user's don't have administrative privellages it makes it problematic to enforce as they won't have permissions at logon to change registry keys in HKLM to stop RDP access for example or disable the network interfaces (forcing them to bring the laptop in). Hopefully though this should help you out with the logic of atleast informing them.

    Cheers Matt :)

     

    Is there some way to either have a script run under the context of an account that has rights to change keys in HKLM or else give the limited users permissions to change the needed registry key without giving them blanket administrator privileges? Disabling the NIC would not be a good idea because that means it couldn't be automatically undone when the laptops were brought in by a group policy on the domain since it wouldn't have network connectivity to see the policy.
    Monday, March 29, 2010 1:33 PM
  • My apologies in my earlier post; I did not really read your query through its entirety so I came up with a lousy answer. =)

    You can use SubInACL.exe (from the Support Tools, iirc) to grant normal users rights on specific registry keys. Alternatively, you can make use of the RegSetKeySecurity function (say, through a VB app) to modify the permissions on a specific registry key.

    Hat's off to Matt for that helluva script he came up with, btw. =)

    Regards,

    Salvador Manaois III
    MCSE MCSA MCTS MCITP C|EH CIWA
    ----------------------------------------------------------------------------
    Bytes & Badz: http://badzmanaois.blogspot.com
    My Passion: http://www.flickr.com/photos/badzmanaois
    My Scripting Blog: http://sgwindowsgroup.org/blogs/badz

    Monday, March 29, 2010 1:57 PM
    Moderator
  • My apologies in my earlier post; I did not really read your query through its entirety so I came up with a lousy answer. =)

    You can use SubInACL.exe (from the Support Tools, iirc) to grant normal users rights on specific registry keys. Alternatively, you can make use of the RegSetKeySecurity function (say, through a VB app) to modify the permissions on a specific registry key.

    Hat's off to Matt for that helluva script he came up with, btw. =)

    Regards,

    Salvador Manaois III
    MCSE MCSA MCTS MCITP C|EH CIWA
    ----------------------------------------------------------------------------
    Bytes & Badz: http://badzmanaois.blogspot.com
    My Passion: http://www.flickr.com/photos/badzmanaois
    My Scripting Blog: http://sgwindowsgroup.org/blogs/badz

    Since I do want to be able to enforce it, if I go ahead and use the subinacle.exe tool to grant normal users access to HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Current Version\Winlogon\ CachedLogonsCount, how would I add changing that value to 0 and forcibly logging out any logged in user (unlocking locked screen etc.) when the threshold time was met to this script?

    Once they bring the laptop back to the domain, our domain group policy would automatically set the key back to the default.

    Monday, March 29, 2010 8:06 PM
  • Hey

    I guess you could change the permissions on the registry key if you wanted to...or you could just force the user to logoff if the threshold has expired (meaning their credentials have expired). I'd recommend using the wshShell.Popup method you can specify the number of seconds the message will be displayed before the user is forcefully logged off. See the code modifications below...

    Cheers Matt :)

    '---------------------------------------------------------------------------------
    'Initialization  Section   
    '---------------------------------------------------------------------------------
    Option Explicit  
    Dim objFSO, wshShell, wshNetwork, logonServer
    Dim hostName, domainName, scriptBaseName
    On Error Resume Next
       Set objFSO     = CreateObject("Scripting.FileSystemObject")  
       Set wshShell   = CreateObject("Wscript.Shell")
       Set WshNetwork = WScript.CreateObject("WScript.Network")
       scriptBaseName = objFSO.GetBaseName(Wscript.ScriptFullName)
       logonServer    = Replace(wshShell.ExpandEnvironmentStrings("%logonserver%"), "\\", "")
       domainName     = wshNetwork.UserDomain
       hostName       = wshNetwork.ComputerName
       If Err.Number <> 0 Then
          Wscript.Quit
       End If
    On Error Goto 0
    '---------------------------------------------------------------------------------
    'Main Processing Section   
    '---------------------------------------------------------------------------------
    On Error Resume Next
       ProcessScript
       If Err.Number <> 0 Then  
          Wscript.Quit
       End If
    On Error Goto 0
    '---------------------------------------------------------------------------------
    'Functions Processing Section
    '---------------------------------------------------------------------------------
    'Name       : ProcessScript -> Primary Function that controls all other script processing.   
    'Parameters : None          ->   
    'Return     : None          ->   
    '---------------------------------------------------------------------------------
    Function ProcessScript
       Dim lastCachedLogon, cachedLogon, currentDateTime
       Dim regKey, threshold, warning, difference, forcedLogOff
       forcedLogOff    = 4
       cachedLogon     = False
       warning         = 40
       threshold       = 60
       regKey          = "HKCU\System\" & domainName & "\" & scriptBaseName & "\CachedLogonDateTime"
       currentDateTime = IsoDateTimeString(Now)
       lastCachedLogon = ReadRegistry(regKey)
       '------------------------------------------------------------------------------
       'Request an ICMP response from the logon server. If a reply is not recieved then it's likely to be a cached logon.
       '------------------------------------------------------------------------------
       If Not CheckConnection(logonServer) Then
          cachedLogon = True
       End If
       '------------------------------------------------------------------------------
       'Ensure the registry values are updated and user is prompted if their cached credentials have expired.
       '------------------------------------------------------------------------------
       On Error Resume Next
          If cachedLogon Then
             '------------------------------------------------------------------------
             'If the Registry key is a valid date then ensure the user is prompted 
             '------------------------------------------------------------------------
             If IsDate(lastCachedLogon) Then
                difference = DateDiff("s", lastCachedLogon, currentDateTime)
                If difference >= warning Then
                   If difference >= threshold Then
                      wshShell.Popup "You credentials have expired. Please reconnect your laptop to the " & _
                                      domainName & " Domain or contact your systems administrator." & _
                                     "You will be automatically logged off.", 7, scriptBaseName, 48
                     '----------------------------------------------------------------
                     'As the user's credentials have expired force them to logoff.
                     '----------------------------------------------------------------
                      If Not LogOffSystem(hostName, forcedLogOff) Then
                         Exit Function
                      End If
                      Exit Function
                   Else
                      MsgBox "Your credentials will expire in " & (threshold - difference) & " seconds. " & _
                             "Please reconnect your laptop to the " & domainName & " domain or " & _
                             "contact your systems administrator.", vbExclamation, scriptBaseName
                      Exit Function
                   End If
                Else
                   MsgBox "Have fun with your cached credentials", vbInformation, scriptBaseName
                End If
             End If
             '------------------------------------------------------------------------
             'Write the "CachedLogonDateTime" Registry key as the user has logged on with cached credentials.
             '------------------------------------------------------------------------
             If lastCachedLogon = "" Then
                wshShell.RegWrite regKey, currentDateTime, "REG_SZ"
                If Err.Number <> 0 Then
                   Exit Function
                End If
             End If
          Else
             '------------------------------------------------------------------------
             'Remove the "CachedLogonDateTime" Registry key as the user has logged onto the domain again.
             '------------------------------------------------------------------------
             wshShell.RegDelete regKey
             If Err.Number <> 0 Then
                Exit Function
             End If
          End If
       On Error Goto 0
    End Function
    '---------------------------------------------------------------------------------
    'Name       : LogOffSystem -> Initiates a user logoff on a specified system.
    'Parameters : hostName     -> String containing the computer name to log the user off on.
    '           : logOffFlags  -> Integer containing the value used by Win32Shutdown. 4 = Forced logoff, 0 = Logoff.
    'Return     : LogOffSystem -> Returns True if the user was successfully logged off, otherwise returns False.
    '---------------------------------------------------------------------------------
    Function LogOffSystem(hostName, logOffFlags)
       Dim wmi, query, results, result
       LogOffSystem = False
       query = "Select * From Win32_OperatingSystem"
       On Error Resume Next
          Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate,(Shutdown)}!\\" & hostName & "\root\cimv2")
          If Err.Number <> 0 Then
             Exit Function
          End If
          Set results = wmi.ExecQuery(query)
          If Err.Number <> 0 Then
             Exit Function
          End If
          For Each result In results
             result.Win32ShutDown logOffFlags
          Next
          If Err.Number <> 0 Then
             Exit Function
          End If
       On Error Goto 0
       LogOffSystem = True
    End Function
    '---------------------------------------------------------------------------------
    Tuesday, March 30, 2010 2:29 AM
    Moderator
  • I am aware this discusion is a year old now but I have been trawling through the internet to a find a way of solving the exact same problem you guys are looking at and was wondering if the problem was resolved using Matts script.  Like I said I am in a very similar scenario, we have issued hundreds of Laptops out to staff over the last seven years and I'd estimate there are over 250+ laptops we cannot account for on the domain.  It would appear that most of these haven't been seen by the domain since not long after the device was issued.  I also know that a vast amount of these laptops were issued to staff who are no longer working here.

    We are less worried about the device itself rather the potential content that it could contain.  We used SafeBoot back in the day prior to its aquisition by Mcafee and now we use Mcafee Endpoint encryption.  As with Salvador I want to make it so the laptop has to be back on the domain no less than once every 2 months maximum.  If they don't bring it back in I want the users profile trashed or cached credentials removed or something similar.  All our users are standard users with no admin permissions (that I'm aware of or at least should not have officially.  I'm not even concerned if the laptop has to be rebuilt as a result of this.  My old script worked great using the landesk client and would near as damn in format the drive after a set date by booting up into a partition and trashing the boot partition. 

    This may seem a little overkill but as I said this is less about the loss of a laptop and more to do with the risk of what data may be stored on it.  I'm aware that the ones that we haven't seen for years are unlikely ever to be seen again but we are currently recalling them all on mass in order to reconfigure the VPN clients and reissue crypto cards (I know we didnt need them back but it seemed a perfect excuse).  Any help or guidance you can give will be greatly appreciated

    Regards  John

     

     

    Saturday, February 26, 2011 4:16 AM