Rename-UCUserProfile.ps1

Please im working on a project to rename users profile on C:\users\ to “.OLD”. This create a new profile for any user login to the computer for the first time. In other to achieve this without any error, i will also need to rename the user profile in the registry. From the snip below, renaming the user profile on File Explorer works perfectly without issues. However, the Challenge is also renaming the user profile in the Registry. Please your assistance will be greatly appreciated.


function Rename-UCUserProfile {
    [cmdletbinding()]
    param(
        [Parameter(Mandatory = $true)] $ComputerName = 'Localhost'
    )

    Begin {}
    Process {

        Invoke-Command -ComputerName $ComputerName -ScriptBlock {
            $UserProfileCollection = [System.Collections.ArrayList]@()
            $AllUsers = (Get-ChildItem -Path C:\Users\).Name
            ForEach ($User in $AllUsers) {
                $ArrayVal = $UserProfileCollection.Add($User)
                Write-Host "$ArrayVal) $User"
            }
            $UserPrompt = Read-Host "ENTER NUMBER TO SELECT A USERNAME"
            $userVal = $UserProfileCollection[$UserPrompt]
            Rename-Item -Path C:\Users\$userVal -NewName "$userVal.OLD" -WhatIf
            Write-Warning "Username '$UserVal' has been renamed to $UserVal.OLD" 
            #Renaming the User Profile in Registry
            $SID = (gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object { $_. ProfileImagePath -eq "C:\users\$userVal" }).PsChildName |
            ForEach-Object {
                Rename-Item -Path .\$SID -NewName "$SID.Old"
            }
            #(New-Object System.Security.Principal.NTAccount("$UserVal")).Translate([System.Security.Principal.SecurityIdentifier]).Value |
    
        }
    
    }
    End {}
}

Enumerate profiles\users with WMI, not the filesystem\registry:

Get-CimInstance -ClassName Win32_UserAccount
Get-CimInstance -ClassName Win32_UserProfile

Then use methods to rename, which would be comparable to the GUI operations:

powershell - How to use Win32_UserAccount rename method? - Stack Overflow

2 Likes

Thanks Rob-Simmers for the suggestions. this was very helpful. However, i noticed that when i run my commands like this

1. $UserPrompt = Read-Host "ENTER NUMBER TO SELECT A USERNAME"
2.     $userVal = $UserProfileCollection[$UserPrompt]
3.     Rename-Item -Path C:\Users\$userVal -NewName "$userVal.OLD" -WhatIf
4.     Write-Warning "Username '$UserVal' has been renamed to $UserVal.OLD" 
5.     #Renaming the User Profile in Registry
6.     
7.     $SID = (Get-CimInstance -ClassName Win32_UserProfile | Where-Object {$_. LocalPath -like '$userVal'}).SID
   

Notice the line 7. it returns am empty value.
let me explain more:
line 1 receives user input
line 2 corresponds the array index number to the exact value the user enters. For example, if the index number is 2, the value will corresponds to the users profile name(ealbert)
Line 3 rename the user profile in C:\users\userprofilename
line 4 just output a message

Now comes the challenge. Line 7 was suppose to output the value of line 2 and use the value to get the user SID in Win32_UserProfile. but it returns an empty variable. Could it be im doing something wrong.

Sorry if i have complicated issues :grinning:

Not sure if you have a typo or not but did you notice the space between $_. and LocalPath?

1 Like

Thank you so much @tonyd for spotting that out. i have just corrected it now but is still not getting the user SID. Returning empty string value

