Powershell 挡块不';如果我上载的文件与条件不匹配,则无法捕获错误
我正在尝试从源位置复制文件并将现有文件备份到备份位置, 所有设置和脚本都按预期工作,但我只想更改一些东西,如 首先,如果我上传了不符合条件的错误语句,脚本就不会捕获catch语句。 第二,我想以表格的形式捕获日志,我该怎么做Powershell 挡块不';如果我上载的文件与条件不匹配,则无法捕获错误,powershell,Powershell,我正在尝试从源位置复制文件并将现有文件备份到备份位置, 所有设置和脚本都按预期工作,但我只想更改一些东西,如 首先,如果我上传了不符合条件的错误语句,脚本就不会捕获catch语句。 第二,我想以表格的形式捕获日志,我该怎么做 如前所述,为了能够使用try{}..catch{},您需要在实际上可以引发异常的cmdlet上添加ErrorAction Stop,如两个Move-Item cmdlet,以便还捕获非终止异常 然后您希望获得一个表样式的输出,而不是文本日志文件。 在这种情况下,您需要输出
如前所述,为了能够使用
try{}..catch{}
,您需要在实际上可以引发异常的cmdlet上添加ErrorAction Stop
,如两个Move-Item cmdlet,以便还捕获非终止异常
然后您希望获得一个表样式的输出,而不是文本日志文件。在这种情况下,您需要输出具有特定属性的对象,这样您就可以将日志文件保存为结构化CSV文件(实际上是一个表格),您可以在Excel中打开它 现在,如果我有正确的答案,代码需要:
$GroupDest
和$RetailDest
中定义的备份目标文件夹$ArchiveData
try{}..catch{}
结构中,以便捕获任何异常 $Source='c:\uploadtool\*' #Source Location
$RetailDest= "D:\ToolUpload\Retail-EIP" #1st Destination Location
$GroupDest= "D:\ToolUpload\Group-EIP" #2nd Destination location
$RetailBack="D:\ToolUpload\Retail-EIP\*" #Backup location which copy the existing file if the file match to Retail-EIP.
$GroupBack="D:\ToolUpload\Group-EIP\*" # 2nd Backup location which copy the existing file if the file match to Group-EIP.
$Backupdata="D:\Backup" #Backup Location
$filename = Get-ChildItem -Path $Source -File -Force -Recurse
#$logname=New-Item "D:\logs\uploadlog_$(Get-Date -Format 'yyyyMMdd').txt" -ItemType file -Force
$lognamefolder="D:\logs"
$logname="D:\logs\uploadlog_$(Get-Date -Format 'yyyyMMdd').txt"
$checkLocalFolderExist = Test-Path -Path $lognamefolder
$checkLocalFileExist = Test-Path -Path $logname -PathType Leaf
if(-NOT $checkLocalFolderExist)
{
New-Item -Path $lognamefolder -ItemType Directory
}
if(-NOT $checkLocalFileExist)
{
New-Item -Path $logname -ItemType File
}
echo " " (Get-Date) | Add-Content -Path $logname -PassThru
echo "Copying file start" | Add-Content -Path $logname -PassThru
echo "Source is:$filename" | Add-Content -Path $logname -PassThru
echo "File size = "($filename).Length | Add-Content -Path $logname -PassThru
echo " " | Add-Content -Path $logname -PassThru
$ArchiveData = New-Item -Path "$Backupdata\backup_$(Get-Date -Format 'yyyyMMddHHMM')" -Force -ItemType Directory
foreach($file in $filename)
{
try
{
if($file -match "Retail-EIP")
{
$fname=$file.fullname
Move-Item -Path $RetailBack -Destination $ArchiveData
echo "File has been backed up :$ArchiveData" | Add-Content -Path $logname -PassThru
Move-Item -Path $fname -Destination $RetailDest
echo "File has been upload to Retail Platform: $RetailDest" |Add-Content -Path $logname -PassThru |Format-Table
}
if($file -match "Group-EIP")
{
$fname=$file.fullname
Move-Item -Path $GroupBack -Destination $ArchiveData
echo "File has been backed up :$ArchiveData" | Add-Content -Path $logname -PassThru
Move-Item -Path $fname -Destination $GroupDest
echo "File has been upload to Group Platform: $GroupDest" |Add-Content -Path $logname -PassThru | Format-Table
}
}
catch # Catch statement doesn't produce the error and capture in the log file.
{
Write-output "Exception Message: $($_.Exception.Message)" -ErrorAction Stop | Add-Content $logname -passthru
}
}
请注意,我已将-WhatIf
开关添加到移动项cmdlet。这是一种安全措施,使用该开关,您只能在控制台中看到一条线,告诉您将执行什么操作。实际上没有任何东西被移动。一旦您对所有控制台消息感到满意,即一切正常,您可以删除这些
-WhatIf
开关
请阅读代码注释(希望)解释方法的每一步
这花的时间太长了 导出中的内容是在返回的对象中收集的内容: 纵队 描述 日期 处理文件的当前日期 来源 正在从源文件夹处理的文件的完整路径和文件名 文件大小 正在处理的文件的大小(字节) 目的地 源文件从
$RetailDest
或$GroupDest
移动到的目标文件夹的完整路径
存档
“N/A”或文件的完整路径和文件名,该文件已在目标文件夹中,必须先移动到存档文件夹
结果
如果移动项目出现问题,则显示“确定”或异常消息
//[1]catch从不在基本
if
或elsif
测试中触发,因为它是为捕获操作期间的异常而设计的,这些操作实际上可能引发异常,如移动项
等。为了让catch在这些cmdlet上工作,即使没有终止,也应该在它们上添加-ErrorAction Stop
,而不是在catch块本身内部的写入输出上..//[2] Format Table
用于在屏幕上输出具有属性的对象的表格样式,而不仅仅是字符串。对于表格格式,可以使用[PSCustomobject]
。另外,建议您使用$Error[0]
而不是psitem。@Abraham,您可以帮助说明,如何在powershellEcho
中添加[PSCustomobject],它只是编写字符串的写入输出的别名<代码>格式化表格
旨在将某些输出格式化为表格。。。这适用于具有属性的每个对象,例如[PSCustomObject]
s。只是对字符串没有任何意义。。。(比较$host | Format Table
和$host | Format List
和“some string”| Format Table
)如果有人能为上述脚本的[PSCustomObject]编写一个代码,那将非常有帮助。嗨,西奥,非常感谢您对此进行研究并为此花费宝贵的时间。正如预期的那样,如果你能看一看的话,还有一件事。源未捕获到CSV日志中。第二,有没有办法创建一个文件名为的备份副本,这样就很容易跟踪了,因为它不会以CSV格式捕获备份日志,就像哪个文件创建了备份位置一样。还有一件事,它会覆盖日志,所以只有当前的副本日志only@essexlake请查看编辑后的代码。现在,仅当需要将文件移动到目标文件夹和存档文件夹时,才会创建目标文件夹和存档文件夹。在输出中,负责的文件始终是具有所述目标的第一个文件。我还将switch-Append
添加到导出Csv中,因此现在结果被添加到一个已经存在的文件中。我不知道你所说的“源代码未捕获到CSV日志”是什么意思。。它总是输出中的第二列..我所说的源是,在源列中CSV中没有数据。
$Source = 'C:\uploadtool' # Source Location
$RetailDest = 'D:\ToolUpload\Retail-EIP' # 1st Destination Location
$GroupDest = 'D:\ToolUpload\Group-EIP' # 2nd Destination location
$ArchiveData = 'D:\Backup\backup_{0:yyyyMMddHHmm}' -f (Get-Date)
$LogFolder = 'D:\logs'
# because of your wish to get a Table-style log, use CSV format you can open in Excel
$LogFile = 'D:\logs\uploadlog_{0:yyyyMMdd}.csv'-f (Get-Date)
# make sure the output LogFolder exist
# by adding the -Force switch there is no need to use Test-Path first, because if
# the folder already exists, the cmdlet will return the DirectoryInfo of that,
# otherwise it will create a new folder. Since we dont want output, we use $null = ..
$null = New-Item -Path $LogFolder -ItemType Directory -Force
# loop through the files in the source folder and collect the outputted objects
$result = Get-ChildItem -Path $Source -Include '*Group-EIP*', '*Retail-EIP*' -File -Force -Recurse |
ForEach-Object {
Write-Host "Processing file '$($_.FullName)'"
# create an object with (for now) 3 empty properties
$out = $_ | Select-Object @{Name = 'Date'; Expression = {(Get-Date)}},
@{Name = 'Source'; Expression = {$_.FullName}},
@{Name = 'FileSize'; Expression = {$_.Length}},
Destination, # depends on the file name
@{Name = 'Archive'; Expression = {'N/A'}}, # initialize to Not Applicable
Result
# depending on its name, get the correct destination folder
$destFolder = if($_.Name -match "Retail-EIP") { $RetailDest } else { $GroupDest }
# create the backup destination folder if it didn't already exist
# the first file in column 'Source' is now responsible for creating the backup folder
$null = New-Item -Path $destFolder -ItemType Directory -Force
# get the full path and filename for the destination
$existingFile = Join-Path -Path $destFolder -ChildPath $_.Name -PathType Leaf
# add the destination folder to the output object
$out.Destination = $destFolder
try {
# if a file with that name already exists in the destination, move it to the Archive folder
if (Test-Path -Path $existingFile -PathType Leaf) {
# create the Archive folder if it didn't already exist
$null = New-Item -Path $ArchiveData -ItemType Directory -Force
Move-Item -Path $existingFile -Destination $ArchiveData -ErrorAction Stop -WhatIf
# add the archived file to the output object
$out.Archive = $existingFile
Write-Host "File '$existingFile' has been backed-up to '$ArchiveData'"
}
# next move the file from the source folder to its destination (either $RetailDest or $GroupDest)
$_ | Move-Item -Destination $destFolder -ErrorAction Stop -WhatIf
$out.Result = 'OK'
Write-Host "File '$($_.FullName)' has been moved to '$destFolder'"
}
catch {
# ouch.. something went horribly wrong on a Move-Item action
Write-Warning "An error occurred: $_.Exception.Message"
$out.Result = "Error: $($_.Exception.Message)"
}
# output the object so it gets collected in variable $result
$out
}
# now you can save the results as structured CSV file to open in Excel
$result | Export-Csv -Path $LogFile -UseCulture -NoTypeInformation -Append
# and display on screen using Out-GridView as the data will probably be too wide for Format-Table
$result | Out-GridView -Title 'Backup results'