powershell move-item based names only from csv and rename If it already exists based numbering

后端 未结 1 635
囚心锁ツ
囚心锁ツ 2021-01-26 04:08

I want to move folders from one location to another (according to the list of folder names in the CSV file). If the name already exists then rename the folder that is passed wit

相关标签:
1条回答
  • 2021-01-26 05:00

    If your input CSV file looks anything like this:

    "UserName","Email","DisplayName"
    "jdoe","john.doe@yourdomain.com","John Doe"
    "janedoe","jane.doe@yourdomain.com","Jane Doe"
    "uknown","un.known@yourdomain.com","Un Known"
    

    then below code should do it.

    $src     = "C:\Users\Yaniv Naor\Desktop\users"
    $dest    = "C:\Users\Yaniv Naor\Desktop\oldusers"
    $CsvFile = "C:\Users\Yaniv Naor\Desktop\Disable_users.csv"
    
    # throw an error if the $src folder does not exist
    if (!(Test-Path -Path $src -PathType Container)){
        Throw [System.IO.FileNotFoundException] "The folder '$src' could not be found."
    }
    # create the destination path if it does not exist
    if (!(Test-Path -Path $dest -PathType Container)) {
        New-Item -Path $dest -ItemType 'Directory' -Force | Out-Null
    }
    
    # get an array of user names from the CSV. These names should correspond with the folders in $src
    #####################################################
    # CHECK THE COLUMN NAME IN YOUR INPUT CSV 
    # I'm using the 'UserName' column from my example Csv
    #####################################################
    $userNames = Import-Csv $CsvFile | Select-Object -ExpandProperty UserName -Unique
    
    # get an array of folders already in the destination. Names only
    $destFolders = @(Get-ChildItem $dest -Directory | Select-Object -ExpandProperty Name)
    
    # find the folders we're after and move them to $dest. Append a sequence number if the folder is already there
    Get-ChildItem -Path $src -Directory | Where-Object { $userNames -contains $_.Name } | ForEach-Object {
        $count = 1
        $newName = $_.Name
        while ($destFolders -contains $newName) {
            $newName = "{0}({1}){2}" -f $_.BaseName, $count++, $_.Extension
        }
        $newFolder = Join-Path -Path $dest -ChildPath $newName
        $_ | Move-Item -Destination $newFolder -Force
    
        # update the $destFolders array with this new name for the next iteration 
        $destFolders += $newName
    }
    

    Edit

    If you want to keep track of any errors that may occur when moving the folders in a log file, you could do this:

    Below the line $CsvFile ='...', declare another variable for the path and filename of your errors log file:

    # create a name for the errors logfile
    $errorLog = Join-Path -Path $dest -ChildPath ('{0:yyyy-MM-dd}_Errors.txt' -f (Get-Date))
    

    Next, in the ForEach-Object loop, change these lines:

    $_ | Move-Item -Destination $newFolder -Force
    
    # update the $destFolders array with this new name for the next iteration 
    $destFolders += $newName
    

    to this:

    try {
        $_ | Move-Item -Destination $newFolder -Force -ErrorAction Stop
        # update the $destFolders array with this new name for the next iteration 
        $destFolders += $newName
    }
    catch {
        Write-Warning "Error moving folder '$($_.FullName)'"
        # write something to the log. You can write the full error message in
        # $_.Exception.Message (or $Error[0].Exception.Message) if you like.
        Add-Content -Path $errorLog -Value "Error moving folder '$($_.FullName)'"
    }
    

    If no errors occur, the error file will not be created. When something does happen, you can find the file in the destination folder: 2019-03-09_Errors.txt (if it is created today). Errors are also written to the console using Write-Warning

    0 讨论(0)
提交回复
热议问题