Sloan
Sloan

Reputation: 1

I need help figuring out where my code is getting hung up at

I have been tasked with coming up with a PowerShell script that I can run on computers at my organization to cleanup old user profiles in Windows. The goal of the script is get a list of users on a pc, exclude certain accounts based on their name, then delete them if they haven't been used in over 90 days. I am sure there is a simpler way to delete profiles, but this also removes the registry keys for a profile.


    $User = get-childitem -Path C:\Users -Name
    #Current Date for comparison
    $Cutoff = (Get-Date).AddDays(-90)
    #Cut Public and Administrator accounts from the list
    $Userlist = @()
    foreach ($User in $Users) {
        if ($User -in "Public", "Administrator", "administrator", ".Net v4.5", ".Net v4.5 classic", ".Default", "itadmin", "it-admin", "cpsi") {
            # Skip the user if their name is in the exclusion list
            continue
        }
    
        try {
            $Userlist.Add($User)
        }
        catch {
            Write-Host "Could not add the user $User to the Userlist."
        }
    }
    #Gather all Login events in the $events variable
    $Events = Get-WinEvent -FilterHashtable @{ LogName='Security'; Id='4624'; StartTime=(Get-Date).AddDays(-90)}
    $LogList = @{}
    $user -lt ($cutoff) 
    #Loop through the previously gathered list is users
    foreach ($User in $Userlist){
    #Filter the Events for ones performed by the user and store it in $Logins
    $Logins = $Events| Where {$_.Message -like "*$User*" -and $_.Message -like "*@tchospital.local*"}
    #Output line ($Logins | Measure).Count will output the number of times the user login during the currently available security logs
    $LoginCount = ($Logins | Measure).Count
    if($LoginCount -eq 0){
    $RemovedUserList =@($RemovedUserList + $User)
    $UserFolder = "C:\Users\$User"
    Get-WmiObject -Class Win32_UserProfile | Where LocalPath -eq $UserFolder | Remove-WmiObject}
    else{
    continue
    }
    }
    $CutOut = Write-Output "Cutoff date is $Cutoff"
    $UserOut = Write-Output "Found users are: $Userlist"
    $Today = Get-Date
    $RunDate= Write-Output "Rundate is: $Today"
    if (!($RemovedUserList)){
    $RemovedUser = Write-Output "No one has been removed"
    }
    else{
    $RemovedUser = Write-Output "$RemovedUserList has been removed"
    }

I am not super familiar with PowerShell, so I think I have everything formatted correctly. But am definitely a beginner when it comes to writing scripts.

This should do the following: Make a list of users under the variable $User Exclude certain profiles from the list look at their login time using event log delete the profiles using get-wmiobject

If anyone can help me out that would be awesome.

Updated Script after taking the feedback#####

''''

# Get a list of user folders in C:\Users
$UserNames = Get-ChildItem -Path C:\Users -Name

# Set the cutoff date to 90 days ago
$Cutoff = (Get-Date).AddDays(-90)

# Initialize user lists
$Userlist = @()
$RemovedUserList = @()

# Loop through each user folder
foreach ($UserName in $UserNames) {
    # List of excluded user names
    $ExcludedUsers = @("Public", "Administrator", "administrator", ".Net v4.5", ".Net v4.5 classic", ".Default", "itadmin", "it-admin", "cpsi")

    # Check if the current user name is in the excluded list
    if ($UserName -in $ExcludedUsers) {
        Write-Host "Excluded user: $UserName"
        continue
    }

    # Add the user to the $Userlist if it's not excluded
    $Userlist += $UserName
}

# Get security events for logins in the last 90 days
$Events = Get-WinEvent -FilterHashtable @{ LogName='Security'; Id='4624'; StartTime=$Cutoff }

# Loop through each user in the $Userlist
foreach ($UserName in $Userlist) {
    $Logins = $Events | Where-Object { $_.Message -like "*$UserName*" -and $_.Message -like "*@tchospital.local*" }
    $LoginCount = ($Logins | Measure-Object).Count

    if ($LoginCount -eq 0) {
        $RemovedUserList += $UserName
        $UserFolder = "C:\Users\$UserName"

        try {
            Get-WmiObject -Class Win32_UserProfile | Where-Object LocalPath -eq $UserFolder | Remove-WmiObject -ErrorAction Stop
            Write-Host "Removed user profile for: $UserName"
        }
        catch {
            Write-Host "Failed to remove user profile for: $UserName"
            Write-Host "Error: $_"
        }
    }
}

# Output the results to files in the root of the C drive
$Cutoff | Out-File -Append -FilePath "C:\cutoff.txt"
$Userlist | Out-File -Append -FilePath "C:\userlist.txt"
$Today = Get-Date
$Today | Out-File -Append -FilePath "C:\runlog.txt"

if ($RemovedUserList.Count -eq 0) {
    "No users were removed" | Out-File -Append -FilePath "C:\runlog.txt"
}
else {
    "Skipped users: $($RemovedUserList -join ', ')" | Out-File -Append -FilePath "C:\runlog.txt"
}

''''

Upvotes: 0

Views: 65

Answers (1)

vipatron
vipatron

Reputation: 176

  1. As Darin said in the comments, you have assigned the results of Get-ChildItem to $User, when you meant $Users.

  2. I tend to use Powershell 5.1 for compatibility, but $Userlist is declared to be an array (which has fixed size) on line 5. For your syntax of $Userlist.Add($User) to work, it would need to be an arrayList. You have two options:

Simplest: Use the += operator. Arrays are immutable in powershell, but for small n, this isn't too bad:

$Userlist = @()
$Userlist += $User

Less simple, but faster:

$Userlist = [System.Collections.ArrayList]::new()
[void] $Userlist.Add($User) # the void cast just hides the output, the index to which the element was added
  1. What are you doing with this line? $user -lt ($cutoff). It's just going to print true or false to the console, and have no effect on flow control.

There's likely more, but I have to go. My script is almost done running. Hopefully that gets you off the ground.

Upvotes: 0

Related Questions