PowerShell中的模式匹配重命名文件夹

时间:2017-04-18 14:29:42

标签: powershell

我正在尝试编写脚本来重命名用户名文件夹,但有些文件夹名为USERNAME_S11-121-121...。我想使用通配符test-path验证路径,而rename-item不使用外卡。

我是否可以使用test-pathrename-item只使用用户名并排除除用户名以外的所有内容。

我不知道test-path $path*是否是正确的做法?

 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}                      

                            } 
                    }
                   }
}

1 个答案:

答案 0 :(得分:2)

未经测试,但试试这个:

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" 
                }
            }
        }
    }
}

<强>解释

  • [string[]]前添加了$Server,以便明确接受数组输入(以及单个字符串)。
  • ForEach($Username in $Server)更改为ForEach($Host in $Server)并使用$Host,以便正确循环服务器。
  • 使用Get-ChildItem $Path*获取任何匹配的路径。然后检查是否已经返回单个路径,如果有,那么它将进行重命名,如果它是多个 如果没有匹配,它会警告你。
  • write-host更改为write-verbose,这需要使用-verbose开关才能看到。 Write-host是一种反模式,特别是在函数中。

如何执行:

我建议您最初按照以下方式运行此操作(因为我在您的函数顶部添加了[cmdletbinding()],它现在支持-WhatIf-Verbose,它们应该传递给{{ 1}} cmdlet并会显示它的作用。如果看起来正确,只需删除Rename-Item

-WhatIf