获取子项 | 复制项

获取子项 | 复制项

尝试解释为什么copy-itemps 脚本无法按预期工作。我尝试在我的文件服务器中搜索所有附加/有效驱动器上的任何 *.pst 文件,然后将找到的 .pst 文件复制到其他共享位置。下面的脚本没有给我预期的结果。显示Out-File未找到 .pst 文件。当我检查目标文件夹时,我发现只有一个 *.pst 文件被复制过来。我已经验证了文件服务器上的不同目录和子文件夹中有多个文件。$Computers.txt 文件未列出找到或复制的任何 .pst 文件 截屏
以下是我的新手 ps 脚本

$Computers = hostname
get-psdrive -PSProvider "FileSystem" `
| foreach {Write-Output $Computers $_.Root;get-childitem $_.Root -include *.PST -Recurse -erroraction silentlyContinue | Copy-Item -Destination "\\Server1\PSTsbackupfolder\" `
| Select-Object -Property $Computers,Directory,Name} | Format-Table -AutoSize `
| Out-File -FilePath "\\Server1\Results\$Computers.txt"

如果我| Copy-Item -Destination "\\Server1\PSTsbackupfolder\"从脚本中删除,输出文件 $Computers.txt 将显示预期结果,但复制这些 .pst 文件的目标仍然是必要的。$Computers.txt 的输出文件结果如下: 截屏, 任何建议都值得感激。

答案1

您需要添加-AppendOut-File获取整个列表;每次遍历列表时都会创建一个新文件。

Copy-Item如果从管道中删除,则会将 的输出发送Get-ChildItem到管道的其余部分。如果保留Copy-Item在那里,则会发送 的输出Copy-Item,这只是它刚刚处理的一个文件。

如果您尝试将 ServerA 上找到的所有文件复制到\\server1\PSTBackupFolder,则最好在 ServerA 上运行 Robocopy,如下所示:

Get-PSDrive -PSProvider FileSystem | ForEach-Objecct {robocopy $_.root *.pst /z /v /r:5 /log:\\Server1\PSTsbackupfolder\RoboCopy.$($_.Name).log \\Server1\PSTsbackupfolder}

这将获取所有,然后遍历与 匹配的FileSystem PSDrives每个驱动器和robocopy位于根目录(驱动器号)下的所有文件。我们以可恢复模式()详细复制它们(),重试复制 5 次(),并将所有事务记录到*.pst\\Server1\PSTBackupfolder/z/v/r:5\\server1\pstbackupfolder\robocopy.DRIVELETTER.Log

我们使用内联替换 ( $($_.Name)) 将复制日志拆分为单独的文件,因为当您试图弄清楚为什么 Bill 的 PST 没有从 L: 驱动器复制时,如果您只需要查看 50 个条目而不是 50,000 个条目,那么处理起来会容易得多

答案2

我确信有更好、更干净、更有效的方法来编写此代码,我将采纳您的建议并尝试改进我的代码,但当前技能水平- 这就是我能够拼凑起来的,它给了我我想要的最终结果。

$FileServer = hostname
$DestPath = "c:\PSTs\$FileServer"
#Checks if the Destination Dir/Path exists, if not it creates the folder and names it whatever the hostname is
If ((Test-Path -path $DestPath -PathType Container) -eq $false) {New-Item $DestPath -ItemType Directory}
#Searches for .psts files on host, exports results to .csv file.
Get-psdrive -PSProvider "FileSystem" `
| ForEach-Object {(get-childitem $_.Root -recurse -file -Filter *.PST -erroraction silentlyContinue `
| Select-Object -Property Directory,Name)} | Export-Csv -path "$DestPath\$FileServer.csv" -NoTypeInformation -Force
#Sets variable for .CSV file from previous command
$PstPath = Get-Content -Path "$DestPath\$FileServer.csv"
#Modifying .CSV for preceding commands to work.
$PSTsCSV = "$DestPath\$FileServer.csv"
($PstPath).Replace('"Directory",','"Path"').replace('"Name"','').replace('","','\') | Out-File -FilePath $PSTsCSV -force
#Reads each line of .CSV file, copies .pst file from source to destination, if file name exsists...
#in destination, it will re-name file appending a consecutive number
$CSV = Import-Csv $DestPath\$FileServer.csv
Get-ChildItem -Path $CSV.Path | ForEach-Object {
    $num=1
    $newName = Join-Path -Path $DestPath -ChildPath $_.Name
    while(Test-Path -Path $newName)
    {
       $newName = Join-Path $DestPath ($_.BaseName + "_$num" + $_.Extension)
       $num+=1
    }
    $_ | Copy-Item -Destination $newName
}

我在我的脚本中发现了一个问题,这是有问题的行。 ($PstPath).Replace('"Directory",','"Path"').replace('"Name"','').replace('","','\') | Out-File -FilePath $PSTsCSV -force

如果在服务器上搜索 .psts,结果为.pst 文件,则 .csv 文件的输出将没有结果。将出现错误,指出您不能对空值表达式调用方法。

You cannot call a method on a null-valued expression.
At D:\Scripts\PowerShell\tempCodeRunnerFile.ps1:6 char:1
+ ($PstPath).Replace('"Directory",','"Path"').replace('"Name"','').repl ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

为了补救(我所能想到的最好的办法),如果找不到 .pst 文件,我会重写代码,添加以下内容,-ErrorAction Stop这样脚本就会在此时停止,就像这样

Get-Content $PSTsCSV.Replace('"Directory",','"Path"').replace('"Name"','').replace('","','\') -ErrorAction Stop | Out-File -FilePath $PSTsCSV -force

相关内容