powershell - powershell move-item based names only from csv and rename 如果它已经存在,则基于编号
问题描述
我想将文件夹从一个位置移动到另一个位置(根据 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)'"
}
}
解决方案
如果您的输入 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
推荐阅读
- javascript - 如何将 html 表单导入到单独的文件中
- python - 为什么我的 TensorFlow 分布式时间线中的 RecTensor 需要这么长时间?
- docker-compose - 命令在 docker compose 中的“命令”部分不起作用
- ios - iOS 应用程序中的 Firebase Crashlytics 无法正常工作
- javascript - 有条件地反应本机更改按钮不透明度
- nginx - NGINX 健康检查需要上游
- java - 将音乐文件从一个应用程序发送到另一个应用程序
- javascript - getBoundingClientRect 给出不正确的值
- asp.net - 我可以在 mvc 控制器中执行多个 sql server 查询并在 MVC 应用程序的单个视图中显示结果吗
- android - viewpager 滑动到片段,但闪烁原始片段