简体   繁体   中英

How can I produce the error in this PowerShell Script

Can someone please let me know, how can I produce the error and capture that in the log file? As I want to test this script for error perspective but not able to get that, It is very helpful if you can let me know, how to test this script manually for error perspective.

Let me describe to you what I am achieving through this script. as I want to move the file to respective folders on the server with file naming convention and backup to existing file if there is any and after the whole process generates a log file in CSV and send an email with success or error message.

$Source       = 'c:\uploadtool\' # Source Location
$RetailSource = 'Retail P&C Sales Intelligence\*'
$GroupSource  = 'Group P&C Sales Intelligence\*'      
$UATSource = 'UAT\*'   
$RetailDest   = 'D:\ToolUpload\Retail-EIP'    # 1st Destination Location
$GroupDest    = 'D:\ToolUpload\Group-EIP'     # 2nd Destination location
$UATDest ='D:\ToolUpload\UAT' # Added 3rd destination location in this version 1.7.2V
$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)
$Sourcetest  = Test-Path -Path '$RetailSource','$GroupSource'  -PathType Leaf

#Email Params:
$EmailParams = @{
    SmtpServer ='xyz.smtp.com' 
    Port   = '25'
    Subject    ='File Upload Status'
    To         ="xyz@xyz.com"
    From       ="no-xyz@xyz.com"
}


# 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 don't 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*','*UAT*' -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 = {$ArchiveData}}, # initialize to Not Applicable
        Result
    
    # depending on its name, get the correct destination folder
    $destFolder = if($_.Name -match "Retail-EIP") { $RetailDest } elseif($_.Name -match "Group-EIP")  { $GroupDest } else {$UATDest}

    
    # 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 
    
    # 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 
            
            # 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 
        $out.Result = 'OK'
        Write-Host "File '$($_.FullName)' has been moved to '$destFolder'"
        $Body = " The File '$($_.FullName)' has been moved to '$destFolder'      'n  Size of the file is '$($_.Length)'   `n   file has been backed up on the location '$ArchiveData' "
    }
    catch 
    {   # ouch.. something went horribly wrong on a Move-Item action
      
        $Body = " Error occured trying to move the file '$($_.FullName)' to '$destFolder. `n$($_.Exception.Message)"
        Write-Warning "An error occurred: $_.Exception.Message"
        $out.Result = "Error: $($_.Exception.Message)" | Add-Content -Path $LogFile -Force
       
    }

    Send-MailMessage @EmailParams -Body $Body

    # 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 -Force

# and display on the screen using Out-GridView as the data will probably be too wide for Format-Table
$result | Out-GridView -Title 'Backup results'

Ok, I have revised your code and added a few comments in it to hopefully point out what was wrong in your code.

As I have gathered from your previous questions, you want to also report the files with 'wrong' filenames (ie not containing either 'Group-EIP', 'Retail-EIP' or 'UAT').
When you add parameter -Include '*Group-EIP*', '*Retail-EIP*','*UAT*' to the Get-ChildItem cmdlet, all files with a bad name will not even make it into the ForEach loop, and you won't be able to log them as "Error: Incorrect filename", so remove that.

Next, the output of all this is a structured CSV file and at one point you added Add-Content -Path $LogFile -Force in the code, which will destroy the structure and make the CSV unusable.

You have added a Send-MailMessage call inside the loop, and by doing that, the code would send an email on every file it processes. I have moved that towards the end of the code, so it will only send one single email.
For demo, I added the resulting CSV file as attachment in this email, but you can also create a nice HTML table of whatever you collected in $result .
I'll leave that up to you, but there are plenty examples to be found here at StackOverflow.

$RetailSource = Join-Path -Path 'c:\uploadtool' -ChildPath 'Retail P&C Sales Intelligence'
$GroupSource  = Join-Path -Path 'c:\uploadtool' -ChildPath 'Group P&C Sales Intelligence'      
$UATSource    = Join-Path -Path 'c:\uploadtool' -ChildPath 'UAT'
####################################################################################
# now group these paths into a single array variable as I have shown you in my answer
# here: https://stackoverflow.com/a/67673422/9898643
####################################################################################
$Source       = $RetailSource, $GroupSource, $UATSource


$RetailDest   = 'D:\ToolUpload\Retail-EIP'    # 1st Destination Location
$GroupDest    = 'D:\ToolUpload\Group-EIP'     # 2nd Destination location
$UATDest      = 'D:\ToolUpload\UAT'           # Added 3rd destination location in this version 1.7.2V
$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 don't want output, we use $null = ..
$null = New-Item -Path $LogFolder -ItemType Directory -Force

# loop through the files in the source folders and collect the outputted objects.
####################################################################################
# $Source is an ARRAY of paths, so do not surround it with quotes!
# If you want to also log files that have a bad name, DO NOT USE 
# -Include '*Group-EIP*', '*Retail-EIP*','*UAT*', otherwise these files are ignored!
####################################################################################
$result = Get-ChildItem -Path $Source -File -Force -Recurse | ForEach-Object {
    Write-Host "Processing file '$($_.FullName)'"
    # create an object with (for now) 2 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 = {$ArchiveData}},
                              Result

     # test if the file has a correct name
     if ($_.BaseName -notmatch 'Group-EIP|Retail-EIP|UAT') {
        # file does not have the correct naming convention
        $out.Archive = $null
        $out.Result = "Error: Incorrect filename"
    }
    else {
        # depending on its name, get the correct destination folder
        $destFolder = if($_.Name -match "Retail-EIP") { $RetailDest } elseif($_.Name -match "Group-EIP")  { $GroupDest } else { $UATDest }

        # 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 

        # 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 
        
                # 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 
            $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)"
            ####################################################################
            # $LogFile will be saved later as CSV, Do not ruin the structure
            # by inserting  '| Add-Content -Path $LogFile -Force'
            ####################################################################
        }
    }
    # 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 -Force

# and display on the screen using Out-GridView as the data will probably be too wide for Format-Table
$result | Out-GridView -Title 'Backup results'

# and send an email with the resulting CSV file as attachment 
# or create a nice HTML table from the objects in $result and put that in the body.
# Lots of examples for that can be found on SO

$EmailParams = @{
    SmtpServer = 'xyz.smtp.com' 
    Port       = '25'
    Subject    = 'File Upload Status'
    To         = "xyz@xyz.com"
    From       = "no-xyz@xyz.com"
    Body       = "Please see attached logfile" 
    Attachments = $LogFile
}

Send-MailMessage @EmailParams

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM