имена на основе перемещаемых элементов powershell только из csv и rename, если нумерация уже существует - PullRequest
0 голосов
/ 09 марта 2019

Я хочу переместить папки из одного места в другое (согласно списку имен папок в файле CSV).Если имя уже существует, переименуйте папку с нумерацией и переместите ее.Я пытался создать что-то на основе сценария, который кто-то написал здесь в прошлом, но это не так успешно.Я буду рад помочь.

$src = "C:\Users\Yaniv Naor\Desktop\users"
$dest = "C:\Users\Yaniv Naor\Desktop\oldusers"
$CsvFile = "C:\Users\Yaniv Naor\Desktop\Disable_users.csv"
$num=1

Import-Csv $CsvFile | select users |ForEach-Object {

Test-Path (Get-ChildItem -Path $src -Recurse |select name) }  |

 $nextName = Join-Path -Path $dest -ChildPath $_.name

 while(Test-Path -Path $nextName)

{
   $nextName = Join-Path $dest ($_.BaseName + "_$num" + $_.Extension)   
   $num+=1  
}

 $_ | Move-Item -Destination $nextName
}



ver2:

$src     = "C:\Users\user_name\Desktop\users"
$dest    = "C:\Users\user_name\Desktop\oldusers"
$CsvFile = "C:\Users\user_name\Desktop\Disable_users.csv"
$errorLog = Join-Path -Path $dest -ChildPath ('{0:yyyy-MM-dd}_Errors.txt' -f (Get-Date))

#####################################################
# CHECK THE COLUMN NAME IN YOUR INPUT CSV
#####################################################
$userNames = Import-Csv $CsvFile | Select-Object -ExpandProperty users -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
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)'"
}
}

1 Ответ

0 голосов
/ 09 марта 2019

Если ваш входной CSV-файл выглядит примерно так:

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

, то приведенный ниже код должен это сделать.

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

Редактировать

Если вы хотите отслеживать любые ошибки, которые могут возникнуть при перемещении папок в файле журнала, вы можете сделать это:

Ниже строки $CsvFile ='...', объявите другую переменную для пути иимя файла журнала ошибок:

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

Далее, в цикле ForEach-Object измените эти строки:

$_ | Move-Item -Destination $newFolder -Force

# update the $destFolders array with this new name for the next iteration 
$destFolders += $newName

на следующее:

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

Если ошибок не возникает, файл ошибок не будет создан.Когда что-то происходит, вы можете найти файл в папке назначения: 2019-03-09_Errors.txt (если он создан сегодня).Ошибки также записываются в консоль с помощью Write-Warning

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...