Solved

Having Issues with Windows - Maintenance Tasks - Remove Old User Profiles Worklet

  • 13 November 2023
  • 6 replies
  • 165 views

Badge

Hello, I am having issues with the worklet mentioned in the title. I have a PC from our environment that I am testing with this worklet. I have changed nothing on the worklet except change the cutoff day to 60 days. I can see under This PC > Windows > Users that there are profiles that show under the “Date Modified” column as not having any changes since April. However, the worklet is not removing those. It runs the first check and says there are no old profiles. I’ll admit I’m still learning Powershell, so maybe I have something confused, but if someone could point me in the right direction of what I need to modify I would appreciate it. Let me know if you’d like more info. TIA! 

icon

Best answer by AnthonyM-Automox 13 November 2023, 15:47

View original

6 replies

Userlevel 1

Good morning @kaitlin.houser !

 

There was a change in default behavior for this Worklet released to production on Friday that should resolve what you’re seeing.

 

Did you by chance create the Worklet policy you’re referring to before then? If yes, you’ll need to delete the policy and recreate it from the Worklet catalog to take advantage of the new version.

 

If you’re curious, here’s the technical breakdown of some basic operational logic in the Worklet, the original behavior and how we tweaked it:

  • To discern the age of a profile, we’re using WMI via `Get-CimInstance` to retrieve profile data from the `Win32_UserProfile` class.
    • Specifically, the `LastUseTime` value returned from the `Win32_UserProfile` class is what we use for date comparison to determine if the profile is older than our provided threshold.
  • In original testing, we found this `LastUseTime` value could sometimes be `$null`, or blank.
    • To avoid blasting away potentially current profiles with an erroneous `LastUseTime`, the default behavior implemented was to assume if this value was `$null` that it should not be removed.
    • Through more testing and Community feedback, it’s been observed that a `LastUseTime` value of `$null` actually looks to indicate the profile has been unused for a vast amount of time ( such as your test case, where the profile hasn’t been used since April ).
  • In light of the last, the default behavior was modified to make the informed assumption that if this value is `$null` → it should indeed be removed.

 

Hope this helps.

 

Anthony M.

 

Userlevel 3
Badge

Just doubling on Anthony’s response so you know where to look to check what version you have

In your Eval block there’s a section to see which version of the worklet you have - you may need to update to the latest from the catalog (We’re also working on a way to make Catalog Managed worklets easier to update!!!!))

 

    .HISTORY
Author : Anthony Maxwell
Date : 08/14/2023
Version : 1.0.0
- Initial Release.

Author : John Guarracino
Date : 11/06/2023
Version : 1.0.2
- Changed default behavior to flag a user profile for remediation where the LastUseTime is $null.
#>

 

Badge

@AnthonyM-Automox  hi Anthony, thank you for the response. I remade the worklet to catch the latest version after your reply. It still did not work for me. Going off of how you replied that the worklet works, I did a little digging. It seems like there is something that is causing these profiles to update as soon as the PC is turned on. I cut off the names for privacy, but I know for a fact that some of these users have not been on this PC for a significant amount of time. I wonder if it’s our security system pinging it? Not sure, but something is updating the lastusetime. Any ideas on what we could change? 

 

 

Userlevel 1

@AnthonyM-Automox  hi Anthony, thank you for the response. I remade the worklet to catch the latest version after your reply. It still did not work for me. Going off of how you replied that the worklet works, I did a little digging. It seems like there is something that is causing these profiles to update as soon as the PC is turned on. I cut off the names for privacy, but I know for a fact that some of these users have not been on this PC for a significant amount of time. I wonder if it’s our security system pinging it? Not sure, but something is updating the lastusetime. Any ideas on what we could change? 

 

 

 

Ahh, I have seen occurrences of this before. Endpoint protection could surely be the culprit but, in short, anything that loads a user’s registry hive and performs at least one query of a key or value resets this date to current.

 

Unfortunately, I don’t know of a solution to this as I’m not aware of any other attributes we can reference to discern profile age ( LastUseTime is about it ).

Badge

@AnthonyM-Automox  I see, that makes sense. Is there a way to modify the worklet to pull the “Date modified” date instead? this is personally what I would use when I was manually removing profiles. (Would of course not include administrator and public accounts)

 

 

Userlevel 1

@AnthonyM-Automox  I see, that makes sense. Is there a way to modify the worklet to pull the “Date modified” date instead? this is personally what I would use when I was manually removing profiles. (Would of course not include administrator and public accounts)

 

 

 

Unfortunately LastWriteTime is as close as we can get to a “true” indication of last login. For example, in the screenshot below is the profile I’m currently logged into displaying a modified date of 11/1 ( and I do shut my PC down at night and fire it up fresh in the AM, so this isn’t even influenced by not rebooting my PC for long periods of time or similar ):

 

Looking further into the various file system attributes, we have these from the .NET DirectoryInfo class ( which is returned from Get-ChildItem ):

  • CreationTime
  • CreationTimeUtc
  • LastAccessTime
  • LastAccessTimeUtc
  • LastWriteTime
  • LastWriteTimeUtc

The unfortunate problem is all these metrics can produce unreliable results ( “unreliable results” meaning relative to our specific use-case in correlating them to the profile owner’s actual “last login” ) through one manner of trickery or another.

 

This is a problem I’ve unfortunately dove quite deep into solving and haven’t been able to identify a solid “one-size-fits-all” solution:

  • We can attempt to go by the Event Viewer’s Security log
    • Events with ID 4624 are generated on user login
    • The problem with this is security events fire so quickly throughout the day that in order to keep enough data to establish your desired “profile age” threshold in log data ( say 30-days ), you’d be holding onto potentially 10’s of gigabytes of log files.
  • We can attempt to evaluate the profile folder’s various timestamps
    • This is outlined just above.
  • We can utilize the timestamp returned in LastUseTime
    • This to-date has been the most consistent identifier I’ve been able to find.

 

The above said, if you’d like something written to remove profiles based upon a specific timestamp or other metric - I’d be happy to help create something unique for your environment. But in the context of the Worklet Catalog offering, until a more concrete attribute can be located LastUseTime is the front-runner.

 

AM

 

Reply