Important Notice: On February 29th, this community was put into read-only mode. All existing posts will remain but customers are unable to add new posts or comment on existing. Please feel to join our Community Discord for any questions and discussions.

Remove profiles with Power Shell help

I have several hundred computers with local profiles on them. I would like to remove these profiles. However There are some profiles I would like keep. I would prefer to do this remotely as these computers are spread across 5 buildings. Can this be done with Power Shell?

 

Thanks

0

Comments

22 comments
Date Votes
  • Sure can. Couple questions:

     

    Is the profile(s) you want to keep consistent across all the machines? How stale do you want the account to be before the profile is removed?

    0
  • Yes. the profiles I want to spare, I want to spare on all machines. As for staleness, 30 days is good enough for me, but I would like to ability to change it and re-run the PS Script. Obviously if it is set to 30 days and I re-run to at 60 days that wouldn't bring those profiles back. I would most likely it would be fewer days.

    0
  • Alrighty. That's enough to go on. Give me about an hour or so to research/write/test and I'll post back!

    0
  • Thank you so much Stephen.

    0
  • No problem man. I've currently got the logic to pull all accounts in that are 30 days or older from lastlogintime. Working out the logic to translate SID > Username so it's friendly.

     

    This will require a little work on your part I imagine since of course SIDs are unique and only you will know which SIDs you want to keep. 

    Stay tuned!

    0
  • Thanks for the update.

    0
  • Alright, I'm pretty damn close here. Just trying to do a little cleanup and testing before I ship this thing off. 

     

    Once you have the script, pay close attention to the code comments. Instructions will be inside them.

    0
  • Thank you.

    0
  • This is what I have so far. I'm still wresting with a .Remove() method. Supposedly that call should work, but it isn't so I've taken it out so you can execute this code and see what it is doing so far. basically it will look at the machine, and list out all profiles that aren't part of the NT stack, though this is easily modified for others as well:

    $profile = Get-WmiObject -Class win32_userprofile | Select LastUseTime, SID
    $profile.PSBase | Get-Member


    Foreach($p in $profile){

     

    $SID = $p.SID

    $objSID = New-Object System.Security.Principal.SecurityIdentifier($SID)
    $objUser = $objSID.Translate([System.Security.Principal.NTAccount])


    If($objUser.Value -notmatch "NT AUTHORITY" -and $objUser.Value -notmatch "NT SERVICE"){


    Write-Host "Resolved user name:" $objUser.Value


    }

    }

     

     

    Jason Hanks: If you're reading this, if you could shoot this code to Mr. Powell that would be sweet. He may have the method laying around in his head that I can use to do the actual remove. So far my google-fu is failing me.

    This is tested on Powershell v5, so bear that in mind.

     

    0
  • I second the request for the Corgi god to look at the code lol. Thank you so much for this much help Stephen. I cant begin to thank you enough.

    0
  • Corgi god? Hah! I love it.  Side note: corgi's are awesome.

    But! Getting back to the task at hand, I think I may have narrowed down what may be happening.

    I believe the method that you're searching for is .Delete(). It appears as though $profile contains PSCustomObjects. Try dropping the Select-Object portion and then looking at the psbase for the individual objects stored in $profile.

    For example, we'll see the .Delete() method with these two examples (single object and all objects):

    $profile = Get-WmiObject -Class Win32_userprofile
    $profile[0].psbase | Get-Member

    Or

    $profile = Get-WmiObject -Class Win32_userprofile
    $profile | ForEach-Object {$_.psbase | Get-Member}

     

    To illustrate this even further, we could take a look at the type of each of the objects:

    $profile = Get-WmiObject -Class Win32_userprofile | Select LastUseTime, SID
    $profile | Foreach-Object {$_.GetType()}

    You may notice that they are all PSCustomObjects and will not include the proper method that we're looking for. If we drop the Select-Object bit, we'll see a different type for each object:

    $profile2 = Get-WmiObject -Class Win32_userprofile
    $profile2 | Foreach-Object {$_.GetType()}

    I hope that's helpful. Best of luck with the remaining portion of your script!

    Cheers,

     

    0
  • Stupid question time: How did you get your code to format like that? Everytime I put code in here it looks like a steaming pile of corgi poo. Is there a special wrapper I can put around the text, or a certain indent to use?

     

    P.S. Thanks for the insight. I was playing around with the PSBase and Get-Type stuff on my own to figure it out and came up with pretty much the same conclusion. 

    I'm going to have to handle this in such a way that I'm using an object with the .Delete() method available to it.

    0
  • Sadly, since the forum posts use rich text, there's no super easy markdown. :(

     However, it's fairly straightforward to get the effect that I have, you just need to modify the html directly. 

    If you click the html button in the little toolbar, it'll have the html direct edit window.

     

    In that window, I simply wrap my code with <pre></pre> tags.

    Here's my code wrapped with <pre></pre> tags

     

    Voila! No more corgi poo! ;)

    0
  • I bet it's a rights assignment thing, I don't have the HTML button unfortunately. Just Bold, Italic, Underline, Strikethrough, and Bullet/Numbered lists. 

     

    Bummer! Oh well. I'll live with it!

    0
  • I am out for half a day and miss all this. I am going to get caught up and see what results I can get. My PS skills are very very bad but I have to start somewhere.  Thank you both so much for all your help.

    0
  • Jason - did the script work for you?  I have this sme issue across the campus on labs and libraries. THANKS

    0
  • I honestly dont remember David. This past summer we had a whole department turn over and I am the only original one left. I am lucky if I remember what i had for lunch yesterday. I will try and look back at my notes to see what if any luck i did or didn't have.

    0
  • Let me know too. I totally forgot that I wrote this little tidbit. I can lend a hand if needed.

    0
  • Totally understand and thanks for the response.  Trying to make the delprof2 work per PDQ recommendations.  Thanks again and good luck

     

    0
  • I used this script with modifications for my environment

    https://gallery.technet.microsoft.com/scriptcenter/Delete-user-profiles-over-05348eef

    0
  • Here, I forgot I discovered this tidbit. I looked at a package I created for auto-login of lab machines. The package I created to revert the changes deletes the profile of the account we use to autologin with.

    Here's that code:

     

    Get-CimInstance win32_userprofile | Where { $_.localpath -match "useraccountname" } | Remove-CimInstance

     

    Note, this has to be run as administrator for the Remove-CimInstance to work, but the beauty of the Powershell Step in PDQ is that it does :)

    0
  • I couldn't help myself. Here, have a function:

     

    Function Remove-UserProfile{
       <#
            .SYNOPSIS
                Removes specified user profile from a local or remote machine using Invoke-Command
       #>
        Param(
            [cmdletBinding()]
            [parameter(
                    Mandatory,
                    Position=1)]
                    [string]
                    $Username,
            [parameter(
                    Mandatory=$false,
                    Position=0)]
                    [array]
                    $Computername
            )
        
        If($Computername -ne '')
        {
            Foreach($computer in $Computername)
                {
                    Try
                        {
                            Get-CimInstance -Computername $Computer win32_userprofile |
                            Where-Object { $_.localpath -match "$Username" } |
                            Remove-CimInstance
                        }
                    
                    Catch
                        {
                            $_.Exception.Message
                        
                        }
                }#end foreach
        }#end if
        
        Else
            {
            
            Get-CimInstance win32_userprofile | Where-Object { $_.localpath -match "$Username" } | Remove-CimInstance
            
            }#end else
    }
    

     

    0