Forum Discussion

ddickinsonBHCET's avatar
ddickinsonBHCET
Copper Contributor
May 21, 2025

User Profile Deletion

Hi,

I just wanted to pick anyone's brains, in case they have also encountered this or would have any idea why this is the case. I am fairly new to Intune and script writing, to clarify.

Basically, we have been working on a Detect and Remediation script that is deployed via Intune (Devices >Ssni Script and Remediations) to Windows 10 (Ent 22H2) and Windows 11 (Ent 24H2) devices. On any fresh enrolled devices, it detects and deletes user profiles completely fine, but fails to even detect profiles on devices that were enrolled a while ago. However, if we run an Autopilot reset on those devices, the script works again. What difference would a freshly built/enrolled device have to an older one, when they also run other scripts fine. 

The script targets profiles that are older than 1 hour as we want to keep on top of removing profiles consistently to keep disk space low, especially on lower spec laptops. It will exclude SYSTEM profiles and also any *Admin* user folders - as that has a separate script to only delete LAPSAdmin on an evening, when the workplace is closed (8pm UK). This LAPSAdmin script worked fine on the older enrolled devices. Some of the profiles on the machines go back to 2023, is the '1 hour' target not effective against that old of a profile - has it become stale?SS

Like I said, I am fairly new to this and have used bits and pieces from different locations to help muster up a script. I thought I had it nailed as it was working on test devices that were just enrolled purely for testing, until I was asked to put it onto another group. 

Intune doesn't say the script fails - indicating there are no errors. However, I am not saying there isn't.

Detect:

Remediate: 

Thanks for your time,

Dean

3 Replies

  • You can try this in detection and check if it detects correctly the profiles.

    $cutoff = (Get-Date).AddMinutes(-60)
    
    Write-Output "`n---- Profile Diagnostic Report ----"
    Write-Output "Cutoff time: $cutoff"
    
    # Get tasklist output once
    $tasklistOutput = tasklist /v
    
    Get-ChildItem "C:\Users" -Directory -ErrorAction SilentlyContinue |
        ForEach-Object {
            $folder = $_
            $folderPath = $folder.FullName
            $ntName = $folder.Name
            $lastWrite = $folder.LastWriteTime
            $idleMinutes = [math]::Round(((Get-Date) - $lastWrite).TotalMinutes)
    
            $profile = Get-CimInstance -Class Win32_UserProfile -ErrorAction SilentlyContinue |
                Where-Object { $_.LocalPath -eq $folderPath }
    
            $status = "Unknown"
            $isSpecial = $false
            $canBeDeleted = $false
    
            if ($profile) {
                $isSpecial = $profile.Special
    
                if (-not $profile.Loaded) {
                    $status = "Unloaded"
                    if (-not $isSpecial -and
                        $ntName -notlike "*Windows*" -and
                        $ntName -notlike "*default*" -and
                        $ntName -notlike "*Public*" -and
                        $ntName -notlike "*Admin*" -and
                        $lastWrite -lt $cutoff) {
                            $canBeDeleted = $true
                    }
                } else {
                    # Loaded profile — check process activity
                    $tasklistName = "$env:COMPUTERNAME\$ntName"
    
                    $hasProcess = $tasklistOutput | Where-Object {
                        $_ -match "\b$([regex]::Escape($tasklistName))\b"
                    }
    
                    $status = $hasProcess ? "Loaded Active" : "Loaded Idle"
                }
            }
    
            [PSCustomObject]@{
                FolderName     = $ntName
                LastWriteTime  = $lastWrite
                IdleMinutes    = $idleMinutes
                Status         = $status
                IsSpecial      = $isSpecial
                Deletable      = $canBeDeleted
                ProfileFound   = [bool]$profile
            }
        } | Sort-Object LastWriteTime | Format-Table -AutoSize

     

    • ddickinsonBHCET's avatar
      ddickinsonBHCET
      Copper Contributor

      Hey, Luca_Scarano_TheItalianWay​ 

      Thanks for your reply. I will get round to testing this. 

      Could you kindly explain what you have changed and why you think it would make a difference when deleting profiles on older enrolled devices. This is also a learning process for me, so would be glad to take any advice or methodology on board.

      • Luca_Scarano_TheItalianWay's avatar
        Luca_Scarano_TheItalianWay
        Iron Contributor

        Hi,

        use it just as a diagnostic. Profiles can result loaded also if they are not, and folders can be accessed also by background process, giving you false information on last activity.

        I would better go with a simple task list.

        In this case I kept Deletable false for loaded idle profiles (without processes). From this script you can already understand if this kind of detection works better for you, and after fix in the general script.

Resources