Powershell 挡块不';如果我上载的文件与条件不匹配,则无法捕获错误

Powershell 挡块不';如果我上载的文件与条件不匹配,则无法捕获错误,powershell,Powershell,我正在尝试从源位置复制文件并将现有文件备份到备份位置, 所有设置和脚本都按预期工作,但我只想更改一些东西,如 首先,如果我上传了不符合条件的错误语句,脚本就不会捕获catch语句。 第二,我想以表格的形式捕获日志,我该怎么做 如前所述,为了能够使用try{}..catch{},您需要在实际上可以引发异常的cmdlet上添加ErrorAction Stop,如两个Move-Item cmdlet,以便还捕获非终止异常 然后您希望获得一个表样式的输出,而不是文本日志文件。 在这种情况下,您需要输出

我正在尝试从源位置复制文件并将现有文件备份到备份位置, 所有设置和脚本都按预期工作,但我只想更改一些东西,如

首先,如果我上传了不符合条件的错误语句,脚本就不会捕获catch语句。 第二,我想以表格的形式捕获日志,我该怎么做


如前所述,为了能够使用
try{}..catch{}
,您需要在实际上可以引发异常的cmdlet上添加
ErrorAction Stop
,如两个Move-Item cmdlet,以便还捕获非终止异常

然后您希望获得一个表样式的输出,而不是文本日志文件。
在这种情况下,您需要输出具有特定属性的对象,这样您就可以将日志文件保存为结构化CSV文件(实际上是一个表格),您可以在Excel中打开它

现在,如果我有正确的答案,代码需要:

  • 从源文件夹(包括子文件夹)获取所有文件,其中文件名包含“Retail EIP”或“Group EIP”
  • 对于这些文件中的每个文件,都有一个在
    $GroupDest
    $RetailDest
    中定义的备份目标文件夹
  • I在这些备份文件夹中,已经存在同名文件,需要将其移动到
    $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,您可以帮助说明,如何在powershell
    Echo
    中添加[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'