Nikhil S
Nikhil S

Reputation: 91

Pattern matching in powershell to rename folder

I am trying to script to rename username folders, but some of the folders are named USERNAME_S11-121-121.... I want to verify path using test-path with wild cards and rename-item doesn't take wild cards.

Is there a way I can use test-path and rename-item with just username and exclude everything except username.

I don't know if test-path $path* is correct way of doing it?

 Function Reset-Profile {
           param(

                    [parameter(Mandatory = $true, Position = 0)]
                    [string] $UserName,
                    [parameter(Mandatory = $true, Position = 1, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]         
                    $Server
                )
                process{

                    $SelectedUser = $UserName
                    $randomNumber = Get-Random

                    Foreach($UserName in $Server){

                            $paths = @(
                                "\\$Server\c$\users\$SelectedUser"     #local profile               
                                "\\server01\users$\$SelectedUser", #roaming profile
                                "\\server02\usersupmprd$\$SelectedUser" #roaming profile
                                )

                            foreach ($path in $paths)
                            {
                                if(test-path $path or test-path $path*)
                                { 


                                    Rename-Item -path $path -NewName "$SelectedUser.$randomNumber"              

                                    break;
                                    write-host profile renamed under $path to 
                                    $SelectedUser.$randomNumber

                                }
                                else{ write-host path not found}                      

                            } 
                    }
                   }
}

Upvotes: 0

Views: 237

Answers (1)

Mark Wragg
Mark Wragg

Reputation: 23405

Untested, but try this:

Function Reset-Profile {
    [cmdletbinding()]
    param(
        [parameter(Mandatory = $true, Position = 0)]
        [string] $UserName,
        [parameter(Mandatory = $true, Position = 1, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]         
        [string[]] $Server
    )    
    Process{

        $randomNumber = Get-Random

        ForEach($Host in $Server)
        {
            $paths = @("\\$Host\c$\users\$UserName",        #local profile               
                       "\\server01\users$\$UserName",       #roaming profile
                       "\\server02\usersupmprd$\$UserName") #roaming profile

            ForEach ($path in $paths)
            {

                if(test-path "$path") 
                {             

                    $CurrentPath = Get-Item "$path"

                }

                elseif(test-path $path_*)
                {
                    write-host $path
                    $CurrentPath = Get-Item "$($path)_*" #it's necessary to put $path_ in parenthesis otherwise it conflicts with some internal command and gets the path of the directory I am working in.
                    write-host $CurrentPath
                }
                else {
                    Write-Warning "Path not found"
                }


                if($CurrentPath.Count() -eq 1)
                {                 
                    Rename-Item -Path $CurrentPath -NewName "$UserName.$randomNumber"              
                    Write-Verbose "Profile renamed under $path to $UserName.$randomNumber"

                } elseif ($CurrentPath.Count -gt 1) { 
                     Write-Warning  "Multiple matches for $path"
                } else { 
                     Write-Warning "Path $path not found" 
                }
            }
        }
    }
}

Explanation:

  • Added [string[]] in front of $Server so that it explicitly accepts array input (as well as a single string).
  • Changed ForEach($Username in $Server) to ForEach($Host in $Server) and made use of $Host so that it loops through the servers correctly.
  • Uses Get-ChildItem $Path* to get any matching paths. Then checks if a single path has been returned, if it has then it will do the rename, if it's multiple or if there was no match it will warn you as such.
  • Changed write-host to write-verbose which will require use of the -verbose switch to be seen. Write-host is an anti-pattern, particularly in a Function.

How to execute:

I suggest you run this as follows initially (because i've added [cmdletbinding()] at the top of your function it now supports -WhatIf and -Verbose which should pass in to the Rename-Item cmdlet and will show you what it does. If it looks right, simply remove -WhatIf:

Reset-Profile -Username TestUsername -Server Localhost -WhatIf -Verbose

Upvotes: 2

Related Questions