type or paste code here$SID = (Get-CimInstance -ClassName Win32_UserProfile | Where-Object {$_.LocalPath -like "C:\users\$userVal" }).SID`
$SID = (Get-CimInstance -ClassName Win32_UserProfile | Where-Object {$_.LocalPath -like "C:\users\$userVal" }).SID

That works for me. Is it actually finding the user? What output do you get when you just run:

Get-CimInstance -ClassName Win32_UserProfile | Where-Object {$_.LocalPath -like "C:\users\$userVal" }

Works for me as well if I set $UserVal to a valid user name. As Matt suggested, is $UserVal a valid username?

FINAL SCRIPT BELOW. Thank you so much friend. Any suggestions to improve the script will be appreciated

#Welcome to registry file 
function Rename-UCUserProfile{
[cmdletbinding()]
param(
    [Parameter(Mandatory = $true)] $ComputerName = 'Localhost'
    #[Parameter(Mandatory = $true)] $UserName
)

Begin{}
Process{

Invoke-Command -ComputerName $ComputerName -ScriptBlock{
    $UserProfileCollection = [System.Collections.ArrayList]@()
    $AllUsers = (Get-ChildItem -Path C:\Users\).Name
    ForEach($User in $AllUsers){
        $ArrayVal = $UserProfileCollection.Add($User)
        Write-Host "$ArrayVal) $User"
        }
    $UserPrompt = Read-Host "ENTER NUMBER TO SELECT A USERNAME"
    $userVal = $UserProfileCollection[$UserPrompt]
    Rename-Item -Path C:\Users\$userVal -NewName "$userVal.OLD" -WhatIf
    Write-Warning "Username '$UserVal' has been renamed to $UserVal.OLD"

    #Renaming the User Profile in Registry
    [string]$USERSID = (Get-CimInstance -ClassName Win32_UserProfile | Where-Object {$_.LocalPath -like "C:\users\$userVal"}).SID
    Write-Output $USERSID

    Get-Item -path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$USERSID" | Rename-Item -NewName "$USERSID.OLD" -Force -WhatIf
    }
    
}
End{}
}

function Revert-UCUserProfile{
[cmdletbinding()]
param(
    [Parameter(Mandatory = $true)] $ComputerName = 'Localhost'   
)

Begin{
Clear-Host
Write-Host "WELCOME: TO REVERT YOUR CHANGES, SELECT A NUMBER FOR THE USERNAME" -ForegroundColor Green
}
Process{
Invoke-Command -ComputerName $ComputerName -ScriptBlock{
    $UserProfileCollection = [System.Collections.ArrayList]@()
    $ContentVals = [System.Collections.ArrayList]@()
    $AllUsers = (Get-ChildItem -Path C:\Users\).Name
    ForEach($User in $AllUsers){
        $ArrayVal = $UserProfileCollection.Add($User)
        Write-Host "$ArrayVal) $User"
        }
    $UserPrompt = Read-Host
    $userVal = $UserProfileCollection[$UserPrompt]
    $USERNAME = Read-Host "RETYPE USERNAME AGAIN WITHOUT .OLD FOR COMFIRMATION"
    Rename-Item -Path C:\Users\$UserVal -NewName $USERNAME -Force -WhatIf
    Write-Warning "Username '$UserVal' has been renamed to '$USERNAME'"
    #Renaming the User Profile in Registry
    [string]$USERSID = (Get-CimInstance -ClassName Win32_UserProfile | Where-Object {$_.LocalPath -like "C:\users\$userVal"}).SID
    "`n"
    Write-Host "THE $USERVAL SID IS '$USERSID'" -ForegroundColor DarkYellow
    "`n"
    $RenameUserSID = Read-Host "COPY THE ABOVE USER SID AND PASTE TO RENAME REGISTRY HIVE WITHOUT THE '.OLD'"
    Get-Item -path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$USERSID" | Rename-Item -NewName "$RenameUserSID.OLD" -Force -WhatIf
  }
}
End{
    Write-warning "To delete a User profile(s) from any remote Computer, please use the Scripted Support Tool (SST) Cmdlet called Remove-UserProfile"
    }
}
function CallFunction{
$UserPrompt = Read-Host "Rename UserProfile (R), Revert Changes (RE)"

switch($UserPrompt){
        "R"{Rename-UCUserProfile}
        "RE"{Revert-UCUserProfile}
    }
}
Revert-UCUserProfile -ComputerName 
#
  1. List item